Skip site navigation (1)Skip section navigation (2)
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>