FreeBSD/sys/dev/xen/blkback/blkback.c
/*-------------------------- Device Teardown Support -------------------------*/
/**
 * Perform device shutdown functions.
 *
 * \param xbb  Per-instance xbb configuration structure.
 *
 * Mark this instance as shutting down, wait for any active I/O on the
 * backend device/file to drain, disconnect from the front-end, and notify
 * any waiters (e.g. a thread invoking our detach method) that detach can
 * now proceed.
 */
Device Teardown Support
Perform device shutdown functions.

\param xbb  Per-instance xbb configuration structure.

Mark this instance as shutting down, wait for any active I/O on the
backend device/file to drain, disconnect from the front-end, and notify
any waiters  that detach can
now proceed.
Device Teardown Support Perform device shutdown functions . \ param xbb Per - instance xbb configuration structure . Mark this instance as shutting down wait for any active I / O on the backend device / file to drain disconnect from the front - end and notify any waiters that detach can now proceed .
static int
xbb_shutdown(struct xbb_softc *xbb)
{
	XenbusState frontState;
	int	    error;
	DPRINTF("\n");
	if ((xbb->flags & XBBF_IN_SHUTDOWN) != 0)
		return (EAGAIN);
	xbb->flags |= XBBF_IN_SHUTDOWN;
	mtx_unlock(&xbb->lock);
	if (xbb->hotplug_watch.node != NULL) {
		xs_unregister_watch(&xbb->hotplug_watch);
		free(xbb->hotplug_watch.node, M_XENBLOCKBACK);
		xbb->hotplug_watch.node = NULL;
	}
	if (xenbus_get_state(xbb->dev) < XenbusStateClosing)
		xenbus_set_state(xbb->dev, XenbusStateClosing);
	frontState = xenbus_get_otherend_state(xbb->dev);
	mtx_lock(&xbb->lock);
	xbb->flags &= ~XBBF_IN_SHUTDOWN;
	if (frontState == XenbusStateConnected)
		return (EAGAIN);
	DPRINTF("\n");
	xbb->flags |= XBBF_SHUTDOWN;
	error = xbb_disconnect(xbb);
	if (error != 0) {
		KASSERT(error == EAGAIN,
			("%s: Unexpected xbb_disconnect() failure %d",
			 __func__, error));
		return (error);
	}
	DPRINTF("\n");
	wakeup(xbb);
	return (0);
}
static int xbb_shutdown ( struct xbb_softc * xbb ) { XenbusState frontState ; int error ; DPRINTF ( " \n " ) ; if ( ( xbb -> flags & XBBF_IN_SHUTDOWN ) != 0 ) return ( EAGAIN ) ; xbb -> flags |= XBBF_IN_SHUTDOWN ; mtx_unlock ( & xbb -> lock ) ; if ( xbb -> hotplug_watch . node != NULL ) { xs_unregister_watch ( & xbb -> hotplug_watch ) ; free ( xbb -> hotplug_watch . node , M_XENBLOCKBACK ) ; xbb -> hotplug_watch . node = NULL ; } if ( xenbus_get_state ( xbb -> dev ) < XenbusStateClosing ) xenbus_set_state ( xbb -> dev , XenbusStateClosing ) ; frontState = xenbus_get_otherend_state ( xbb -> dev ) ; mtx_lock ( & xbb -> lock ) ; xbb -> flags &= ~ XBBF_IN_SHUTDOWN ; if ( frontState == XenbusStateConnected ) return ( EAGAIN ) ; DPRINTF ( " \n " ) ; xbb -> flags |= XBBF_SHUTDOWN ; error = xbb_disconnect ( xbb ) ; if ( error != 0 ) { KASSERT ( error == EAGAIN , ( " " , __func__ , error ) ) ; return ( error ) ; } DPRINTF ( " \n " ) ; wakeup ( xbb ) ; return ( 0 ) ; }
Device Teardown Support
 Perform device shutdown functions.
Device Teardown Support Perform device shutdown functions .
/*
	 * Due to the need to drop our mutex during some
	 * xenbus operations, it is possible for two threads
	 * to attempt to close out shutdown processing at
	 * the same time.  Tell the caller that hits this
	 * race to try back later. 
	 */ /* Wait for the frontend to disconnect (if it's connected). */ /* Indicate shutdown is in progress. */ /* Disconnect from the front-end. */ /*
		 * Requests still outstanding.  We'll be called again
		 * once they complete.
		 */ /* Indicate to xbb_detach() that is it safe to proceed. */