static void cfcs_onoffline(void *arg, int online) { struct cfcs_softc *softc; union ccb *ccb; softc = (struct cfcs_softc *)arg; mtx_lock(&softc->lock); softc->online = online; ccb = xpt_alloc_ccb_nowait(); if (ccb == NULL) { printf("%s: unable to allocate CCB for rescan\n", __func__); goto bailout; } if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(softc->sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { printf("%s: can't allocate path for rescan\n", __func__); xpt_free_ccb(ccb); goto bailout; } xpt_rescan(ccb); bailout: mtx_unlock(&softc->lock); }
static void * nvme_sim_new_ns(struct nvme_namespace *ns, void *sc_arg) { struct nvme_sim_softc *sc = sc_arg; struct nvme_controller *ctrlr = sc->s_ctrlr; union ccb *ccb; mtx_lock(&ctrlr->lock); ccb = xpt_alloc_ccb_nowait(); if (ccb == NULL) { printf("unable to alloc CCB for rescan\n"); return (NULL); } if (xpt_create_path(&ccb->ccb_h.path, /*periph*/NULL, cam_sim_path(sc->s_sim), 0, ns->id) != CAM_REQ_CMP) { printf("unable to create path for rescan\n"); xpt_free_ccb(ccb); return (NULL); } xpt_rescan(ccb); mtx_unlock(&ctrlr->lock); return (ns); }
void isci_controller_domain_discovery_complete( struct ISCI_CONTROLLER *isci_controller, struct ISCI_DOMAIN *isci_domain) { if (!isci_controller->has_been_scanned) { /* Controller has not been scanned yet. We'll clear * the discovery bit for this domain, then check if all bits * are now clear. That would indicate that all domains are * done with discovery and we can then proceed with initial * scan. */ isci_controller->initial_discovery_mask &= ~(1 << isci_domain->index); if (isci_controller->initial_discovery_mask == 0) { struct isci_softc *driver = isci_controller->isci; uint8_t next_index = isci_controller->index + 1; isci_controller->has_been_scanned = TRUE; /* Unfreeze simq to allow initial scan to proceed. */ xpt_release_simq(isci_controller->sim, TRUE); #if __FreeBSD_version < 800000 /* When driver is loaded after boot, we need to * explicitly rescan here for versions <8.0, because * CAM only automatically scans new buses at boot * time. */ union ccb *ccb = xpt_alloc_ccb_nowait(); xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(isci_controller->sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); xpt_rescan(ccb); #endif if (next_index < driver->controller_count) { /* There are more controllers that need to * start. So start the next one. */ isci_controller_start( &driver->controllers[next_index]); } else { /* All controllers have been started and completed discovery. * Disestablish the config hook while will signal to the * kernel during boot that it is safe to try to find and * mount the root partition. */ config_intrhook_disestablish( &driver->config_hook); } } } }
static void nvme_sim_rescan_target(struct nvme_controller *ctrlr, struct cam_path *path) { union ccb *ccb; ccb = xpt_alloc_ccb_nowait(); if (ccb == NULL) { printf("unable to alloc CCB for rescan\n"); return; } if (xpt_clone_path(&ccb->ccb_h.path, path) != CAM_REQ_CMP) { printf("unable to copy path for rescan\n"); xpt_free_ccb(ccb); return; } xpt_rescan(ccb); }
static void ata_conn_event(void *context, int dummy) { device_t dev = (device_t)context; struct ata_channel *ch = device_get_softc(dev); union ccb *ccb; mtx_lock(&ch->state_mtx); if (ch->sim == NULL) { mtx_unlock(&ch->state_mtx); return; } ata_reinit(dev); if ((ccb = xpt_alloc_ccb_nowait()) == NULL) return; if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(ch->sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_free_ccb(ccb); return; } xpt_rescan(ccb); mtx_unlock(&ch->state_mtx); }
/** * @brief This callback method informs the framework user that the remote * device is ready and capable of processing IO requests. * * @param[in] controller This parameter specifies the controller object * with which this callback is associated. * @param[in] domain This parameter specifies the domain object with * which this callback is associated. * @param[in] remote_device This parameter specifies the device object with * which this callback is associated. * * @return none */ void scif_cb_remote_device_ready(SCI_CONTROLLER_HANDLE_T controller, SCI_DOMAIN_HANDLE_T domain, SCI_REMOTE_DEVICE_HANDLE_T remote_device) { struct ISCI_REMOTE_DEVICE *isci_remote_device = sci_object_get_association(remote_device); struct ISCI_CONTROLLER *isci_controller = sci_object_get_association(controller); uint32_t device_index = isci_remote_device->index; if (isci_controller->remote_device[device_index] == NULL) { /* This new device is now ready, so put it in the controller's * remote device list so it is visible to CAM. */ isci_controller->remote_device[device_index] = isci_remote_device; if (isci_controller->has_been_scanned) { /* The sim object has been scanned at least once * already. In that case, create a CCB to instruct * CAM to rescan this device. * If the sim object has not been scanned, this device * will get scanned as part of the initial scan. */ union ccb *ccb = xpt_alloc_ccb_nowait(); xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(isci_controller->sim), isci_remote_device->index, CAM_LUN_WILDCARD); xpt_rescan(ccb); } } isci_remote_device_release_device_queue(isci_remote_device); }
/** * mpssas_SSU_to_SATA_devices * @sc: per adapter object * * Looks through the target list and issues a StartStopUnit SCSI command to each * SATA direct-access device. This helps to ensure that data corruption is * avoided when the system is being shut down. This must be called after the IR * System Shutdown RAID Action is sent if in IR mode. * * Return nothing. */ static void mpssas_SSU_to_SATA_devices(struct mps_softc *sc) { struct mpssas_softc *sassc = sc->sassc; union ccb *ccb; path_id_t pathid = cam_sim_path(sassc->sim); target_id_t targetid; struct mpssas_target *target; char path_str[64]; struct timeval cur_time, start_time; /* * For each target, issue a StartStopUnit command to stop the device. */ sc->SSU_started = TRUE; sc->SSU_refcount = 0; for (targetid = 0; targetid < sc->facts->MaxTargets; targetid++) { target = &sassc->targets[targetid]; if (target->handle == 0x0) { continue; } ccb = xpt_alloc_ccb_nowait(); if (ccb == NULL) { mps_dprint(sc, MPS_FAULT, "Unable to alloc CCB to stop " "unit.\n"); return; } /* * The stop_at_shutdown flag will be set if this device is * a SATA direct-access end device. */ if (target->stop_at_shutdown) { if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, pathid, targetid, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { mps_dprint(sc, MPS_FAULT, "Unable to create " "LUN path to stop unit.\n"); xpt_free_ccb(ccb); return; } xpt_path_string(ccb->ccb_h.path, path_str, sizeof(path_str)); mps_dprint(sc, MPS_INFO, "Sending StopUnit: path %s " "handle %d\n", path_str, target->handle); /* * Issue a START STOP UNIT command for the target. * Increment the SSU counter to be used to count the * number of required replies. */ mps_dprint(sc, MPS_INFO, "Incrementing SSU count\n"); sc->SSU_refcount++; ccb->ccb_h.target_id = xpt_path_target_id(ccb->ccb_h.path); ccb->ccb_h.ppriv_ptr1 = sassc; scsi_start_stop(&ccb->csio, /*retries*/0, mpssas_stop_unit_done, MSG_SIMPLE_Q_TAG, /*start*/FALSE, /*load/eject*/0, /*immediate*/FALSE, MPS_SENSE_LEN, /*timeout*/10000); xpt_action(ccb); } } /* * Wait until all of the SSU commands have completed or time has * expired (60 seconds). Pause for 100ms each time through. If any * command times out, the target will be reset in the SCSI command * timeout routine. */ getmicrotime(&start_time); while (sc->SSU_refcount) { pause("mpswait", hz/10); getmicrotime(&cur_time); if ((cur_time.tv_sec - start_time.tv_sec) > 60) { mps_dprint(sc, MPS_FAULT, "Time has expired waiting " "for SSU commands to complete.\n"); break; } } }