FreeBSD/sys/dev/xen/blkback/blkback.c
/**
 * Detach from a block back device instance.
 *
 * \param dev  NewBus device object representing this Xen Block Back instance.
 *
 * \return  0 for success, errno codes for failure.
 * 
 * \note A block back device may be detached at any time in its life-cycle,
 *       including part way through the attach process.  For this reason,
 *       initialization order and the initialization state checks in this
 *       routine must be carefully coupled so that attach time failures
 *       are gracefully handled.
 */
Detach from a block back device instance.
\param dev  NewBus device object representing this Xen Block Back instance.

\return  0 for success, errno codes for failure.

\note A block back device may be detached at any time in its life-cycle,
including part way through the attach process.  For this reason,
initialization order and the initialization state checks in this
routine must be carefully coupled so that attach time failures
are gracefully handled.
Detach from a block back device instance . \ param dev NewBus device object representing this Xen Block Back instance . \ return 0 for success errno codes for failure . \ note A block back device may be detached at any time in its life - cycle including part way through the attach process . For this reason initialization order and the initialization state checks in this routine must be carefully coupled so that attach time failures are gracefully handled .
static int
xbb_detach(device_t dev)
{
        struct xbb_softc *xbb;
	DPRINTF("\n");
        xbb = device_get_softc(dev);
	mtx_lock(&xbb->lock);
	while (xbb_shutdown(xbb) == EAGAIN) {
		msleep(xbb, &xbb->lock, 0,
		       "xbb_shutdown", 0);
	}
	mtx_unlock(&xbb->lock);
	DPRINTF("\n");
	if (xbb->io_taskqueue != NULL)
		taskqueue_free(xbb->io_taskqueue);
	if (xbb->xbb_stats != NULL)
		devstat_remove_entry(xbb->xbb_stats);
	if (xbb->xbb_stats_in != NULL)
		devstat_remove_entry(xbb->xbb_stats_in);
	xbb_close_backend(xbb);
	if (xbb->dev_mode != NULL) {
		free(xbb->dev_mode, M_XENSTORE);
		xbb->dev_mode = NULL;
	}
	if (xbb->dev_type != NULL) {
		free(xbb->dev_type, M_XENSTORE);
		xbb->dev_type = NULL;
	}
	if (xbb->dev_name != NULL) {
		free(xbb->dev_name, M_XENSTORE);
		xbb->dev_name = NULL;
	}
	mtx_destroy(&xbb->lock);
        return (0);
}
static int xbb_detach ( device_t dev ) { struct xbb_softc * xbb ; DPRINTF ( " \n " ) ; xbb = device_get_softc ( dev ) ; mtx_lock ( & xbb -> lock ) ; while ( xbb_shutdown ( xbb ) == EAGAIN ) { msleep ( xbb , & xbb -> lock , 0 , " " , 0 ) ; } mtx_unlock ( & xbb -> lock ) ; DPRINTF ( " \n " ) ; if ( xbb -> io_taskqueue != NULL ) taskqueue_free ( xbb -> io_taskqueue ) ; if ( xbb -> xbb_stats != NULL ) devstat_remove_entry ( xbb -> xbb_stats ) ; if ( xbb -> xbb_stats_in != NULL ) devstat_remove_entry ( xbb -> xbb_stats_in ) ; xbb_close_backend ( xbb ) ; if ( xbb -> dev_mode != NULL ) { free ( xbb -> dev_mode , M_XENSTORE ) ; xbb -> dev_mode = NULL ; } if ( xbb -> dev_type != NULL ) { free ( xbb -> dev_type , M_XENSTORE ) ; xbb -> dev_type = NULL ; } if ( xbb -> dev_name != NULL ) { free ( xbb -> dev_name , M_XENSTORE ) ; xbb -> dev_name = NULL ; } mtx_destroy ( & xbb -> lock ) ; return ( 0 ) ; }
Detach from a block back device instance.
Detach from a block back device instance .
/*wakeup prio unchanged*/