Date: Sun, 5 Apr 2009 19:07:08 GMT From: Scott Long <scottl@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 160243 for review Message-ID: <200904051907.n35J78oQ004315@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=160243 Change 160243 by scottl@scottl-deimos on 2009/04/05 19:06:54 Start separating SCSI transport code out of cam_xpt.c and into scsi/scsi_xpt.c. Right now, this is mainly the probe periph and the bus and lun scan code. This does not yet compile. Affected files ... .. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#81 edit .. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.h#13 edit .. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_xpt.c#7 edit .. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_xpt.h#4 edit Differences ... ==== //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#81 (text+ko) ==== @@ -69,6 +69,14 @@ #include <machine/stdarg.h> /* for xpt_print below */ #include "opt_cam.h" +/* + * This is the maximum number of high powered commands (e.g. start unit) + * that can be outstanding at a particular time. + */ +#ifndef CAM_MAX_HIGHPOWER +#define CAM_MAX_HIGHPOWER 4 +#endif + /* Datastructures internal to the xpt layer */ MALLOC_DEFINE(M_CAMXPT, "CAM XPT", "CAM XPT buffers"); @@ -79,50 +87,6 @@ uintptr_t data2; }; -/* - * This is the maximum number of high powered commands (e.g. start unit) - * that can be outstanding at a particular time. - */ -#ifndef CAM_MAX_HIGHPOWER -#define CAM_MAX_HIGHPOWER 4 -#endif - -struct xpt_quirk_entry { - struct scsi_inquiry_pattern inq_pat; - u_int8_t quirks; -#define CAM_QUIRK_NOLUNS 0x01 -#define CAM_QUIRK_NOSERIAL 0x02 -#define CAM_QUIRK_HILUNS 0x04 -#define CAM_QUIRK_NOHILUNS 0x08 - u_int mintags; - u_int maxtags; -}; - -static int cam_srch_hi = 0; -TUNABLE_INT("kern.cam.cam_srch_hi", &cam_srch_hi); -static int sysctl_cam_search_luns(SYSCTL_HANDLER_ARGS); -SYSCTL_PROC(_kern_cam, OID_AUTO, cam_srch_hi, CTLTYPE_INT|CTLFLAG_RW, 0, 0, - sysctl_cam_search_luns, "I", - "allow search above LUN 7 for SCSI3 and greater devices"); - -#define CAM_SCSI2_MAXLUN 8 -/* - * If we're not quirked to search <= the first 8 luns - * and we are either quirked to search above lun 8, - * or we're > SCSI-2 and we've enabled hilun searching, - * or we're > SCSI-2 and the last lun was a success, - * we can look for luns above lun 8. - */ -#define CAN_SRCH_HI_SPARSE(dv) \ - (((dv->quirk->quirks & CAM_QUIRK_NOHILUNS) == 0) \ - && ((dv->quirk->quirks & CAM_QUIRK_HILUNS) \ - || (SID_ANSI_REV(&dv->inq_data) > SCSI_REV_2 && cam_srch_hi))) - -#define CAN_SRCH_HI_DENSE(dv) \ - (((dv->quirk->quirks & CAM_QUIRK_NOHILUNS) == 0) \ - && ((dv->quirk->quirks & CAM_QUIRK_HILUNS) \ - || (SID_ANSI_REV(&dv->inq_data) > SCSI_REV_2))) - typedef enum { XPT_FLAG_OPEN = 0x01 } xpt_flags; @@ -148,359 +112,6 @@ struct mtx xpt_lock; }; -static const char quantum[] = "QUANTUM"; -static const char sony[] = "SONY"; -static const char west_digital[] = "WDIGTL"; -static const char samsung[] = "SAMSUNG"; -static const char seagate[] = "SEAGATE"; -static const char microp[] = "MICROP"; - -static struct xpt_quirk_entry xpt_quirk_table[] = -{ - { - /* Reports QUEUE FULL for temporary resource shortages */ - { T_DIRECT, SIP_MEDIA_FIXED, quantum, "XP39100*", "*" }, - /*quirks*/0, /*mintags*/24, /*maxtags*/32 - }, - { - /* Reports QUEUE FULL for temporary resource shortages */ - { T_DIRECT, SIP_MEDIA_FIXED, quantum, "XP34550*", "*" }, - /*quirks*/0, /*mintags*/24, /*maxtags*/32 - }, - { - /* Reports QUEUE FULL for temporary resource shortages */ - { T_DIRECT, SIP_MEDIA_FIXED, quantum, "XP32275*", "*" }, - /*quirks*/0, /*mintags*/24, /*maxtags*/32 - }, - { - /* Broken tagged queuing drive */ - { T_DIRECT, SIP_MEDIA_FIXED, microp, "4421-07*", "*" }, - /*quirks*/0, /*mintags*/0, /*maxtags*/0 - }, - { - /* Broken tagged queuing drive */ - { T_DIRECT, SIP_MEDIA_FIXED, "HP", "C372*", "*" }, - /*quirks*/0, /*mintags*/0, /*maxtags*/0 - }, - { - /* Broken tagged queuing drive */ - { T_DIRECT, SIP_MEDIA_FIXED, microp, "3391*", "x43h" }, - /*quirks*/0, /*mintags*/0, /*maxtags*/0 - }, - { - /* - * Unfortunately, the Quantum Atlas III has the same - * problem as the Atlas II drives above. - * Reported by: "Johan Granlund" <johan@granlund.nu> - * - * For future reference, the drive with the problem was: - * QUANTUM QM39100TD-SW N1B0 - * - * It's possible that Quantum will fix the problem in later - * firmware revisions. If that happens, the quirk entry - * will need to be made specific to the firmware revisions - * with the problem. - * - */ - /* Reports QUEUE FULL for temporary resource shortages */ - { T_DIRECT, SIP_MEDIA_FIXED, quantum, "QM39100*", "*" }, - /*quirks*/0, /*mintags*/24, /*maxtags*/32 - }, - { - /* - * 18 Gig Atlas III, same problem as the 9G version. - * Reported by: Andre Albsmeier - * <andre.albsmeier@mchp.siemens.de> - * - * For future reference, the drive with the problem was: - * QUANTUM QM318000TD-S N491 - */ - /* Reports QUEUE FULL for temporary resource shortages */ - { T_DIRECT, SIP_MEDIA_FIXED, quantum, "QM318000*", "*" }, - /*quirks*/0, /*mintags*/24, /*maxtags*/32 - }, - { - /* - * Broken tagged queuing drive - * Reported by: Bret Ford <bford@uop.cs.uop.edu> - * and: Martin Renters <martin@tdc.on.ca> - */ - { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST410800*", "71*" }, - /*quirks*/0, /*mintags*/0, /*maxtags*/0 - }, - /* - * The Seagate Medalist Pro drives have very poor write - * performance with anything more than 2 tags. - * - * Reported by: Paul van der Zwan <paulz@trantor.xs4all.nl> - * Drive: <SEAGATE ST36530N 1444> - * - * Reported by: Jeremy Lea <reg@shale.csir.co.za> - * Drive: <SEAGATE ST34520W 1281> - * - * No one has actually reported that the 9G version - * (ST39140*) of the Medalist Pro has the same problem, but - * we're assuming that it does because the 4G and 6.5G - * versions of the drive are broken. - */ - { - { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST34520*", "*"}, - /*quirks*/0, /*mintags*/2, /*maxtags*/2 - }, - { - { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST36530*", "*"}, - /*quirks*/0, /*mintags*/2, /*maxtags*/2 - }, - { - { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST39140*", "*"}, - /*quirks*/0, /*mintags*/2, /*maxtags*/2 - }, - { - /* - * Slow when tagged queueing is enabled. Write performance - * steadily drops off with more and more concurrent - * transactions. Best sequential write performance with - * tagged queueing turned off and write caching turned on. - * - * PR: kern/10398 - * Submitted by: Hideaki Okada <hokada@isl.melco.co.jp> - * Drive: DCAS-34330 w/ "S65A" firmware. - * - * The drive with the problem had the "S65A" firmware - * revision, and has also been reported (by Stephen J. - * Roznowski <sjr@home.net>) for a drive with the "S61A" - * firmware revision. - * - * Although no one has reported problems with the 2 gig - * version of the DCAS drive, the assumption is that it - * has the same problems as the 4 gig version. Therefore - * this quirk entries disables tagged queueing for all - * DCAS drives. - */ - { T_DIRECT, SIP_MEDIA_FIXED, "IBM", "DCAS*", "*" }, - /*quirks*/0, /*mintags*/0, /*maxtags*/0 - }, - { - /* Broken tagged queuing drive */ - { T_DIRECT, SIP_MEDIA_REMOVABLE, "iomega", "jaz*", "*" }, - /*quirks*/0, /*mintags*/0, /*maxtags*/0 - }, - { - /* Broken tagged queuing drive */ - { T_DIRECT, SIP_MEDIA_FIXED, "CONNER", "CFP2107*", "*" }, - /*quirks*/0, /*mintags*/0, /*maxtags*/0 - }, - { - /* This does not support other than LUN 0 */ - { T_DIRECT, SIP_MEDIA_FIXED, "VMware*", "*", "*" }, - CAM_QUIRK_NOLUNS, /*mintags*/2, /*maxtags*/255 - }, - { - /* - * Broken tagged queuing drive. - * Submitted by: - * NAKAJI Hiroyuki <nakaji@zeisei.dpri.kyoto-u.ac.jp> - * in PR kern/9535 - */ - { T_DIRECT, SIP_MEDIA_FIXED, samsung, "WN34324U*", "*" }, - /*quirks*/0, /*mintags*/0, /*maxtags*/0 - }, - { - /* - * Slow when tagged queueing is enabled. (1.5MB/sec versus - * 8MB/sec.) - * Submitted by: Andrew Gallatin <gallatin@cs.duke.edu> - * Best performance with these drives is achieved with - * tagged queueing turned off, and write caching turned on. - */ - { T_DIRECT, SIP_MEDIA_FIXED, west_digital, "WDE*", "*" }, - /*quirks*/0, /*mintags*/0, /*maxtags*/0 - }, - { - /* - * Slow when tagged queueing is enabled. (1.5MB/sec versus - * 8MB/sec.) - * Submitted by: Andrew Gallatin <gallatin@cs.duke.edu> - * Best performance with these drives is achieved with - * tagged queueing turned off, and write caching turned on. - */ - { T_DIRECT, SIP_MEDIA_FIXED, west_digital, "ENTERPRISE", "*" }, - /*quirks*/0, /*mintags*/0, /*maxtags*/0 - }, - { - /* - * Doesn't handle queue full condition correctly, - * so we need to limit maxtags to what the device - * can handle instead of determining this automatically. - */ - { T_DIRECT, SIP_MEDIA_FIXED, samsung, "WN321010S*", "*" }, - /*quirks*/0, /*mintags*/2, /*maxtags*/32 - }, - { - /* Really only one LUN */ - { T_ENCLOSURE, SIP_MEDIA_FIXED, "SUN", "SENA", "*" }, - CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0 - }, - { - /* I can't believe we need a quirk for DPT volumes. */ - { T_ANY, SIP_MEDIA_FIXED|SIP_MEDIA_REMOVABLE, "DPT", "*", "*" }, - CAM_QUIRK_NOLUNS, - /*mintags*/0, /*maxtags*/255 - }, - { - /* - * Many Sony CDROM drives don't like multi-LUN probing. - */ - { T_CDROM, SIP_MEDIA_REMOVABLE, sony, "CD-ROM CDU*", "*" }, - CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0 - }, - { - /* - * This drive doesn't like multiple LUN probing. - * Submitted by: Parag Patel <parag@cgt.com> - */ - { T_WORM, SIP_MEDIA_REMOVABLE, sony, "CD-R CDU9*", "*" }, - CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0 - }, - { - { T_WORM, SIP_MEDIA_REMOVABLE, "YAMAHA", "CDR100*", "*" }, - CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0 - }, - { - /* - * The 8200 doesn't like multi-lun probing, and probably - * don't like serial number requests either. - */ - { - T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "EXABYTE", - "EXB-8200*", "*" - }, - CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0 - }, - { - /* - * Let's try the same as above, but for a drive that says - * it's an IPL-6860 but is actually an EXB 8200. - */ - { - T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "EXABYTE", - "IPL-6860*", "*" - }, - CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0 - }, - { - /* - * These Hitachi drives don't like multi-lun probing. - * The PR submitter has a DK319H, but says that the Linux - * kernel has a similar work-around for the DK312 and DK314, - * so all DK31* drives are quirked here. - * PR: misc/18793 - * Submitted by: Paul Haddad <paul@pth.com> - */ - { T_DIRECT, SIP_MEDIA_FIXED, "HITACHI", "DK31*", "*" }, - CAM_QUIRK_NOLUNS, /*mintags*/2, /*maxtags*/255 - }, - { - /* - * The Hitachi CJ series with J8A8 firmware apparantly has - * problems with tagged commands. - * PR: 23536 - * Reported by: amagai@nue.org - */ - { T_DIRECT, SIP_MEDIA_FIXED, "HITACHI", "DK32CJ*", "J8A8" }, - CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0 - }, - { - /* - * These are the large storage arrays. - * Submitted by: William Carrel <william.carrel@infospace.com> - */ - { T_DIRECT, SIP_MEDIA_FIXED, "HITACHI", "OPEN*", "*" }, - CAM_QUIRK_HILUNS, 2, 1024 - }, - { - /* - * This old revision of the TDC3600 is also SCSI-1, and - * hangs upon serial number probing. - */ - { - T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG", - " TDC 3600", "U07:" - }, - CAM_QUIRK_NOSERIAL, /*mintags*/0, /*maxtags*/0 - }, - { - /* - * Would repond to all LUNs if asked for. - */ - { - T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "CALIPER", - "CP150", "*" - }, - CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0 - }, - { - /* - * Would repond to all LUNs if asked for. - */ - { - T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "KENNEDY", - "96X2*", "*" - }, - CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0 - }, - { - /* Submitted by: Matthew Dodd <winter@jurai.net> */ - { T_PROCESSOR, SIP_MEDIA_FIXED, "Cabletrn", "EA41*", "*" }, - CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0 - }, - { - /* Submitted by: Matthew Dodd <winter@jurai.net> */ - { T_PROCESSOR, SIP_MEDIA_FIXED, "CABLETRN", "EA41*", "*" }, - CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0 - }, - { - /* TeraSolutions special settings for TRC-22 RAID */ - { T_DIRECT, SIP_MEDIA_FIXED, "TERASOLU", "TRC-22", "*" }, - /*quirks*/0, /*mintags*/55, /*maxtags*/255 - }, - { - /* Veritas Storage Appliance */ - { T_DIRECT, SIP_MEDIA_FIXED, "VERITAS", "*", "*" }, - CAM_QUIRK_HILUNS, /*mintags*/2, /*maxtags*/1024 - }, - { - /* - * Would respond to all LUNs. Device type and removable - * flag are jumper-selectable. - */ - { T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED, "MaxOptix", - "Tahiti 1", "*" - }, - CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0 - }, - { - /* EasyRAID E5A aka. areca ARC-6010 */ - { T_DIRECT, SIP_MEDIA_FIXED, "easyRAID", "*", "*" }, - CAM_QUIRK_NOHILUNS, /*mintags*/2, /*maxtags*/255 - }, - { - { T_ENCLOSURE, SIP_MEDIA_FIXED, "DP", "BACKPLANE", "*" }, - CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0 - }, - { - /* Default tagged queuing parameters for all devices */ - { - T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED, - /*vendor*/"*", /*product*/"*", /*revision*/"*" - }, - /*quirks*/0, /*mintags*/2, /*maxtags*/255 - }, -}; - -static const int xpt_quirk_table_size = - sizeof(xpt_quirk_table) / sizeof(*xpt_quirk_table); - typedef enum { DM_RET_COPY = 0x01, DM_RET_FLAG_MASK = 0x0f, @@ -546,24 +157,14 @@ static periph_init_t xpt_periph_init; -static periph_init_t probe_periph_init; - static struct periph_driver xpt_driver = { xpt_periph_init, "xpt", TAILQ_HEAD_INITIALIZER(xpt_driver.units) }; -static struct periph_driver probe_driver = -{ - probe_periph_init, "probe", - TAILQ_HEAD_INITIALIZER(probe_driver.units) -}; - PERIPHDRIVER_DECLARE(xpt, xpt_driver); -PERIPHDRIVER_DECLARE(probe, probe_driver); - static d_open_t xptopen; static d_close_t xptclose; static d_ioctl_t xptioctl; @@ -635,11 +236,6 @@ xpt_find_target(struct cam_eb *bus, target_id_t target_id); static struct cam_ed* xpt_find_device(struct cam_et *target, lun_id_t lun_id); -static void xpt_scan_bus(struct cam_periph *periph, union ccb *ccb); -static void xpt_scan_lun(struct cam_periph *periph, - struct cam_path *path, cam_flags flags, - union ccb *ccb); -static void xptscandone(struct cam_periph *periph, union ccb *done_ccb); static xpt_busfunc_t xptconfigbuscountfunc; static xpt_busfunc_t xptconfigfunc; static void xpt_config(void *arg); @@ -693,16 +289,6 @@ static xpt_busfunc_t xptsetasyncbusfunc; static cam_status xptregister(struct cam_periph *periph, void *arg); -static cam_status proberegister(struct cam_periph *periph, - void *arg); -static void probeschedule(struct cam_periph *probe_periph); -static void probestart(struct cam_periph *periph, union ccb *start_ccb); -static void proberequestdefaultnegotiation(struct cam_periph *periph); -static int proberequestbackoff(struct cam_periph *periph, - struct cam_ed *device); -static void probedone(struct cam_periph *periph, union ccb *done_ccb); -static void probecleanup(struct cam_periph *periph); -static void xpt_find_quirk(struct cam_ed *device); static void xpt_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device, int async_update); @@ -803,12 +389,6 @@ } static void -probe_periph_init() -{ -} - - -static void xptdone(struct cam_periph *periph, union ccb *done_ccb) { /* Caller will release the CCB */ @@ -4984,1315 +4564,6 @@ return (device); } -typedef struct { - union ccb *request_ccb; - struct ccb_pathinq *cpi; - int counter; -} xpt_scan_bus_info; - -/* - * To start a scan, request_ccb is an XPT_SCAN_BUS ccb. - * As the scan progresses, xpt_scan_bus is used as the - * callback on completion function. - */ -static void -xpt_scan_bus(struct cam_periph *periph, union ccb *request_ccb) -{ - CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE, - ("xpt_scan_bus\n")); - switch (request_ccb->ccb_h.func_code) { - case XPT_SCAN_BUS: - { - xpt_scan_bus_info *scan_info; - union ccb *work_ccb; - struct cam_path *path; - u_int i; - u_int max_target; - u_int initiator_id; - - /* Find out the characteristics of the bus */ - work_ccb = xpt_alloc_ccb_nowait(); - if (work_ccb == NULL) { - request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; - xpt_done(request_ccb); - return; - } - xpt_setup_ccb(&work_ccb->ccb_h, request_ccb->ccb_h.path, - request_ccb->ccb_h.pinfo.priority); - work_ccb->ccb_h.func_code = XPT_PATH_INQ; - xpt_action(work_ccb); - if (work_ccb->ccb_h.status != CAM_REQ_CMP) { - request_ccb->ccb_h.status = work_ccb->ccb_h.status; - xpt_free_ccb(work_ccb); - xpt_done(request_ccb); - return; - } - - if ((work_ccb->cpi.hba_misc & PIM_NOINITIATOR) != 0) { - /* - * Can't scan the bus on an adapter that - * cannot perform the initiator role. - */ - request_ccb->ccb_h.status = CAM_REQ_CMP; - xpt_free_ccb(work_ccb); - xpt_done(request_ccb); - return; - } - - /* Save some state for use while we probe for devices */ - scan_info = (xpt_scan_bus_info *) - malloc(sizeof(xpt_scan_bus_info), M_CAMXPT, M_NOWAIT); - if (scan_info == NULL) { - request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; - xpt_done(request_ccb); - return; - } - scan_info->request_ccb = request_ccb; - scan_info->cpi = &work_ccb->cpi; - - /* Cache on our stack so we can work asynchronously */ - max_target = scan_info->cpi->max_target; - initiator_id = scan_info->cpi->initiator_id; - - - /* - * We can scan all targets in parallel, or do it sequentially. - */ - if (scan_info->cpi->hba_misc & PIM_SEQSCAN) { - max_target = 0; - scan_info->counter = 0; - } else { - scan_info->counter = scan_info->cpi->max_target + 1; - if (scan_info->cpi->initiator_id < scan_info->counter) { - scan_info->counter--; - } - } - - for (i = 0; i <= max_target; i++) { - cam_status status; - if (i == initiator_id) - continue; - - status = xpt_create_path(&path, xpt_periph, - request_ccb->ccb_h.path_id, - i, 0); - if (status != CAM_REQ_CMP) { - printf("xpt_scan_bus: xpt_create_path failed" - " with status %#x, bus scan halted\n", - status); - free(scan_info, M_CAMXPT); - request_ccb->ccb_h.status = status; - xpt_free_ccb(work_ccb); - xpt_done(request_ccb); - break; - } - work_ccb = xpt_alloc_ccb_nowait(); - if (work_ccb == NULL) { - free(scan_info, M_CAMXPT); - xpt_free_path(path); - request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; - xpt_done(request_ccb); - break; - } - xpt_setup_ccb(&work_ccb->ccb_h, path, - request_ccb->ccb_h.pinfo.priority); - work_ccb->ccb_h.func_code = XPT_SCAN_LUN; - work_ccb->ccb_h.cbfcnp = xpt_scan_bus; - work_ccb->ccb_h.ppriv_ptr0 = scan_info; - work_ccb->crcn.flags = request_ccb->crcn.flags; - xpt_action(work_ccb); - } - break; - } - case XPT_SCAN_LUN: - { - cam_status status; - struct cam_path *path; - xpt_scan_bus_info *scan_info; - path_id_t path_id; - target_id_t target_id; - lun_id_t lun_id; - - /* Reuse the same CCB to query if a device was really found */ - scan_info = (xpt_scan_bus_info *)request_ccb->ccb_h.ppriv_ptr0; - xpt_setup_ccb(&request_ccb->ccb_h, request_ccb->ccb_h.path, - request_ccb->ccb_h.pinfo.priority); - request_ccb->ccb_h.func_code = XPT_GDEV_TYPE; - - path_id = request_ccb->ccb_h.path_id; - target_id = request_ccb->ccb_h.target_id; - lun_id = request_ccb->ccb_h.target_lun; - xpt_action(request_ccb); - - if (request_ccb->ccb_h.status != CAM_REQ_CMP) { - struct cam_ed *device; - struct cam_et *target; - int phl; - - /* - * If we already probed lun 0 successfully, or - * we have additional configured luns on this - * target that might have "gone away", go onto - * the next lun. - */ - target = request_ccb->ccb_h.path->target; - /* - * We may touch devices that we don't - * hold references too, so ensure they - * don't disappear out from under us. - * The target above is referenced by the - * path in the request ccb. - */ - phl = 0; - device = TAILQ_FIRST(&target->ed_entries); - if (device != NULL) { - phl = CAN_SRCH_HI_SPARSE(device); - if (device->lun_id == 0) - device = TAILQ_NEXT(device, links); - } - if ((lun_id != 0) || (device != NULL)) { - if (lun_id < (CAM_SCSI2_MAXLUN-1) || phl) - lun_id++; - } - } else { - struct cam_ed *device; - - device = request_ccb->ccb_h.path->device; - - if ((device->quirk->quirks & CAM_QUIRK_NOLUNS) == 0) { - /* Try the next lun */ - if (lun_id < (CAM_SCSI2_MAXLUN-1) - || CAN_SRCH_HI_DENSE(device)) - lun_id++; - } - } - - /* - * Free the current request path- we're done with it. - */ - xpt_free_path(request_ccb->ccb_h.path); - - /* - * Check to see if we scan any further luns. - */ - if (lun_id == request_ccb->ccb_h.target_lun - || lun_id > scan_info->cpi->max_lun) { - int done; - - hop_again: - done = 0; - if (scan_info->cpi->hba_misc & PIM_SEQSCAN) { - scan_info->counter++; - if (scan_info->counter == - scan_info->cpi->initiator_id) { - scan_info->counter++; - } - if (scan_info->counter >= - scan_info->cpi->max_target+1) { - done = 1; - } - } else { - scan_info->counter--; - if (scan_info->counter == 0) { - done = 1; - } - } - if (done) { - xpt_free_ccb(request_ccb); - xpt_free_ccb((union ccb *)scan_info->cpi); - request_ccb = scan_info->request_ccb; - free(scan_info, M_CAMXPT); - request_ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(request_ccb); - break; - } - - if ((scan_info->cpi->hba_misc & PIM_SEQSCAN) == 0) { - break; - } - status = xpt_create_path(&path, xpt_periph, - scan_info->request_ccb->ccb_h.path_id, - scan_info->counter, 0); - if (status != CAM_REQ_CMP) { - printf("xpt_scan_bus: xpt_create_path failed" - " with status %#x, bus scan halted\n", - status); - xpt_free_ccb(request_ccb); - xpt_free_ccb((union ccb *)scan_info->cpi); - request_ccb = scan_info->request_ccb; - free(scan_info, M_CAMXPT); - request_ccb->ccb_h.status = status; - xpt_done(request_ccb); - break; - } - xpt_setup_ccb(&request_ccb->ccb_h, path, - request_ccb->ccb_h.pinfo.priority); - request_ccb->ccb_h.func_code = XPT_SCAN_LUN; - request_ccb->ccb_h.cbfcnp = xpt_scan_bus; - request_ccb->ccb_h.ppriv_ptr0 = scan_info; - request_ccb->crcn.flags = - scan_info->request_ccb->crcn.flags; - } else { - status = xpt_create_path(&path, xpt_periph, - path_id, target_id, lun_id); - if (status != CAM_REQ_CMP) { - printf("xpt_scan_bus: xpt_create_path failed " - "with status %#x, halting LUN scan\n", - status); - goto hop_again; - } - xpt_setup_ccb(&request_ccb->ccb_h, path, - request_ccb->ccb_h.pinfo.priority); - request_ccb->ccb_h.func_code = XPT_SCAN_LUN; - request_ccb->ccb_h.cbfcnp = xpt_scan_bus; - request_ccb->ccb_h.ppriv_ptr0 = scan_info; - request_ccb->crcn.flags = - scan_info->request_ccb->crcn.flags; - } - xpt_action(request_ccb); - break; - } - default: - break; - } -} - -typedef enum { - PROBE_TUR, - PROBE_INQUIRY, /* this counts as DV0 for Basic Domain Validation */ - PROBE_FULL_INQUIRY, - PROBE_MODE_SENSE, - PROBE_SERIAL_NUM_0, - PROBE_SERIAL_NUM_1, - PROBE_TUR_FOR_NEGOTIATION, - PROBE_INQUIRY_BASIC_DV1, - PROBE_INQUIRY_BASIC_DV2, - PROBE_DV_EXIT, - PROBE_INVALID -} probe_action; - -static char *probe_action_text[] = { - "PROBE_TUR", - "PROBE_INQUIRY", - "PROBE_FULL_INQUIRY", - "PROBE_MODE_SENSE", - "PROBE_SERIAL_NUM_0", - "PROBE_SERIAL_NUM_1", - "PROBE_TUR_FOR_NEGOTIATION", - "PROBE_INQUIRY_BASIC_DV1", - "PROBE_INQUIRY_BASIC_DV2", - "PROBE_DV_EXIT", - "PROBE_INVALID" -}; - -#define PROBE_SET_ACTION(softc, newaction) \ -do { \ - char **text; \ - text = probe_action_text; \ - CAM_DEBUG((softc)->periph->path, CAM_DEBUG_INFO, \ - ("Probe %s to %s\n", text[(softc)->action], \ - text[(newaction)])); \ - (softc)->action = (newaction); \ -} while(0) - -typedef enum { - PROBE_INQUIRY_CKSUM = 0x01, - PROBE_SERIAL_CKSUM = 0x02, - PROBE_NO_ANNOUNCE = 0x04 -} probe_flags; - -typedef struct { - TAILQ_HEAD(, ccb_hdr) request_ccbs; - probe_action action; - union ccb saved_ccb; - probe_flags flags; - MD5_CTX context; - u_int8_t digest[16]; - struct cam_periph *periph; -} probe_softc; - -static void -xpt_scan_lun(struct cam_periph *periph, struct cam_path *path, - cam_flags flags, union ccb *request_ccb) -{ - struct ccb_pathinq cpi; - cam_status status; - struct cam_path *new_path; - struct cam_periph *old_periph; - - CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE, - ("xpt_scan_lun\n")); - - xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1); - cpi.ccb_h.func_code = XPT_PATH_INQ; - xpt_action((union ccb *)&cpi); - - if (cpi.ccb_h.status != CAM_REQ_CMP) { - if (request_ccb != NULL) { - request_ccb->ccb_h.status = cpi.ccb_h.status; - xpt_done(request_ccb); - } - return; - } - - if ((cpi.hba_misc & PIM_NOINITIATOR) != 0) { - /* - * Can't scan the bus on an adapter that - * cannot perform the initiator role. - */ - if (request_ccb != NULL) { - request_ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(request_ccb); - } - return; - } - - if (request_ccb == NULL) { - request_ccb = malloc(sizeof(union ccb), M_CAMXPT, M_NOWAIT); - if (request_ccb == NULL) { - xpt_print(path, "xpt_scan_lun: can't allocate CCB, " - "can't continue\n"); - return; - } - new_path = malloc(sizeof(*new_path), M_CAMXPT, M_NOWAIT); - if (new_path == NULL) { - xpt_print(path, "xpt_scan_lun: can't allocate path, " - "can't continue\n"); - free(request_ccb, M_CAMXPT); - return; - } - status = xpt_compile_path(new_path, xpt_periph, - path->bus->path_id, - path->target->target_id, - path->device->lun_id); - - if (status != CAM_REQ_CMP) { - xpt_print(path, "xpt_scan_lun: can't compile path, " - "can't continue\n"); - free(request_ccb, M_CAMXPT); - free(new_path, M_CAMXPT); - return; - } - xpt_setup_ccb(&request_ccb->ccb_h, new_path, /*priority*/ 1); - request_ccb->ccb_h.cbfcnp = xptscandone; - request_ccb->ccb_h.func_code = XPT_SCAN_LUN; - request_ccb->crcn.flags = flags; - } - - if ((old_periph = cam_periph_find(path, "probe")) != NULL) { - probe_softc *softc; - - softc = (probe_softc *)old_periph->softc; - TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h, - periph_links.tqe); - } else { - status = cam_periph_alloc(proberegister, NULL, probecleanup, - probestart, "probe", - CAM_PERIPH_BIO, - request_ccb->ccb_h.path, NULL, 0, - request_ccb); - - if (status != CAM_REQ_CMP) { - xpt_print(path, "xpt_scan_lun: cam_alloc_periph " - "returned an error, can't continue probe\n"); - request_ccb->ccb_h.status = status; - xpt_done(request_ccb); - } - } -} - -static void -xptscandone(struct cam_periph *periph, union ccb *done_ccb) -{ - xpt_release_path(done_ccb->ccb_h.path); - free(done_ccb->ccb_h.path, M_CAMXPT); - free(done_ccb, M_CAMXPT); -} - -static cam_status -proberegister(struct cam_periph *periph, void *arg) -{ - union ccb *request_ccb; /* CCB representing the probe request */ - cam_status status; - probe_softc *softc; - - request_ccb = (union ccb *)arg; - if (periph == NULL) { - printf("proberegister: periph was NULL!!\n"); - return(CAM_REQ_CMP_ERR); - } - - if (request_ccb == NULL) { - printf("proberegister: no probe CCB, " - "can't register device\n"); - return(CAM_REQ_CMP_ERR); - } - - softc = (probe_softc *)malloc(sizeof(*softc), M_CAMXPT, M_NOWAIT); - - if (softc == NULL) { - printf("proberegister: Unable to probe new device. " - "Unable to allocate softc\n"); - return(CAM_REQ_CMP_ERR); - } - TAILQ_INIT(&softc->request_ccbs); - TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h, - periph_links.tqe); - softc->flags = 0; - periph->softc = softc; - softc->periph = periph; - softc->action = PROBE_INVALID; - status = cam_periph_acquire(periph); - if (status != CAM_REQ_CMP) { - return (status); - } - - - /* - * Ensure we've waited at least a bus settle - * delay before attempting to probe the device. - * For HBAs that don't do bus resets, this won't make a difference. - */ - cam_periph_freeze_after_event(periph, &periph->path->bus->last_reset, - scsi_delay); - probeschedule(periph); - return(CAM_REQ_CMP); -} - -static void -probeschedule(struct cam_periph *periph) -{ - struct ccb_pathinq cpi; - union ccb *ccb; - probe_softc *softc; - - softc = (probe_softc *)periph->softc; - ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs); - - xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1); >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200904051907.n35J78oQ004315>