/* * mrsas_bus_scan: Perform bus scan * input: Adapter instance soft state * * This mrsas_bus_scan function is needed for FreeBSD 7.x. Also, it should not * be called in FreeBSD 8.x and later versions, where the bus scan is * automatic. */ int mrsas_bus_scan(struct mrsas_softc *sc) { union ccb *ccb_0; union ccb *ccb_1; if ((ccb_0 = xpt_alloc_ccb()) == NULL) { return (ENOMEM); } if ((ccb_1 = xpt_alloc_ccb()) == NULL) { xpt_free_ccb(ccb_0); return (ENOMEM); } mtx_lock(&sc->sim_lock); if (xpt_create_path(&ccb_0->ccb_h.path, xpt_periph, cam_sim_path(sc->sim_0), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_free_ccb(ccb_0); xpt_free_ccb(ccb_1); mtx_unlock(&sc->sim_lock); return (EIO); } if (xpt_create_path(&ccb_1->ccb_h.path, xpt_periph, cam_sim_path(sc->sim_1), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_free_ccb(ccb_0); xpt_free_ccb(ccb_1); mtx_unlock(&sc->sim_lock); return (EIO); } mtx_unlock(&sc->sim_lock); xpt_rescan(ccb_0); xpt_rescan(ccb_1); return (0); }
/* * mrsas_bus_scan: Perform bus scan * input: Adapter instance soft state * * This mrsas_bus_scan function is needed for FreeBSD 7.x. Also, it should * not be called in FreeBSD 8.x and later versions, where the bus scan is * automatic. */ int mrsas_bus_scan(struct mrsas_softc *sc) { union ccb *ccb_0; union ccb *ccb_1; lockmgr(&sc->sim_lock, LK_EXCLUSIVE); if ((ccb_0 = xpt_alloc_ccb()) == NULL) { lockmgr(&sc->sim_lock, LK_RELEASE); return(ENOMEM); } if ((ccb_1 = xpt_alloc_ccb()) == NULL) { xpt_free_ccb(ccb_0); lockmgr(&sc->sim_lock, LK_RELEASE); return(ENOMEM); } if (xpt_create_path(&ccb_0->ccb_h.path, xpt_periph, cam_sim_path(sc->sim_0), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP){ xpt_free_ccb(ccb_0); xpt_free_ccb(ccb_1); lockmgr(&sc->sim_lock, LK_RELEASE); return(EIO); } if (xpt_create_path(&ccb_1->ccb_h.path, xpt_periph, cam_sim_path(sc->sim_1), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP){ xpt_free_ccb(ccb_0); xpt_free_ccb(ccb_1); lockmgr(&sc->sim_lock, LK_RELEASE); return(EIO); } xpt_setup_ccb(&ccb_0->ccb_h, ccb_0->ccb_h.path, 5/*priority (low)*/); ccb_0->ccb_h.func_code = XPT_SCAN_BUS; ccb_0->ccb_h.cbfcnp = mrsas_rescan_callback; ccb_0->crcn.flags = CAM_FLAG_NONE; xpt_action(ccb_0); /* scan is now in progress */ xpt_setup_ccb(&ccb_1->ccb_h, ccb_1->ccb_h.path, 5/*priority (low)*/); ccb_1->ccb_h.func_code = XPT_SCAN_BUS; ccb_1->ccb_h.cbfcnp = mrsas_rescan_callback; ccb_1->crcn.flags = CAM_FLAG_NONE; xpt_action(ccb_1); /* scan is now in progress */ lockmgr(&sc->sim_lock, LK_RELEASE); return(0); }
static void ahci_cam_rescan(struct ahci_port *ap) { struct cam_path *path; union ccb *ccb; int status; int i; if (ap->ap_flags & AP_F_SCAN_RUNNING) { ap->ap_flags |= AP_F_SCAN_REQUESTED; return; } ap->ap_flags |= AP_F_SCAN_RUNNING; for (i = 0; i < AHCI_MAX_PMPORTS; ++i) { ap->ap_ata[i]->at_features |= ATA_PORT_F_RESCAN; } status = xpt_create_path(&path, xpt_periph, cam_sim_path(ap->ap_sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); if (status != CAM_REQ_CMP) return; ccb = xpt_alloc_ccb(); xpt_setup_ccb(&ccb->ccb_h, path, 5); /* 5 = low priority */ ccb->ccb_h.func_code = XPT_ENG_EXEC; ccb->ccb_h.cbfcnp = ahci_cam_rescan_callback; ccb->ccb_h.sim_priv.entries[0].ptr = ap; ccb->crcn.flags = CAM_FLAG_NONE; xpt_action_async(ccb); }
static int ic_scan(isc_session_t *sp) { union ccb *ccb; debug_called(8); sdebug(2, "scanning sid=%d", sp->sid); sp->flags &= ~ISC_CAMDEVS; sp->flags |= ISC_SCANWAIT; ccb = xpt_alloc_ccb(); ccb->ccb_h.path = sp->cam_path; ccb->ccb_h.cbfcnp = scan_callback; ccb->ccb_h.spriv_ptr0 = sp; xpt_rescan(ccb); 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; }
/* * Function name: tw_osli_request_bus_scan * Description: Requests CAM for a scan of the bus. * * Input: sc -- ptr to per ctlr structure * Output: None * Return value: 0 -- success * non-zero-- failure */ TW_INT32 tw_osli_request_bus_scan(struct twa_softc *sc) { union ccb *ccb; tw_osli_dbg_dprintf(3, sc, "entering"); /* If we get here before sc->sim is initialized, return an error. */ if (!(sc->sim)) return(ENXIO); if ((ccb = xpt_alloc_ccb()) == NULL) return(ENOMEM); lockmgr(sc->sim_lock, LK_EXCLUSIVE); if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(sc->sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_free_ccb(ccb); lockmgr(sc->sim_lock, LK_RELEASE); return(EIO); } xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, 5/*priority (low)*/); ccb->ccb_h.func_code = XPT_SCAN_BUS; ccb->ccb_h.cbfcnp = twa_bus_scan_cb; ccb->crcn.flags = CAM_FLAG_NONE; xpt_action(ccb); lockmgr(sc->sim_lock, LK_RELEASE); return(0); }
static void ahci_xpt_rescan(struct ahci_port *ap) { struct cam_path *path; union ccb *ccb; int status; status = xpt_create_path(&path, xpt_periph, cam_sim_path(ap->ap_sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); if (status != CAM_REQ_CMP) return; ccb = xpt_alloc_ccb(); xpt_setup_ccb(&ccb->ccb_h, path, 5); /* 5 = low priority */ ccb->ccb_h.func_code = XPT_SCAN_BUS; ccb->ccb_h.cbfcnp = ahci_cam_rescan_callback; ccb->ccb_h.sim_priv.entries[0].ptr = ap; ccb->crcn.flags = CAM_FLAG_NONE; xpt_action_async(ccb); }
int tws_bus_scan(struct tws_softc *sc) { union ccb *ccb; TWS_TRACE_DEBUG(sc, "entry", sc, 0); if (!(sc->sim)) return(ENXIO); ccb = xpt_alloc_ccb(); mtx_lock(&sc->sim_lock); if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(sc->sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { mtx_unlock(&sc->sim_lock); xpt_free_ccb(ccb); return(EIO); } xpt_rescan(ccb); mtx_unlock(&sc->sim_lock); return(0); }
/* * Function name: tw_osli_request_bus_scan * Description: Requests CAM for a scan of the bus. * * Input: sc -- ptr to per ctlr structure * Output: None * Return value: 0 -- success * non-zero-- failure */ TW_INT32 tw_osli_request_bus_scan(struct twa_softc *sc) { union ccb *ccb; tw_osli_dbg_dprintf(3, sc, "entering"); /* If we get here before sc->sim is initialized, return an error. */ if (!(sc->sim)) return(ENXIO); if ((ccb = xpt_alloc_ccb()) == NULL) return(ENOMEM); mtx_lock(sc->sim_lock); if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(sc->sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_free_ccb(ccb); mtx_unlock(sc->sim_lock); return(EIO); } xpt_rescan(ccb); mtx_unlock(sc->sim_lock); return(0); }
/* * Attach all the sub-devices we can find */ int adv_attach(struct adv_softc *adv) { struct ccb_setasync *csa; int max_sg; /* * Allocate an array of ccb mapping structures. We put the * index of the ccb_info structure into the queue representing * a transaction and use it for mapping the queue to the * upper level SCSI transaction it represents. */ adv->ccb_infos = kmalloc(sizeof(*adv->ccb_infos) * adv->max_openings, M_DEVBUF, M_WAITOK); adv->init_level++; /* * Create our DMA tags. These tags define the kinds of device * accessible memory allocations and memory mappings we will * need to perform during normal operation. * * Unless we need to further restrict the allocation, we rely * on the restrictions of the parent dmat, hence the common * use of MAXADDR and MAXSIZE. * * The ASC boards use chains of "queues" (the transactional * resources on the board) to represent long S/G lists. * The first queue represents the command and holds a * single address and data pair. The queues that follow * can each hold ADV_SG_LIST_PER_Q entries. Given the * total number of queues, we can express the largest * transaction we can map. We reserve a few queues for * error recovery. Take those into account as well. * * There is a way to take an interrupt to download the * next batch of S/G entries if there are more than 255 * of them (the counter in the queue structure is a u_int8_t). * We don't use this feature, so limit the S/G list size * accordingly. */ max_sg = (adv->max_openings - ADV_MIN_FREE_Q - 1) * ADV_SG_LIST_PER_Q; if (max_sg > 255) max_sg = 255; /* DMA tag for mapping buffers into device visible space. */ if (bus_dma_tag_create(adv->parent_dmat, /*alignment*/1, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, /*maxsize*/MAXPHYS, /*nsegments*/max_sg, /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, /*flags*/BUS_DMA_ALLOCNOW, &adv->buffer_dmat) != 0) { return (ENXIO); } adv->init_level++; /* DMA tag for our sense buffers */ if (bus_dma_tag_create(adv->parent_dmat, /*alignment*/1, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, sizeof(struct scsi_sense_data)*adv->max_openings, /*nsegments*/1, /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, /*flags*/0, &adv->sense_dmat) != 0) { return (ENXIO); } adv->init_level++; /* Allocation for our sense buffers */ if (bus_dmamem_alloc(adv->sense_dmat, (void *)&adv->sense_buffers, BUS_DMA_NOWAIT, &adv->sense_dmamap) != 0) { return (ENOMEM); } adv->init_level++; /* And permanently map them */ bus_dmamap_load(adv->sense_dmat, adv->sense_dmamap, adv->sense_buffers, sizeof(struct scsi_sense_data)*adv->max_openings, adv_map, &adv->sense_physbase, /*flags*/0); adv->init_level++; /* * Fire up the chip */ if (adv_start_chip(adv) != 1) { kprintf("adv%d: Unable to start on board processor. Aborting.\n", adv->unit); return (ENXIO); } /* * Construct our SIM entry. */ adv->sim = cam_sim_alloc(adv_action, adv_poll, "adv", adv, adv->unit, &sim_mplock, 1, adv->max_openings, NULL); if (adv->sim == NULL) return (ENOMEM); /* * Register the bus. * * XXX Twin Channel EISA Cards??? */ if (xpt_bus_register(adv->sim, 0) != CAM_SUCCESS) { cam_sim_free(adv->sim); return (ENXIO); } if (xpt_create_path(&adv->path, /*periph*/NULL, cam_sim_path(adv->sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_bus_deregister(cam_sim_path(adv->sim)); cam_sim_free(adv->sim); return (ENXIO); } csa = &xpt_alloc_ccb()->csa; xpt_setup_ccb(&csa->ccb_h, adv->path, /*priority*/5); csa->ccb_h.func_code = XPT_SASYNC_CB; csa->event_enable = AC_FOUND_DEVICE|AC_LOST_DEVICE; csa->callback = advasync; csa->callback_arg = adv; xpt_action((union ccb *)csa); xpt_free_ccb(&csa->ccb_h); return (0); }
static int cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td, d_ioctl_t *cbfnp) { union ccb *ccb; struct ccb_hdr *hdr; struct ccb_hdr_0x18 *hdr18; uint8_t *ccbb, *ccbb18; u_int error; hdr18 = (struct ccb_hdr_0x18 *)addr; ccb = xpt_alloc_ccb(); hdr = &ccb->ccb_h; hdr->pinfo = hdr18->pinfo; hdr->xpt_links = hdr18->xpt_links; hdr->sim_links = hdr18->sim_links; hdr->periph_links = hdr18->periph_links; hdr->retry_count = hdr18->retry_count; hdr->cbfcnp = hdr18->cbfcnp; hdr->func_code = hdr18->func_code; hdr->status = hdr18->status; hdr->path = hdr18->path; hdr->path_id = hdr18->path_id; hdr->target_id = hdr18->target_id; hdr->target_lun = hdr18->target_lun; if (hdr18->xflags & CAM_EXTLUN_VALID_0x18) hdr->target_lun = hdr18->ext_lun; hdr->flags = hdr18->flags; hdr->xflags = hdr18->xflags; hdr->periph_priv = hdr18->periph_priv; hdr->sim_priv = hdr18->sim_priv; hdr->timeout = hdr18->timeout; hdr->softtimeout.tv_sec = 0; hdr->softtimeout.tv_usec = 0; ccbb = (uint8_t *)&hdr[1]; ccbb18 = (uint8_t *)&hdr18[1]; if (ccb->ccb_h.func_code == XPT_SET_TRAN_SETTINGS) { struct ccb_trans_settings *cts; struct ccb_trans_settings_0x18 *cts18; cts = &ccb->cts; cts18 = (struct ccb_trans_settings_0x18 *)hdr18; cts->type = cts18->type; cts->protocol = cts18->protocol; cts->protocol_version = cts18->protocol_version; cts->transport = cts18->transport; cts->transport_version = cts18->transport_version; bcopy(&cts18->proto_specific, &cts->proto_specific, sizeof(cts18->proto_specific)); bcopy(&cts18->xport_specific, &cts->xport_specific, sizeof(cts18->xport_specific)); } else { bcopy(ccbb18, ccbb, CAM_0X18_DATA_LEN); } error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td); hdr18->pinfo = hdr->pinfo; hdr18->xpt_links = hdr->xpt_links; hdr18->sim_links = hdr->sim_links; hdr18->periph_links = hdr->periph_links; hdr18->retry_count = hdr->retry_count; hdr18->cbfcnp = hdr->cbfcnp; hdr18->func_code = hdr->func_code; hdr18->status = hdr->status; hdr18->path = hdr->path; hdr18->path_id = hdr->path_id; hdr18->target_id = hdr->target_id; hdr18->target_lun = hdr->target_lun; hdr18->ext_lun = hdr->target_lun; hdr18->flags = hdr->flags; hdr18->xflags = hdr->xflags | CAM_EXTLUN_VALID_0x18; hdr18->periph_priv = hdr->periph_priv; hdr18->sim_priv = hdr->sim_priv; hdr18->timeout = hdr->timeout; if (ccb->ccb_h.func_code == XPT_GET_TRAN_SETTINGS) { struct ccb_trans_settings *cts; struct ccb_trans_settings_0x18 *cts18; cts = &ccb->cts; cts18 = (struct ccb_trans_settings_0x18 *)hdr18; cts18->type = cts->type; cts18->protocol = cts->protocol; cts18->protocol_version = cts->protocol_version; cts18->transport = cts->transport; cts18->transport_version = cts->transport_version; bcopy(&cts->proto_specific, &cts18->proto_specific, sizeof(cts18->proto_specific)); bcopy(&cts->xport_specific, &cts18->xport_specific, sizeof(cts18->xport_specific)); } else if (ccb->ccb_h.func_code == XPT_DEV_MATCH) { bcopy(ccbb, ccbb18, CAM_0X18_DATA_LEN); cam_compat_translate_dev_match_0x18(ccb); } else { bcopy(ccbb, ccbb18, CAM_0X18_DATA_LEN); } xpt_free_ccb(ccb); return (error); }
static int cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td, d_ioctl_t *cbfnp) { union ccb *ccb; struct ccb_hdr *hdr; struct ccb_hdr_0x17 *hdr17; uint8_t *ccbb, *ccbb17; u_int error; hdr17 = (struct ccb_hdr_0x17 *)addr; ccb = xpt_alloc_ccb(); hdr = &ccb->ccb_h; hdr->pinfo = hdr17->pinfo; hdr->xpt_links = hdr17->xpt_links; hdr->sim_links = hdr17->sim_links; hdr->periph_links = hdr17->periph_links; hdr->retry_count = hdr17->retry_count; hdr->cbfcnp = hdr17->cbfcnp; hdr->func_code = hdr17->func_code; hdr->status = hdr17->status; hdr->path = hdr17->path; hdr->path_id = hdr17->path_id; hdr->target_id = hdr17->target_id; hdr->target_lun = hdr17->target_lun; hdr->flags = hdr17->flags; hdr->xflags = 0; hdr->periph_priv = hdr17->periph_priv; hdr->sim_priv = hdr17->sim_priv; hdr->timeout = hdr17->timeout; hdr->softtimeout.tv_sec = 0; hdr->softtimeout.tv_usec = 0; ccbb = (uint8_t *)&hdr[1]; ccbb17 = (uint8_t *)&hdr17[1]; if (ccb->ccb_h.func_code == XPT_SET_TRAN_SETTINGS) { struct ccb_trans_settings *cts; struct ccb_trans_settings_0x17 *cts17; cts = &ccb->cts; cts17 = (struct ccb_trans_settings_0x17 *)hdr17; cts->type = cts17->type; cts->protocol = cts17->protocol; cts->protocol_version = cts17->protocol_version; cts->transport = cts17->transport; cts->transport_version = cts17->transport_version; bcopy(&cts17->proto_specific, &cts->proto_specific, sizeof(cts17->proto_specific)); bcopy(&cts17->xport_specific, &cts->xport_specific, sizeof(cts17->xport_specific)); } else { bcopy(ccbb17, ccbb, CAM_0X17_DATA_LEN); } error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td); hdr17->pinfo = hdr->pinfo; hdr17->xpt_links = hdr->xpt_links; hdr17->sim_links = hdr->sim_links; hdr17->periph_links = hdr->periph_links; hdr17->retry_count = hdr->retry_count; hdr17->cbfcnp = hdr->cbfcnp; hdr17->func_code = hdr->func_code; hdr17->status = hdr->status; hdr17->path = hdr->path; hdr17->path_id = hdr->path_id; hdr17->target_id = hdr->target_id; hdr17->target_lun = hdr->target_lun; hdr17->flags = hdr->flags; hdr17->periph_priv = hdr->periph_priv; hdr17->sim_priv = hdr->sim_priv; hdr17->timeout = hdr->timeout; if (ccb->ccb_h.func_code == XPT_PATH_INQ) { struct ccb_pathinq *cpi; struct ccb_pathinq_0x17 *cpi17; /* The PATH_INQ only needs special handling on the way out */ cpi = &ccb->cpi; cpi17 = (struct ccb_pathinq_0x17 *)hdr17; cpi17->version_num = cpi->version_num; cpi17->hba_inquiry = cpi->hba_inquiry; cpi17->target_sprt = (u_int8_t)cpi->target_sprt; cpi17->hba_misc = (u_int8_t)cpi->hba_misc; cpi17->hba_eng_cnt = cpi->hba_eng_cnt; bcopy(&cpi->vuhba_flags[0], &cpi17->vuhba_flags[0], VUHBALEN); cpi17->max_target = cpi->max_target; cpi17->max_lun = cpi->max_lun; cpi17->async_flags = cpi->async_flags; cpi17->hpath_id = cpi->hpath_id; cpi17->initiator_id = cpi->initiator_id; bcopy(&cpi->sim_vid[0], &cpi17->sim_vid[0], SIM_IDLEN); bcopy(&cpi->hba_vid[0], &cpi17->hba_vid[0], HBA_IDLEN); bcopy(&cpi->dev_name[0], &cpi17->dev_name[0], DEV_IDLEN); cpi17->unit_number = cpi->unit_number; cpi17->bus_id = cpi->bus_id; cpi17->base_transfer_speed = cpi->base_transfer_speed; cpi17->protocol = cpi->protocol; cpi17->protocol_version = cpi->protocol_version; cpi17->transport = cpi->transport; cpi17->transport_version = cpi->transport_version; bcopy(&cpi->xport_specific, &cpi17->xport_specific, PATHINQ_SETTINGS_SIZE); cpi17->maxio = cpi->maxio; cpi17->hba_vendor = cpi->hba_vendor; cpi17->hba_device = cpi->hba_device; cpi17->hba_subvendor = cpi->hba_subvendor; cpi17->hba_subdevice = cpi->hba_subdevice; } else if (ccb->ccb_h.func_code == XPT_GET_TRAN_SETTINGS) { struct ccb_trans_settings *cts; struct ccb_trans_settings_0x17 *cts17; cts = &ccb->cts; cts17 = (struct ccb_trans_settings_0x17 *)hdr17; cts17->type = cts->type; cts17->protocol = cts->protocol; cts17->protocol_version = cts->protocol_version; cts17->transport = cts->transport; cts17->transport_version = cts->transport_version; bcopy(&cts->proto_specific, &cts17->proto_specific, sizeof(cts17->proto_specific)); bcopy(&cts->xport_specific, &cts17->xport_specific, sizeof(cts17->xport_specific)); } else if (ccb->ccb_h.func_code == XPT_DEV_MATCH) { /* Copy the rest of the header over */ bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN); cam_compat_translate_dev_match_0x18(ccb); } else { bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN); } xpt_free_ccb(ccb); return (error); }