/* * vpo_attach() */ static int vpo_attach(device_t dev) { struct vpo_data *vpo = DEVTOSOFTC(dev); struct cam_devq *devq; int error; /* low level attachment */ if (vpo->vpo_isplus) { if ((error = imm_attach(&vpo->vpo_io))) return (error); } else { if ((error = vpoio_attach(&vpo->vpo_io))) return (error); } /* ** Now tell the generic SCSI layer ** about our bus. */ devq = cam_simq_alloc(/*maxopenings*/1); /* XXX What about low-level detach on error? */ if (devq == NULL) return (ENXIO); vpo->sim = cam_sim_alloc(vpo_action, vpo_poll, "vpo", vpo, device_get_unit(dev), /*untagged*/1, /*tagged*/0, devq); if (vpo->sim == NULL) { cam_simq_free(devq); return (ENXIO); } if (xpt_bus_register(vpo->sim, /*bus*/0) != CAM_SUCCESS) { cam_sim_free(vpo->sim, /*free_devq*/TRUE); return (ENXIO); } if (xpt_create_path(&vpo->path, /*periph*/NULL, cam_sim_path(vpo->sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_bus_deregister(cam_sim_path(vpo->sim)); cam_sim_free(vpo->sim, /*free_devq*/TRUE); return (ENXIO); } /* all went ok */ return (0); }
void mpt_cam_attach(mpt_softc_t *mpt) { struct cam_devq *devq; struct cam_sim *sim; int maxq; mpt->bus = 0; maxq = (mpt->mpt_global_credits < MPT_MAX_REQUESTS(mpt))? mpt->mpt_global_credits : MPT_MAX_REQUESTS(mpt); /* * Create the device queue for our SIM(s). */ devq = cam_simq_alloc(maxq); if (devq == NULL) { return; } /* * Construct our SIM entry. */ sim = cam_sim_alloc(mpt_action, mpt_poll, "mpt", mpt, mpt->unit, 1, maxq, devq); if (sim == NULL) { cam_simq_free(devq); return; } /* * Register exactly the bus. */ if (xpt_bus_register(sim, 0) != CAM_SUCCESS) { cam_sim_free(sim, TRUE); return; } if (xpt_create_path(&mpt->path, NULL, cam_sim_path(sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_bus_deregister(cam_sim_path(sim)); cam_sim_free(sim, TRUE); return; } mpt->sim = sim; }
/* * Register the driver as a CAM SIM */ static int aac_cam_attach(device_t dev) { struct cam_devq *devq; struct cam_sim *sim; struct cam_path *path; struct aac_cam *camsc; struct aac_sim *inf; fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); camsc = (struct aac_cam *)device_get_softc(dev); inf = (struct aac_sim *)device_get_ivars(dev); camsc->inf = inf; devq = cam_simq_alloc(inf->TargetsPerBus); if (devq == NULL) return (EIO); sim = cam_sim_alloc(aac_cam_action, aac_cam_poll, "aacp", camsc, device_get_unit(dev), &inf->aac_sc->aac_io_lock, 1, 1, devq); if (sim == NULL) { cam_simq_free(devq); return (EIO); } /* Since every bus has it's own sim, every bus 'appears' as bus 0 */ mtx_lock(&inf->aac_sc->aac_io_lock); if (xpt_bus_register(sim, dev, 0) != CAM_SUCCESS) { cam_sim_free(sim, TRUE); mtx_unlock(&inf->aac_sc->aac_io_lock); return (EIO); } if (xpt_create_path(&path, NULL, cam_sim_path(sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_bus_deregister(cam_sim_path(sim)); cam_sim_free(sim, TRUE); mtx_unlock(&inf->aac_sc->aac_io_lock); return (EIO); } mtx_unlock(&inf->aac_sc->aac_io_lock); camsc->sim = sim; camsc->path = path; return (0); }
/******************************************************************************** * Disconnect ourselves from CAM */ static int amr_cam_detach(device_t dev) { struct amr_softc *sc; int chn; sc = device_get_softc(dev); mtx_lock(&sc->amr_list_lock); for (chn = 0; chn < sc->amr_maxchan; chn++) { /* * If a sim was allocated for this channel, free it */ if (sc->amr_cam_sim[chn] != NULL) { xpt_bus_deregister(cam_sim_path(sc->amr_cam_sim[chn])); cam_sim_free(sc->amr_cam_sim[chn], FALSE); } } mtx_unlock(&sc->amr_list_lock); /* Now free the devq */ if (sc->amr_cam_devq != NULL) cam_simq_free(sc->amr_cam_devq); return (0); }
/******************************************************************************** * Disconnect ourselves from CAM */ static int amr_cam_detach(device_t dev) { struct amr_softc *sc; int chn; sc = device_get_softc(dev); lockmgr(&sc->amr_list_lock, LK_EXCLUSIVE); for (chn = 0; chn < sc->amr_maxchan; chn++) { /* * If a sim was allocated for this channel, free it */ if (sc->amr_cam_sim[chn] != NULL) { xpt_bus_deregister(cam_sim_path(sc->amr_cam_sim[chn])); cam_sim_free(sc->amr_cam_sim[chn]); } } lockmgr(&sc->amr_list_lock, LK_RELEASE); /* Now free the devq */ if (sc->amr_cam_devq != NULL) cam_simq_release(sc->amr_cam_devq); return (0); }
/******************************************************************************** * Detach from CAM */ void mly_cam_detach(struct mly_softc *sc) { int chn, nchn, first; debug_called(1); nchn = sc->mly_controllerinfo->physical_channels_present + sc->mly_controllerinfo->virtual_channels_present; /* * Iterate over channels, deregistering as we go. */ nchn = sc->mly_controllerinfo->physical_channels_present + sc->mly_controllerinfo->virtual_channels_present; for (chn = 0, first = 1; chn < nchn; chn++) { /* * If a sim was registered for this channel, free it. */ if (sc->mly_cam_sim[chn] != NULL) { debug(1, "deregister bus %d", chn); xpt_bus_deregister(cam_sim_path(sc->mly_cam_sim[chn])); debug(1, "free sim for channel %d (%sfree queue)", chn, first ? "" : "don't "); cam_sim_free(sc->mly_cam_sim[chn], first ? TRUE : FALSE); first = 0; } } }
int aha_attach(struct aha_softc *aha) { int tagged_dev_openings; struct cam_devq *devq; /* * We don't do tagged queueing, since the aha cards don't * support it. */ tagged_dev_openings = 0; /* * Create the device queue for our SIM. */ devq = cam_simq_alloc(aha->max_ccbs - 1); if (devq == NULL) return (ENOMEM); /* * Construct our SIM entry */ aha->sim = cam_sim_alloc(ahaaction, ahapoll, "aha", aha, device_get_unit(aha->dev), &aha->lock, 2, tagged_dev_openings, devq); if (aha->sim == NULL) { cam_simq_free(devq); return (ENOMEM); } mtx_lock(&aha->lock); if (xpt_bus_register(aha->sim, aha->dev, 0) != CAM_SUCCESS) { cam_sim_free(aha->sim, /*free_devq*/TRUE); mtx_unlock(&aha->lock); return (ENXIO); } if (xpt_create_path(&aha->path, /*periph*/NULL, cam_sim_path(aha->sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_bus_deregister(cam_sim_path(aha->sim)); cam_sim_free(aha->sim, /*free_devq*/TRUE); mtx_unlock(&aha->lock); return (ENXIO); } mtx_unlock(&aha->lock); return (0); }
int ic_init(isc_session_t *sp) { struct cam_sim *sim; struct cam_devq *devq; debug_called(8); if((devq = cam_simq_alloc(256)) == NULL) return ENOMEM; #if __FreeBSD_version >= 700000 mtx_init(&sp->cam_mtx, "isc-cam", NULL, MTX_DEF); #else isp->cam_mtx = Giant; #endif sim = cam_sim_alloc(ic_action, ic_poll, "iscsi", sp, sp->sid, // unit #if __FreeBSD_version >= 700000 &sp->cam_mtx, #endif 1, // max_dev_transactions 0, // max_tagged_dev_transactions devq); if(sim == NULL) { cam_simq_free(devq); #if __FreeBSD_version >= 700000 mtx_destroy(&sp->cam_mtx); #endif return ENXIO; } CAM_LOCK(sp); if(xpt_bus_register(sim, #if __FreeBSD_version >= 700000 NULL, #endif 0/*bus_number*/) != CAM_SUCCESS) { cam_sim_free(sim, /*free_devq*/TRUE); CAM_UNLOCK(sp); #if __FreeBSD_version >= 700000 mtx_destroy(&sp->cam_mtx); #endif return ENXIO; } sp->cam_sim = sim; CAM_UNLOCK(sp); sdebug(1, "cam subsystem initialized"); ic_scan(sp); return 0; }
/** * mrsas_cam_detach: De-allocates and teardown CAM * input: Adapter instance soft state * * De-registers and frees the paths and SIMs. */ void mrsas_cam_detach(struct mrsas_softc *sc) { if (sc->ev_tq != NULL) taskqueue_free(sc->ev_tq); lockmgr(&sc->sim_lock, LK_EXCLUSIVE); if (sc->path_0) xpt_free_path(sc->path_0); if (sc->sim_0) { xpt_bus_deregister(cam_sim_path(sc->sim_0)); cam_sim_free(sc->sim_0); } if (sc->path_1) xpt_free_path(sc->path_1); if (sc->sim_1) { xpt_bus_deregister(cam_sim_path(sc->sim_1)); cam_sim_free(sc->sim_1); } lockmgr(&sc->sim_lock, LK_RELEASE); }
void mpt_cam_detach(mpt_softc_t *mpt) { if (mpt->sim != NULL) { xpt_free_path(mpt->path); xpt_bus_deregister(cam_sim_path(mpt->sim)); cam_sim_free(mpt->sim, TRUE); mpt->sim = NULL; } }
/* * Function name: twa_cam_detach * Description: Detaches the driver from CAM. * * Input: sc -- ptr to per ctlr structure * Output: None * Return value: None */ void twa_cam_detach(struct twa_softc *sc) { if (sc->twa_path) xpt_free_path(sc->twa_path); if (sc->twa_sim) { xpt_bus_deregister(cam_sim_path(sc->twa_sim)); cam_sim_free(sc->twa_sim, TRUE); /* passing TRUE will free the devq as well */ } }
/** * mrsas_cam_detach: De-allocates and teardown CAM * input: Adapter instance soft state * * De-registers and frees the paths and SIMs. */ void mrsas_cam_detach(struct mrsas_softc *sc) { if (sc->ev_tq != NULL) taskqueue_free(sc->ev_tq); mtx_lock(&sc->sim_lock); if (sc->path_0) xpt_free_path(sc->path_0); if (sc->sim_0) { xpt_bus_deregister(cam_sim_path(sc->sim_0)); cam_sim_free(sc->sim_0, FALSE); } if (sc->path_1) xpt_free_path(sc->path_1); if (sc->sim_1) { xpt_bus_deregister(cam_sim_path(sc->sim_1)); cam_sim_free(sc->sim_1, TRUE); } mtx_unlock(&sc->sim_lock); }
int isci_controller_attach_to_cam(struct ISCI_CONTROLLER *controller) { struct isci_softc *isci = controller->isci; device_t parent = device_get_parent(isci->device); int unit = device_get_unit(isci->device); struct cam_devq *isci_devq = cam_simq_alloc(controller->sim_queue_depth); if(isci_devq == NULL) { isci_log_message(0, "ISCI", "isci_devq is NULL \n"); return (-1); } controller->sim = cam_sim_alloc(isci_action, isci_poll, "isci", controller, unit, &controller->lock, controller->sim_queue_depth, controller->sim_queue_depth, isci_devq); if(controller->sim == NULL) { isci_log_message(0, "ISCI", "cam_sim_alloc... fails\n"); cam_simq_free(isci_devq); return (-1); } if(xpt_bus_register(controller->sim, parent, controller->index) != CAM_SUCCESS) { isci_log_message(0, "ISCI", "xpt_bus_register...fails \n"); cam_sim_free(controller->sim, TRUE); mtx_unlock(&controller->lock); return (-1); } if(xpt_create_path(&controller->path, NULL, cam_sim_path(controller->sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { isci_log_message(0, "ISCI", "xpt_create_path....fails\n"); xpt_bus_deregister(cam_sim_path(controller->sim)); cam_sim_free(controller->sim, TRUE); mtx_unlock(&controller->lock); return (-1); } return (0); }
int aha_detach(struct aha_softc *aha) { mtx_lock(&aha->lock); xpt_async(AC_LOST_DEVICE, aha->path, NULL); xpt_free_path(aha->path); xpt_bus_deregister(cam_sim_path(aha->sim)); cam_sim_free(aha->sim, /*free_devq*/TRUE); mtx_unlock(&aha->lock); /* XXX: Drain all timers? */ return (0); }
void tws_cam_detach(struct tws_softc *sc) { TWS_TRACE_DEBUG(sc, "entry", 0, 0); mtx_lock(&sc->sim_lock); if (sc->path) xpt_free_path(sc->path); if (sc->sim) { xpt_bus_deregister(cam_sim_path(sc->sim)); cam_sim_free(sc->sim, TRUE); } mtx_unlock(&sc->sim_lock); }
void tws_cam_detach(struct tws_softc *sc) { TWS_TRACE_DEBUG(sc, "entry", 0, 0); lockmgr(&sc->sim_lock, LK_EXCLUSIVE); if (sc->path) xpt_free_path(sc->path); if (sc->sim) { xpt_bus_deregister(cam_sim_path(sc->sim)); cam_sim_free(sc->sim); } lockmgr(&sc->sim_lock, LK_RELEASE); }
static void nvme_sim_controller_fail(void *ctrlr_arg) { struct nvme_sim_softc *sc = ctrlr_arg; struct nvme_controller *ctrlr = sc->s_ctrlr; mtx_lock(&ctrlr->lock); xpt_async(AC_LOST_DEVICE, sc->s_path, NULL); xpt_free_path(sc->s_path); xpt_bus_deregister(cam_sim_path(sc->s_sim)); cam_sim_free(sc->s_sim, /*free_devq*/TRUE); mtx_unlock(&ctrlr->lock); free(sc, M_NVME); }
/******************************************************************************** * Disconnect ourselves from CAM */ void amr_cam_detach(struct amr_softc *sc) { int chn, first; for (chn = 0, first = 1; chn < sc->amr_maxchan; chn++) { /* * If a sim was allocated for this channel, free it */ if (sc->amr_cam_sim[chn] != NULL) { xpt_bus_deregister(cam_sim_path(sc->amr_cam_sim[chn])); cam_sim_free(sc->amr_cam_sim[chn], first ? TRUE : FALSE); first = 0; } } }
/* * Function name: tw_osli_cam_detach * Description: Detaches the driver from CAM. * * Input: sc -- ptr to OSL internal ctlr context * Output: None * Return value: None */ TW_VOID tw_osli_cam_detach(struct twa_softc *sc) { tw_osli_dbg_dprintf(3, sc, "entered"); mtx_lock(sc->sim_lock); if (sc->path) xpt_free_path(sc->path); if (sc->sim) { xpt_bus_deregister(cam_sim_path(sc->sim)); /* Passing TRUE to cam_sim_free will free the devq as well. */ cam_sim_free(sc->sim, TRUE); } /* It's ok have 1 hold count while destroying the mutex */ mtx_destroy(sc->sim_lock); }
/* * vpo_attach() */ static int vpo_attach(device_t dev) { struct vpo_data *vpo = DEVTOSOFTC(dev); device_t ppbus = device_get_parent(dev); struct ppb_data *ppb = device_get_softc(ppbus); /* XXX: layering */ struct cam_devq *devq; int error; /* low level attachment */ if (vpo->vpo_isplus) { if ((error = imm_attach(&vpo->vpo_io))) return (error); } else { if ((error = vpoio_attach(&vpo->vpo_io))) return (error); } /* ** Now tell the generic SCSI layer ** about our bus. */ devq = cam_simq_alloc(/*maxopenings*/1); /* XXX What about low-level detach on error? */ if (devq == NULL) return (ENXIO); vpo->sim = cam_sim_alloc(vpo_action, vpo_poll, "vpo", vpo, device_get_unit(dev), ppb->ppc_lock, /*untagged*/1, /*tagged*/0, devq); if (vpo->sim == NULL) { cam_simq_free(devq); return (ENXIO); } ppb_lock(ppbus); if (xpt_bus_register(vpo->sim, dev, /*bus*/0) != CAM_SUCCESS) { cam_sim_free(vpo->sim, /*free_devq*/TRUE); ppb_unlock(ppbus); return (ENXIO); } ppb_unlock(ppbus); return (0); }
static int mfip_detach(device_t dev) { struct mfip_softc *sc; sc = device_get_softc(dev); if (sc == NULL) return (EINVAL); if (sc->sim != NULL) { lockmgr(&sc->mfi_sc->mfi_io_lock, LK_EXCLUSIVE); xpt_bus_deregister(cam_sim_path(sc->sim)); cam_sim_free(sc->sim); lockmgr(&sc->mfi_sc->mfi_io_lock, LK_RELEASE); } return (0); }
/* * vpo_attach() */ static int vpo_attach(device_t dev) { struct vpo_data *vpo = DEVTOSOFTC(dev); struct cam_devq *devq; int error; /* low level attachment */ if (vpo->vpo_isplus) { if ((error = imm_attach(&vpo->vpo_io))) return (error); } else { if ((error = vpoio_attach(&vpo->vpo_io))) return (error); } /* ** Now tell the generic SCSI layer ** about our bus. */ devq = cam_simq_alloc(/*maxopenings*/1); /* XXX What about low-level detach on error? */ if (devq == NULL) return (ENXIO); vpo->sim = cam_sim_alloc(vpo_action, vpo_poll, "vpo", vpo, device_get_unit(dev), &sim_mplock, /*untagged*/1, /*tagged*/0, devq); cam_simq_release(devq); if (vpo->sim == NULL) { return (ENXIO); } if (xpt_bus_register(vpo->sim, /*bus*/0) != CAM_SUCCESS) { cam_sim_free(vpo->sim); return (ENXIO); } /* all went ok */ vpo_cam_rescan(vpo); /* have CAM rescan the bus */ return (0); }
static void * nvme_sim_new_controller(struct nvme_controller *ctrlr) { struct nvme_sim_softc *sc; struct cam_devq *devq; int max_trans; max_trans = ctrlr->max_hw_pend_io; devq = cam_simq_alloc(max_trans); if (devq == NULL) return (NULL); sc = malloc(sizeof(*sc), M_NVME, M_ZERO | M_WAITOK); sc->s_ctrlr = ctrlr; sc->s_sim = cam_sim_alloc(nvme_sim_action, nvme_sim_poll, "nvme", sc, device_get_unit(ctrlr->dev), &ctrlr->lock, max_trans, max_trans, devq); if (sc->s_sim == NULL) { printf("Failed to allocate a sim\n"); cam_simq_free(devq); goto err1; } if (xpt_bus_register(sc->s_sim, ctrlr->dev, 0) != CAM_SUCCESS) { printf("Failed to create a bus\n"); goto err2; } if (xpt_create_path(&sc->s_path, /*periph*/NULL, cam_sim_path(sc->s_sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { printf("Failed to create a path\n"); goto err3; } return (sc); err3: xpt_bus_deregister(cam_sim_path(sc->s_sim)); err2: cam_sim_free(sc->s_sim, /*free_devq*/TRUE); err1: free(sc, M_NVME); return (NULL); }
static int mfip_detach(device_t dev) { struct mfip_softc *sc; sc = device_get_softc(dev); if (sc == NULL) return (EINVAL); if (sc->sim != NULL) { mtx_lock(&sc->mfi_sc->mfi_io_lock); xpt_bus_deregister(cam_sim_path(sc->sim)); cam_sim_free(sc->sim, FALSE); mtx_unlock(&sc->mfi_sc->mfi_io_lock); } if (sc->devq != NULL) cam_simq_free(sc->devq); return (0); }
static int aac_cam_detach(device_t dev) { struct aac_softc *sc; struct aac_cam *camsc; fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); camsc = (struct aac_cam *)device_get_softc(dev); sc = camsc->inf->aac_sc; mtx_lock(&sc->aac_io_lock); xpt_async(AC_LOST_DEVICE, camsc->path, NULL); xpt_free_path(camsc->path); xpt_bus_deregister(cam_sim_path(camsc->sim)); cam_sim_free(camsc->sim, /*free_devq*/TRUE); mtx_unlock(&sc->aac_io_lock); return (0); }
void ic_destroy(isc_session_t *sp ) { debug_called(8); if(sp->cam_path != NULL) { sdebug(2, "name=%s unit=%d", cam_sim_name(sp->cam_sim), cam_sim_unit(sp->cam_sim)); CAM_LOCK(sp); #if 0 xpt_async(AC_LOST_DEVICE, sp->cam_path, NULL); #else xpt_async(XPT_RESET_BUS, sp->cam_path, NULL); #endif xpt_free_path(sp->cam_path); xpt_bus_deregister(cam_sim_path(sp->cam_sim)); cam_sim_free(sp->cam_sim, TRUE /*free_devq*/); CAM_UNLOCK(sp); sdebug(2, "done"); } }
static int mfip_attach(device_t dev) { struct mfip_softc *sc; struct mfi_softc *mfisc; sc = device_get_softc(dev); if (sc == NULL) return (EINVAL); mfisc = device_get_softc(device_get_parent(dev)); sc->dev = dev; sc->mfi_sc = mfisc; mfisc->mfi_cam_start = mfip_start; if ((sc->devq = cam_simq_alloc(MFI_SCSI_MAX_CMDS)) == NULL) return (ENOMEM); sc->sim = cam_sim_alloc(mfip_cam_action, mfip_cam_poll, "mfi", sc, device_get_unit(dev), &mfisc->mfi_io_lock, 1, MFI_SCSI_MAX_CMDS, sc->devq); if (sc->sim == NULL) { cam_simq_free(sc->devq); device_printf(dev, "CAM SIM attach failed\n"); return (EINVAL); } mtx_lock(&mfisc->mfi_io_lock); if (xpt_bus_register(sc->sim, dev, 0) != 0) { device_printf(dev, "XPT bus registration failed\n"); cam_sim_free(sc->sim, FALSE); cam_simq_free(sc->devq); mtx_unlock(&mfisc->mfi_io_lock); return (EINVAL); } mtx_unlock(&mfisc->mfi_io_lock); return (0); }
int ata_detach(device_t dev) { struct ata_channel *ch = device_get_softc(dev); /* check that we have a valid channel to detach */ if (!ch->r_irq) return ENXIO; /* grap the channel lock so no new requests gets launched */ mtx_lock(&ch->state_mtx); ch->state |= ATA_STALL_QUEUE; mtx_unlock(&ch->state_mtx); if (ch->flags & ATA_PERIODIC_POLL) callout_drain(&ch->poll_callout); taskqueue_drain(taskqueue_thread, &ch->conntask); mtx_lock(&ch->state_mtx); xpt_async(AC_LOST_DEVICE, ch->path, NULL); xpt_free_path(ch->path); xpt_bus_deregister(cam_sim_path(ch->sim)); cam_sim_free(ch->sim, /*free_devq*/TRUE); ch->sim = NULL; mtx_unlock(&ch->state_mtx); /* release resources */ bus_teardown_intr(dev, ch->r_irq, ch->ih); bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); ch->r_irq = NULL; /* free DMA resources if DMA HW present*/ if (ch->dma.free) ch->dma.free(dev); mtx_destroy(&ch->state_mtx); return 0; }
void ahci_cam_detach(struct ahci_port *ap) { int error; if ((ap->ap_flags & AP_F_CAM_ATTACHED) == 0) return; lockmgr(&ap->ap_sim_lock, LK_EXCLUSIVE); if (ap->ap_sim) { xpt_freeze_simq(ap->ap_sim, 1); } if (ap->ap_flags & AP_F_BUS_REGISTERED) { error = xpt_bus_deregister(cam_sim_path(ap->ap_sim)); KKASSERT(error == CAM_REQ_CMP); ap->ap_flags &= ~AP_F_BUS_REGISTERED; } if (ap->ap_sim) { cam_sim_free(ap->ap_sim); ap->ap_sim = NULL; } lockmgr(&ap->ap_sim_lock, LK_RELEASE); ap->ap_flags &= ~AP_F_CAM_ATTACHED; }
static int ahci_em_detach(device_t dev) { struct ahci_enclosure *enc = device_get_softc(dev); int i; for (i = 0; i < enc->channels * AHCI_NUM_LEDS; i++) { if (enc->leds[i].led) led_destroy(enc->leds[i].led); } mtx_lock(&enc->mtx); xpt_async(AC_LOST_DEVICE, enc->path, NULL); xpt_free_path(enc->path); xpt_bus_deregister(cam_sim_path(enc->sim)); cam_sim_free(enc->sim, /*free_devq*/TRUE); mtx_unlock(&enc->mtx); bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc); bus_release_resource(dev, SYS_RES_MEMORY, 1, enc->r_memt); if (enc->r_memr) bus_release_resource(dev, SYS_RES_MEMORY, 2, enc->r_memr); mtx_destroy(&enc->mtx); return (0); }