PERFORCE change 49774 for review

Scott Long scottl at FreeBSD.org
Sat Mar 27 00:30:36 PST 2004


http://perforce.freebsd.org/chv.cgi?CH=49774

Change 49774 by scottl at scottl-junior-camlock on 2004/03/27 00:30:33

	Mechanical split of the lun probe and probe periph code into it's
	own file.  The XPT is still painfully SCSI-aware and will require
	a lot of work, but this is a first step.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/cam/cam_probe.c#1 add
.. //depot/projects/scottl-camlock/src/sys/cam/cam_probe.h#1 add
.. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#2 edit
.. //depot/projects/scottl-camlock/src/sys/modules/cam/Makefile#2 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#2 (text+ko) ====

@@ -55,28 +55,13 @@
 #include <cam/cam_xpt_sim.h>
 #include <cam/cam_xpt_periph.h>
 #include <cam/cam_debug.h>
+#include <cam/cam_probe.h>
 
 #include <cam/scsi/scsi_all.h>
 #include <cam/scsi/scsi_message.h>
 #include <cam/scsi/scsi_pass.h>
 #include "opt_cam.h"
 
-/* Datastructures internal to the xpt layer */
-
-/*
- * Definition of an async handler callback block.  These are used to add
- * SIMs and peripherals to the async callback lists.
- */
-struct async_node {
-	SLIST_ENTRY(async_node)	links;
-	u_int32_t	event_enable;	/* Async Event enables */
-	void		(*callback)(void *arg, u_int32_t code,
-				    struct cam_path *path, void *args);
-	void		*callback_arg;
-};
-
-SLIST_HEAD(async_list, async_node);
-SLIST_HEAD(periph_list, cam_periph);
 static STAILQ_HEAD(highpowerlist, ccb_hdr) highpowerq;
 
 /*
@@ -90,120 +75,6 @@
 /* number of high powered commands that can go through right now */
 static int num_highpower = CAM_MAX_HIGHPOWER;
 
-/*
- * Structure for queueing a device in a run queue.
- * There is one run queue for allocating new ccbs,
- * and another for sending ccbs to the controller.
- */
-struct cam_ed_qinfo {
-	cam_pinfo pinfo;
-	struct	  cam_ed *device;
-};
-
-/*
- * The CAM EDT (Existing Device Table) contains the device information for
- * all devices for all busses in the system.  The table contains a
- * cam_ed structure for each device on the bus.
- */
-struct cam_ed {
-	TAILQ_ENTRY(cam_ed) links;
-	struct	cam_ed_qinfo alloc_ccb_entry;
-	struct	cam_ed_qinfo send_ccb_entry;
-	struct	cam_et	 *target;
-	lun_id_t	 lun_id;
-	struct	camq drvq;		/*
-					 * Queue of type drivers wanting to do
-					 * work on this device.
-					 */
-	struct	cam_ccbq ccbq;		/* Queue of pending ccbs */
-	struct	async_list asyncs;	/* Async callback info for this B/T/L */
-	struct	periph_list periphs;	/* All attached devices */
-	u_int	generation;		/* Generation number */
-	struct	cam_periph *owner;	/* Peripheral driver's ownership tag */
-	struct	xpt_quirk_entry *quirk;	/* Oddities about this device */
-					/* Storage for the inquiry data */
-#ifdef CAM_NEW_TRAN_CODE
-	cam_proto	 protocol;
-	u_int		 protocol_version;
-	cam_xport	 transport;
-	u_int		 transport_version;
-#endif /* CAM_NEW_TRAN_CODE */
-	struct		 scsi_inquiry_data inq_data;
-	u_int8_t	 inq_flags;	/*
-					 * Current settings for inquiry flags.
-					 * This allows us to override settings
-					 * like disconnection and tagged
-					 * queuing for a device.
-					 */
-	u_int8_t	 queue_flags;	/* Queue flags from the control page */
-	u_int8_t	 serial_num_len;
-	u_int8_t	*serial_num;
-	u_int32_t	 qfrozen_cnt;
-	u_int32_t	 flags;
-#define CAM_DEV_UNCONFIGURED	 	0x01
-#define CAM_DEV_REL_TIMEOUT_PENDING	0x02
-#define CAM_DEV_REL_ON_COMPLETE		0x04
-#define CAM_DEV_REL_ON_QUEUE_EMPTY	0x08
-#define CAM_DEV_RESIZE_QUEUE_NEEDED	0x10
-#define CAM_DEV_TAG_AFTER_COUNT		0x20
-#define CAM_DEV_INQUIRY_DATA_VALID	0x40
-	u_int32_t	 tag_delay_count;
-#define	CAM_TAG_DELAY_COUNT		5
-	u_int32_t	 refcount;
-	struct		 callout_handle c_handle;
-};
-
-/*
- * Each target is represented by an ET (Existing Target).  These
- * entries are created when a target is successfully probed with an
- * identify, and removed when a device fails to respond after a number
- * of retries, or a bus rescan finds the device missing.
- */
-struct cam_et { 
-	TAILQ_HEAD(, cam_ed) ed_entries;
-	TAILQ_ENTRY(cam_et) links;
-	struct	cam_eb	*bus;	
-	target_id_t	target_id;
-	u_int32_t	refcount;	
-	u_int		generation;
-	struct		timeval last_reset;
-};
-
-/*
- * Each bus is represented by an EB (Existing Bus).  These entries
- * are created by calls to xpt_bus_register and deleted by calls to
- * xpt_bus_deregister.
- */
-struct cam_eb { 
-	TAILQ_HEAD(, cam_et) et_entries;
-	TAILQ_ENTRY(cam_eb)  links;
-	path_id_t	     path_id;
-	struct cam_sim	     *sim;
-	struct timeval	     last_reset;
-	u_int32_t	     flags;
-#define	CAM_EB_RUNQ_SCHEDULED	0x01
-	u_int32_t	     refcount;
-	u_int		     generation;
-};
-
-struct cam_path {
-	struct cam_periph *periph;
-	struct cam_eb	  *bus;
-	struct cam_et	  *target;
-	struct cam_ed	  *device;
-};
-
-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
-	u_int mintags;
-	u_int maxtags;
-};
-#define	CAM_SCSI2_MAXLUN	8
-
 typedef enum {
 	XPT_FLAG_OPEN		= 0x01
 } xpt_flags;
@@ -613,22 +484,13 @@
 
 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;
@@ -697,15 +559,6 @@
 DECLARE_MODULE(cam, cam_moduledata, SI_SUB_CONFIGURE, SI_ORDER_SECOND);
 MODULE_VERSION(cam, 1);
 
-
-static cam_status	xpt_compile_path(struct cam_path *new_path,
-					 struct cam_periph *perph,
-					 path_id_t path_id,
-					 target_id_t target_id,
-					 lun_id_t lun_id);
-
-static void		xpt_release_path(struct cam_path *path);
-
 static void		xpt_async_bcast(struct async_list *async_head,
 					u_int32_t async_code,
 					struct cam_path *path,
@@ -743,10 +596,6 @@
 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);
@@ -812,14 +661,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 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);
 #ifdef CAM_NEW_TRAN_CODE
 static void	 xpt_devise_transport(struct cam_path *path);
 #endif /* CAM_NEW_TRAN_CODE */
@@ -923,12 +764,6 @@
 }
 
 static void
-probe_periph_init()
-{
-}
-
-
-static void
 xptdone(struct cam_periph *periph, union ccb *done_ccb)
 {
 	/* Caller will release the CCB */
@@ -4012,7 +3847,7 @@
 	return (status);
 }
 
-static cam_status
+cam_status
 xpt_compile_path(struct cam_path *new_path, struct cam_periph *perph,
 		 path_id_t path_id, target_id_t target_id, lun_id_t lun_id)
 {
@@ -4086,7 +3921,7 @@
 	return (status);
 }
 
-static void
+void
 xpt_release_path(struct cam_path *path)
 {
 	CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_release_path\n"));
@@ -5379,682 +5214,7 @@
 	}
 }
 
-typedef enum {
-	PROBE_TUR,
-	PROBE_INQUIRY,
-	PROBE_FULL_INQUIRY,
-	PROBE_MODE_SENSE,
-	PROBE_SERIAL_NUM,
-	PROBE_TUR_FOR_NEGOTIATION
-} probe_action;
-
-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];
-} 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;
-	int s;
-	
-	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_TEMP, M_NOWAIT);
-		if (request_ccb == NULL) {
-			xpt_print_path(path);
-			printf("xpt_scan_lun: can't allocate CCB, can't "
-			       "continue\n");
-			return;
-		}
-		new_path = malloc(sizeof(*new_path), M_TEMP, M_NOWAIT);
-		if (new_path == NULL) {
-			xpt_print_path(path);
-			printf("xpt_scan_lun: can't allocate path, can't "
-			       "continue\n");
-			free(request_ccb, M_TEMP);
-			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(path);
-			printf("xpt_scan_lun: can't compile path, can't "
-			       "continue\n");
-			free(request_ccb, M_TEMP);
-			free(new_path, M_TEMP);
-			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;
-	}
-
-	s = splsoftcam();
-	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(path);
-			printf("xpt_scan_lun: cam_alloc_periph returned an "
-			       "error, can't continue probe\n");
-			request_ccb->ccb_h.status = status;
-			xpt_done(request_ccb);
-		}
-	}
-	splx(s);
-}
-
-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_TEMP);
-	free(done_ccb, M_TEMP);
-}
-
-static cam_status
-proberegister(struct cam_periph *periph, void *arg)
-{
-	union ccb *request_ccb;	/* CCB representing the probe request */
-	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_TEMP, 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;
-	cam_periph_acquire(periph);
-	/*
-	 * 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);
-	cpi.ccb_h.func_code = XPT_PATH_INQ;
-	xpt_action((union ccb *)&cpi);
-
-	/*
-	 * If a device has gone away and another device, or the same one,
-	 * is back in the same place, it should have a unit attention
-	 * condition pending.  It will not report the unit attention in
-	 * response to an inquiry, which may leave invalid transfer
-	 * negotiations in effect.  The TUR will reveal the unit attention
-	 * condition.  Only send the TUR for lun 0, since some devices 
-	 * will get confused by commands other than inquiry to non-existent
-	 * luns.  If you think a device has gone away start your scan from
-	 * lun 0.  This will insure that any bogus transfer settings are
-	 * invalidated.
-	 *
-	 * If we haven't seen the device before and the controller supports
-	 * some kind of transfer negotiation, negotiate with the first
-	 * sent command if no bus reset was performed at startup.  This
-	 * ensures that the device is not confused by transfer negotiation
-	 * settings left over by loader or BIOS action.
-	 */
-	if (((ccb->ccb_h.path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
-	 && (ccb->ccb_h.target_lun == 0)) {
-		softc->action = PROBE_TUR;
-	} else if ((cpi.hba_inquiry & (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE)) != 0
-	      && (cpi.hba_misc & PIM_NOBUSRESET) != 0) {
-		proberequestdefaultnegotiation(periph);
-		softc->action = PROBE_INQUIRY;
-	} else {
-		softc->action = PROBE_INQUIRY;
-	}
-
-	if (ccb->crcn.flags & CAM_EXPECT_INQ_CHANGE)
-		softc->flags |= PROBE_NO_ANNOUNCE;
-	else
-		softc->flags &= ~PROBE_NO_ANNOUNCE;
-
-	xpt_schedule(periph, ccb->ccb_h.pinfo.priority);
-}
-
-static void
-probestart(struct cam_periph *periph, union ccb *start_ccb)
-{
-	/* Probe the device that our peripheral driver points to */
-	struct ccb_scsiio *csio;
-	probe_softc *softc;
-
-	CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probestart\n"));
-
-	softc = (probe_softc *)periph->softc;
-	csio = &start_ccb->csio;
-
-	switch (softc->action) {
-	case PROBE_TUR:
-	case PROBE_TUR_FOR_NEGOTIATION:
-	{
-		scsi_test_unit_ready(csio,
-				     /*retries*/4,
-				     probedone,
-				     MSG_SIMPLE_Q_TAG,
-				     SSD_FULL_SIZE,
-				     /*timeout*/60000);
-		break;
-	}
-	case PROBE_INQUIRY:
-	case PROBE_FULL_INQUIRY:
-	{
-		u_int inquiry_len;
-		struct scsi_inquiry_data *inq_buf;
-
-		inq_buf = &periph->path->device->inq_data;
-		/*
-		 * If the device is currently configured, we calculate an
-		 * MD5 checksum of the inquiry data, and if the serial number
-		 * length is greater than 0, add the serial number data
-		 * into the checksum as well.  Once the inquiry and the
-		 * serial number check finish, we attempt to figure out
-		 * whether we still have the same device.
-		 */
-		if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
-			
-			MD5Init(&softc->context);
-			MD5Update(&softc->context, (unsigned char *)inq_buf,
-				  sizeof(struct scsi_inquiry_data));
-			softc->flags |= PROBE_INQUIRY_CKSUM;
-			if (periph->path->device->serial_num_len > 0) {
-				MD5Update(&softc->context,
-					  periph->path->device->serial_num,
-					  periph->path->device->serial_num_len);
-				softc->flags |= PROBE_SERIAL_CKSUM;
-			}
-			MD5Final(softc->digest, &softc->context);
-		} 
-
-		if (softc->action == PROBE_INQUIRY)
-			inquiry_len = SHORT_INQUIRY_LENGTH;
-		else
-			inquiry_len = inq_buf->additional_length + 4;
-	
-		scsi_inquiry(csio,
-			     /*retries*/4,
-			     probedone,
-			     MSG_SIMPLE_Q_TAG,
-			     (u_int8_t *)inq_buf,
-			     inquiry_len,
-			     /*evpd*/FALSE,
-			     /*page_code*/0,
-			     SSD_MIN_SIZE,
-			     /*timeout*/60 * 1000);
-		break;
-	}
-	case PROBE_MODE_SENSE:
-	{
-		void  *mode_buf;
-		int    mode_buf_len;
-
-		mode_buf_len = sizeof(struct scsi_mode_header_6)
-			     + sizeof(struct scsi_mode_blk_desc)
-			     + sizeof(struct scsi_control_page);
-		mode_buf = malloc(mode_buf_len, M_TEMP, M_NOWAIT);
-		if (mode_buf != NULL) {
-	                scsi_mode_sense(csio,
-					/*retries*/4,
-					probedone,
-					MSG_SIMPLE_Q_TAG,
-					/*dbd*/FALSE,
-					SMS_PAGE_CTRL_CURRENT,
-					SMS_CONTROL_MODE_PAGE,
-					mode_buf,
-					mode_buf_len,
-					SSD_FULL_SIZE,
-					/*timeout*/60000);
-			break;
-		}
-		xpt_print_path(periph->path);
-		printf("Unable to mode sense control page - malloc failure\n");
-		softc->action = PROBE_SERIAL_NUM;
-	}
-	/* FALLTHROUGH */
-	case PROBE_SERIAL_NUM:
-	{
-		struct scsi_vpd_unit_serial_number *serial_buf;
-		struct cam_ed* device;
-
-		serial_buf = NULL;
-		device = periph->path->device;
-		device->serial_num = NULL;
-		device->serial_num_len = 0;
-
-		if ((device->quirk->quirks & CAM_QUIRK_NOSERIAL) == 0)
-			serial_buf = (struct scsi_vpd_unit_serial_number *)
-				malloc(sizeof(*serial_buf), M_TEMP,
-					M_NOWAIT | M_ZERO);
-
-		if (serial_buf != NULL) {
-			scsi_inquiry(csio,
-				     /*retries*/4,
-				     probedone,
-				     MSG_SIMPLE_Q_TAG,
-				     (u_int8_t *)serial_buf,
-				     sizeof(*serial_buf),
-				     /*evpd*/TRUE,
-				     SVPD_UNIT_SERIAL_NUMBER,
-				     SSD_MIN_SIZE,
-				     /*timeout*/60 * 1000);
-			break;
-		}
-		/*
-		 * We'll have to do without, let our probedone
-		 * routine finish up for us.
-		 */
-		start_ccb->csio.data_ptr = NULL;
-		probedone(periph, start_ccb);
-		return;
-	}
-	}
-	xpt_action(start_ccb);
-}
-
-static void
-proberequestdefaultnegotiation(struct cam_periph *periph)
-{
-	struct ccb_trans_settings cts;
-
-	xpt_setup_ccb(&cts.ccb_h, periph->path, /*priority*/1);
-	cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
-#ifdef CAM_NEW_TRAN_CODE
-	cts.type = CTS_TYPE_USER_SETTINGS;
-#else /* CAM_NEW_TRAN_CODE */
-	cts.flags = CCB_TRANS_USER_SETTINGS;
-#endif /* CAM_NEW_TRAN_CODE */
-	xpt_action((union ccb *)&cts);
-	cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
-#ifdef CAM_NEW_TRAN_CODE
-	cts.type = CTS_TYPE_CURRENT_SETTINGS;
-#else /* CAM_NEW_TRAN_CODE */
-	cts.flags &= ~CCB_TRANS_USER_SETTINGS;
-	cts.flags |= CCB_TRANS_CURRENT_SETTINGS;
-#endif /* CAM_NEW_TRAN_CODE */
-	xpt_action((union ccb *)&cts);
-}
-
-static void
-probedone(struct cam_periph *periph, union ccb *done_ccb)
-{
-	probe_softc *softc;
-	struct cam_path *path;
-	u_int32_t  priority;
-
-	CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probedone\n"));
-
-	softc = (probe_softc *)periph->softc;
-	path = done_ccb->ccb_h.path;
-	priority = done_ccb->ccb_h.pinfo.priority;
-
-	switch (softc->action) {
-	case PROBE_TUR:
-	{
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
-
-			if (cam_periph_error(done_ccb, 0,
-					     SF_NO_PRINT, NULL) == ERESTART)
-				return;
-			else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
-				/* Don't wedge the queue */
-				xpt_release_devq(done_ccb->ccb_h.path,
-						 /*count*/1,
-						 /*run_queue*/TRUE);
-		}
-		softc->action = PROBE_INQUIRY;
-		xpt_release_ccb(done_ccb);
-		xpt_schedule(periph, priority);
-		return;
-	}
-	case PROBE_INQUIRY:
-	case PROBE_FULL_INQUIRY:
-	{
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			struct scsi_inquiry_data *inq_buf;
-			u_int8_t periph_qual;
-
-			path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
-			inq_buf = &path->device->inq_data;
-
-			periph_qual = SID_QUAL(inq_buf);
-			
-			switch(periph_qual) {
-			case SID_QUAL_LU_CONNECTED:
-			{
-				u_int8_t alen;
-
-				/*
-				 * We conservatively request only
-				 * SHORT_INQUIRY_LEN bytes of inquiry
-				 * information during our first try
-				 * at sending an INQUIRY. If the device
-				 * has more information to give,
-				 * perform a second request specifying
-				 * the amount of information the device
-				 * is willing to give.
-				 */
-				alen = inq_buf->additional_length;
-				if (softc->action == PROBE_INQUIRY
-				 && alen > (SHORT_INQUIRY_LENGTH - 4)) {
-					softc->action = PROBE_FULL_INQUIRY;
-					xpt_release_ccb(done_ccb);
-					xpt_schedule(periph, priority);
-					return;
-				}
-
-				xpt_find_quirk(path->device);
-
-#ifdef CAM_NEW_TRAN_CODE
-				xpt_devise_transport(path);
-#endif /* CAM_NEW_TRAN_CODE */
-				if ((inq_buf->flags & SID_CmdQue) != 0)
-					softc->action = PROBE_MODE_SENSE;
-				else
-					softc->action = PROBE_SERIAL_NUM;
-
-				path->device->flags &= ~CAM_DEV_UNCONFIGURED;
-
-				xpt_release_ccb(done_ccb);
-				xpt_schedule(periph, priority);
-				return;
-			}
-			default:
-				break;
-			}
-		} else if (cam_periph_error(done_ccb, 0,
-					    done_ccb->ccb_h.target_lun > 0
-					    ? SF_RETRY_UA|SF_QUIET_IR
-					    : SF_RETRY_UA,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
-					 /*run_queue*/TRUE);
-		}
-		/*
-		 * If we get to this point, we got an error status back
-		 * from the inquiry and the error status doesn't require
-		 * automatically retrying the command.  Therefore, the
-		 * inquiry failed.  If we had inquiry information before
-		 * for this device, but this latest inquiry command failed,
-		 * the device has probably gone away.  If this device isn't
-		 * already marked unconfigured, notify the peripheral
-		 * drivers that this device is no more.
-		 */
-		if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
-			/* Send the async notification. */
-			xpt_async(AC_LOST_DEVICE, path, NULL);
-
-		xpt_release_ccb(done_ccb);
-		break;
-	}
-	case PROBE_MODE_SENSE:
-	{
-		struct ccb_scsiio *csio;
-		struct scsi_mode_header_6 *mode_hdr;
-
-		csio = &done_ccb->csio;
-		mode_hdr = (struct scsi_mode_header_6 *)csio->data_ptr;
-		if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			struct scsi_control_page *page;
-			u_int8_t *offset;
-
-			offset = ((u_int8_t *)&mode_hdr[1])
-			    + mode_hdr->blk_desc_len;
-			page = (struct scsi_control_page *)offset;
-			path->device->queue_flags = page->queue_flags;
-		} else if (cam_periph_error(done_ccb, 0,
-					    SF_RETRY_UA|SF_NO_PRINT,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path,
-					 /*count*/1, /*run_queue*/TRUE);
-		}
-		xpt_release_ccb(done_ccb);
-		free(mode_hdr, M_TEMP);
-		softc->action = PROBE_SERIAL_NUM;
-		xpt_schedule(periph, priority);
-		return;
-	}
-	case PROBE_SERIAL_NUM:
-	{
-		struct ccb_scsiio *csio;
-		struct scsi_vpd_unit_serial_number *serial_buf;
-		u_int32_t  priority;
-		int changed;
-		int have_serialnum;
-
-		changed = 1;
-		have_serialnum = 0;
-		csio = &done_ccb->csio;
-		priority = done_ccb->ccb_h.pinfo.priority;
-		serial_buf =
-		    (struct scsi_vpd_unit_serial_number *)csio->data_ptr;
-
-		/* Clean up from previous instance of this device */
-		if (path->device->serial_num != NULL) {
-			free(path->device->serial_num, M_DEVBUF);
-			path->device->serial_num = NULL;
-			path->device->serial_num_len = 0;
-		}
-
-		if (serial_buf == NULL) {
-			/*
-			 * Don't process the command as it was never sent
-			 */
-		} else if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP
-			&& (serial_buf->length > 0)) {
-
-			have_serialnum = 1;
-			path->device->serial_num =
-				(u_int8_t *)malloc((serial_buf->length + 1),
-						   M_DEVBUF, M_NOWAIT);
-			if (path->device->serial_num != NULL) {
-				bcopy(serial_buf->serial_num,
-				      path->device->serial_num,
-				      serial_buf->length);
-				path->device->serial_num_len =
-				    serial_buf->length;
-				path->device->serial_num[serial_buf->length]
-				    = '\0';
-			}
-		} else if (cam_periph_error(done_ccb, 0,
-					    SF_RETRY_UA|SF_NO_PRINT,
-					    &softc->saved_ccb) == ERESTART) {
-			return;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
-					 /*run_queue*/TRUE);
-		}
-		
-		/*
-		 * Let's see if we have seen this device before.
-		 */
-		if ((softc->flags & PROBE_INQUIRY_CKSUM) != 0) {
-			MD5_CTX context;
-			u_int8_t digest[16];
-
-			MD5Init(&context);
-			
-			MD5Update(&context,
-				  (unsigned char *)&path->device->inq_data,
-				  sizeof(struct scsi_inquiry_data));
-
-			if (have_serialnum)
-				MD5Update(&context, serial_buf->serial_num,
-					  serial_buf->length);
-
-			MD5Final(digest, &context);
-			if (bcmp(softc->digest, digest, 16) == 0)
-				changed = 0;
-
-			/*
-			 * XXX Do we need to do a TUR in order to ensure
-			 *     that the device really hasn't changed???
-			 */
-			if ((changed != 0)
-			 && ((softc->flags & PROBE_NO_ANNOUNCE) == 0))
-				xpt_async(AC_LOST_DEVICE, path, NULL);
-		}
-		if (serial_buf != NULL)
-			free(serial_buf, M_TEMP);
-
-		if (changed != 0) {
-			/*
-			 * Now that we have all the necessary
-			 * information to safely perform transfer
-			 * negotiations... Controllers don't perform
-			 * any negotiation or tagged queuing until
-			 * after the first XPT_SET_TRAN_SETTINGS ccb is
-			 * received.  So, on a new device, just retreive
-			 * the user settings, and set them as the current
-			 * settings to set the device up.
-			 */
-			proberequestdefaultnegotiation(periph);
-			xpt_release_ccb(done_ccb);
-
-			/*
-			 * Perform a TUR to allow the controller to
-			 * perform any necessary transfer negotiation.
-			 */
-			softc->action = PROBE_TUR_FOR_NEGOTIATION;
-			xpt_schedule(periph, priority);
-			return;
-		}
-		xpt_release_ccb(done_ccb);
-		break;
-	}
-	case PROBE_TUR_FOR_NEGOTIATION:
-		if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
-					 /*run_queue*/TRUE);
-		}
-
-		path->device->flags &= ~CAM_DEV_UNCONFIGURED;
-
-		if ((softc->flags & PROBE_NO_ANNOUNCE) == 0) {
-			/* Inform the XPT that a new device has been found */
-			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
-			xpt_action(done_ccb);
-
-			xpt_async(AC_FOUND_DEVICE, xpt_periph->path, done_ccb);
-		}
-		xpt_release_ccb(done_ccb);
-		break;
-	}
-	done_ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
-	TAILQ_REMOVE(&softc->request_ccbs, &done_ccb->ccb_h, periph_links.tqe);
-	done_ccb->ccb_h.status = CAM_REQ_CMP;
-	xpt_done(done_ccb);
-	if (TAILQ_FIRST(&softc->request_ccbs) == NULL) {
-		cam_periph_invalidate(periph);
-		cam_periph_release(periph);
-	} else {
-		probeschedule(periph);
-	}
-}
-
-static void
-probecleanup(struct cam_periph *periph)
-{
-	free(periph->softc, M_TEMP);
-}
-
-static void
+void
 xpt_find_quirk(struct cam_ed *device)
 {
 	caddr_t	match;

==== //depot/projects/scottl-camlock/src/sys/modules/cam/Makefile#2 (text+ko) ====

@@ -19,6 +19,7 @@
 SRCS+=	device_if.h bus_if.h vnode_if.h
 SRCS+=	cam.c cam_periph.c cam_queue.c
 SRCS+=	cam_sim.c cam_xpt.c
+SRCS+=	scsi_probe.c
 SRCS+=	scsi_all.c scsi_cd.c scsi_ch.c
 SRCS+=	scsi_da.c
 SRCS+=	scsi_pass.c


More information about the p4-projects mailing list