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; }
static int ic_scan(isc_session_t *sp) { union ccb *ccb; debug_called(8); sdebug(2, "scanning sid=%d", sp->sid); if((ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK | M_ZERO)) == NULL) { xdebug("scan failed (can't allocate CCB)"); return ENOMEM; // XXX } sp->flags &= ~ISC_CAMDEVS; sp->flags |= ISC_SCANWAIT; CAM_LOCK(sp); if(xpt_create_path(&sp->cam_path, NULL, cam_sim_path(sp->cam_sim), 0, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xdebug("can't create cam path"); CAM_UNLOCK(sp); free(ccb, M_TEMP); return ENODEV; // XXX } xpt_setup_ccb(&ccb->ccb_h, sp->cam_path, 5/*priority (low)*/); ccb->ccb_h.func_code = XPT_SCAN_BUS; ccb->ccb_h.cbfcnp = scan_callback; ccb->crcn.flags = CAM_FLAG_NONE; ccb->ccb_h.spriv_ptr0 = sp; xpt_action(ccb); CAM_UNLOCK(sp); while(sp->flags & ISC_SCANWAIT) tsleep(sp, PRIBIO, "ffp", 5*hz); // the timeout time should // be configurable sdebug(2, "# of luns=%d", sp->target_nluns); if(sp->target_nluns > 0) { sp->flags |= ISC_CAMDEVS; return 0; } return ENODEV; }
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"); } }