Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 2 Nov 2006 04:45:45 GMT
From:      Matt Jacob <mjacob@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 109009 for review
Message-ID:  <200611020445.kA24jjLV046073@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=109009

Change 109009 by mjacob@newisp on 2006/11/02 04:45:21

	Beginning stub of basic domain validation.

Affected files ...

.. //depot/projects/newisp/cam/cam_ccb.h#3 edit
.. //depot/projects/newisp/cam/cam_xpt.c#5 edit
.. //depot/projects/newisp/cam/scsi/scsi_all.h#2 edit

Differences ...

==== //depot/projects/newisp/cam/cam_ccb.h#3 (text+ko) ====


==== //depot/projects/newisp/cam/cam_xpt.c#5 (text+ko) ====

@@ -871,6 +871,7 @@
 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);
 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);
@@ -5457,11 +5458,14 @@
 
 typedef enum {
 	PROBE_TUR,
-	PROBE_INQUIRY,
+	PROBE_INQUIRY,	/* this counts as DV0 for Basic Domain Validation */
 	PROBE_FULL_INQUIRY,
 	PROBE_MODE_SENSE,
 	PROBE_SERIAL_NUM,
-	PROBE_TUR_FOR_NEGOTIATION
+	PROBE_TUR_FOR_NEGOTIATION,
+	PROBE_INQUIRY_BASIC_DV1,
+	PROBE_INQUIRY_BASIC_DV2,
+	PROBE_DV_EXIT
 } probe_action;
 
 typedef enum {
@@ -5692,6 +5696,7 @@
 	switch (softc->action) {
 	case PROBE_TUR:
 	case PROBE_TUR_FOR_NEGOTIATION:
+	case PROBE_DV_EXIT:
 	{
 		scsi_test_unit_ready(csio,
 				     /*retries*/4,
@@ -5703,11 +5708,14 @@
 	}
 	case PROBE_INQUIRY:
 	case PROBE_FULL_INQUIRY:
+	case PROBE_INQUIRY_BASIC_DV1:
+	case PROBE_INQUIRY_BASIC_DV2:
 	{
 		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
@@ -5734,9 +5742,7 @@
 		if (softc->action == PROBE_INQUIRY)
 			inquiry_len = SHORT_INQUIRY_LENGTH;
 		else
-			inquiry_len = inq_buf->additional_length
-				    + offsetof(struct scsi_inquiry_data,
-                                               additional_length) + 1;
+			inquiry_len = SID_ADDITIONAL_LENGTH(inq_buf);
 
 		/*
 		 * Some parallel SCSI devices fail to send an
@@ -5746,6 +5752,22 @@
 		 */
 		inquiry_len = roundup2(inquiry_len, 2);
 	
+		if (softc->action == PROBE_INQUIRY_BASIC_DV1
+		 || softc->action == PROBE_INQUIRY_BASIC_DV2) {
+			inq_buf = malloc(inquiry_len, M_TEMP, M_NOWAIT);
+		}
+		if (inq_buf == NULL) {
+			xpt_print_path(periph->path);
+			printf("malloc failure- skipping Domain Validation\n");
+			softc->action = PROBE_DV_EXIT;
+			scsi_test_unit_ready(csio,
+					     /*retries*/4,
+					     probedone,
+					     MSG_SIMPLE_Q_TAG,
+					     SSD_FULL_SIZE,
+					     /*timeout*/60000);
+			break;
+		}
 		scsi_inquiry(csio,
 			     /*retries*/4,
 			     probedone,
@@ -5840,6 +5862,24 @@
 	xpt_action((union ccb *)&cts);
 }
 
+/*
+ * Backoff Negotiation Code
+ */
+static int
+proberequestbackoff(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;
+	cts.type = CTS_TYPE_CURRENT_SETTINGS;
+	xpt_action((union ccb *)&cts);
+	if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+		return (0);
+	}
+	return (1);
+}
+
 static void
 probedone(struct cam_periph *periph, union ccb *done_ccb)
 {
@@ -6076,7 +6116,7 @@
 			 * 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
+			 * received.  So, on a new device, just retrieve
 			 * the user settings, and set them as the current
 			 * settings to set the device up.
 			 */
@@ -6095,25 +6135,82 @@
 		break;
 	}
 	case PROBE_TUR_FOR_NEGOTIATION:
+	case PROBE_DV_EXIT:
 		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);
 		}
+		/*
+		 * Do Domain Validation for lun 0 on devices that claim
+		 * to support Synchronous Transfer modes.
+		 */
+	 	if (softc->action == PROBE_TUR_FOR_NEGOTIATION
+		 && done_ccb->ccb_h.target_lun == 0
+		 && (path->device->inq_data.flags & SID_Sync) != 0) {
+			xpt_release_ccb(done_ccb);
+			softc->action = PROBE_INQUIRY_BASIC_DV1;
+			xpt_schedule(periph, priority);
+			return;
+		}
+		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, done_ccb->ccb_h.path,
+				  done_ccb);
+		}
+		xpt_release_ccb(done_ccb);
+		break;
+	case PROBE_INQUIRY_BASIC_DV1:
+	case PROBE_INQUIRY_BASIC_DV2:
+	{
+		struct scsi_inquiry_data *nbuf;
+		struct ccb_scsiio *csio;
+		int iqlen = SID_ADDITIONAL_LENGTH(&path->device->inq_data);
+
+		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);
+		}
+		csio = &done_ccb->csio;
+		nbuf = (struct scsi_inquiry_data *)csio->data_ptr;
 
+		if (bcmp(nbuf, &path->device->inq_data, iqlen) != 0) {
+			xpt_print_path(path);
+			printf("inquiry data does not compare at DV%d step\n",
+			    softc->action == PROBE_INQUIRY_BASIC_DV1? 1 : 2);
+			if (proberequestbackoff(periph)) {
+				softc->action = PROBE_DV_EXIT;
+			} else {
+				softc->action = PROBE_TUR_FOR_NEGOTIATION;
+			}
+			free(nbuf, M_TEMP);
+			xpt_release_ccb(done_ccb);
+			xpt_schedule(periph, priority);
+			return;
+		}
+		free(nbuf, M_TEMP);
+		if (softc->action == PROBE_INQUIRY_BASIC_DV1) {
+			softc->action = PROBE_INQUIRY_BASIC_DV2;
+			xpt_release_ccb(done_ccb);
+			xpt_schedule(periph, priority);
+			return;
+		}
 		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, done_ccb->ccb_h.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;

==== //depot/projects/newisp/cam/scsi/scsi_all.h#2 (text+ko) ====

@@ -599,6 +599,9 @@
 #define SID_AENC	0x80
 #define SID_TrmIOP	0x40
 	u_int8_t additional_length;
+#define	SID_ADDITIONAL_LENGTH(iqd)					\
+	((iqd)->additional_length +					\
+	offsetof(struct scsi_inquiry_data, additional_length) + 1)
 	u_int8_t reserved;
 	u_int8_t spc2_flags;
 #define SPC2_SID_MChngr 	0x08



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200611020445.kA24jjLV046073>