Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 May 2009 21:40:44 GMT
From:      Alexander Motin <mav@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 162821 for review
Message-ID:  <200905262140.n4QLeiti050312@repoman.freebsd.org>

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

Change 162821 by mav@mav_mavbook on 2009/05/26 21:40:39

	Some parts of ATAPI support.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_all.c#3 edit
.. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_all.h#3 edit
.. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#7 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_all.c#3 (text+ko) ====

@@ -46,25 +46,6 @@
 #include <sys/sbuf.h>
 
 void
-ata_ident(struct ccb_ataio *ataio, u_int32_t retries,
-	     void (*cbfcnp)(struct cam_periph *, union ccb *),
-	     u_int8_t tag_action, u_int8_t *inq_buf, u_int32_t inq_len,
-	     u_int32_t timeout)
-{
-
-	cam_fill_ataio(ataio,
-		      retries,
-		      cbfcnp,
-		      /*flags*/CAM_DIR_IN,
-		      tag_action,
-		      /*data_ptr*/inq_buf,
-		      /*dxfer_len*/inq_len,
-		      timeout);
-
-	ataio->cmd.command = ATA_ATA_IDENTIFY;
-}
-
-void
 ata_print_ident(struct ata_params *ident_data)
 {
 	char product[48], revision[16];

==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_all.h#3 (text+ko) ====

@@ -41,12 +41,6 @@
 };
 
 void
-ata_ident(struct ccb_ataio *ataio, u_int32_t retries,
-	     void (*cbfcnp)(struct cam_periph *, union ccb *),
-	     u_int8_t tag_action, u_int8_t *inq_buf, u_int32_t inq_len,
-	     u_int32_t timeout);
-
-void
 ata_print_ident(struct ata_params *ident_data);
 
 void

==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#7 (text+ko) ====

@@ -92,11 +92,15 @@
 
 typedef enum {
 	PROBE_IDENTIFY,
+	PROBE_INQUIRY,
+	PROBE_FULL_INQUIRY,
 	PROBE_INVALID
 } probe_action;
 
 static char *probe_action_text[] = {
 	"PROBE_IDENTIFY",
+	"PROBE_INQUIRY",
+	"PROBE_FULL_INQUIRY",
 	"PROBE_INVALID"
 };
 
@@ -308,12 +312,14 @@
 {
 	/* Probe the device that our peripheral driver points to */
 	struct ccb_ataio *ataio;
+	struct ccb_scsiio *csio;
 	probe_softc *softc;
 
 	CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probestart\n"));
 
 	softc = (probe_softc *)periph->softc;
 	ataio = &start_ccb->ataio;
+	csio = &start_ccb->csio;
 
 	switch (softc->action) {
 	case PROBE_IDENTIFY:
@@ -339,12 +345,51 @@
 			MD5Final(softc->digest, &context);
 		}
 
-		ata_ident(ataio,
+		cam_fill_ataio(ataio,
+		      4,
+		      probedone,
+		      /*flags*/CAM_DIR_IN,
+		      MSG_SIMPLE_Q_TAG,
+		      /*data_ptr*/(u_int8_t *)ident_buf,
+		      /*dxfer_len*/sizeof(struct ata_params),
+		      60 * 1000);
+
+		if (periph->path->device->protocol == PROTO_ATA)
+			ataio->cmd.command = ATA_ATA_IDENTIFY;
+		else
+			ataio->cmd.command = ATA_ATAPI_IDENTIFY;
+		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 (softc->action == PROBE_INQUIRY)
+			inquiry_len = SHORT_INQUIRY_LENGTH;
+		else
+			inquiry_len = SID_ADDITIONAL_LENGTH(inq_buf);
+
+		/*
+		 * Some parallel SCSI devices fail to send an
+		 * ignore wide residue message when dealing with
+		 * odd length inquiry requests.  Round up to be
+		 * safe.
+		 */
+		inquiry_len = roundup2(inquiry_len, 2);
+
+		scsi_inquiry(csio,
 			     /*retries*/4,
 			     probedone,
 			     MSG_SIMPLE_Q_TAG,
-			     (u_int8_t *)ident_buf,
-			     sizeof(struct ata_params),
+			     (u_int8_t *)inq_buf,
+			     inquiry_len,
+			     /*evpd*/FALSE,
+			     /*page_code*/0,
+			     SSD_MIN_SIZE,
 			     /*timeout*/60 * 1000);
 		break;
 	}
@@ -573,16 +618,101 @@
 //			else
 //				PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_0);
 
-			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+//			if ((softc->flags & PROBE_NO_ANNOUNCE) == 0) {
+			if (path->device->protocol == PROTO_ATA) {
+				path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+				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;
+			} else {
+				PROBE_SET_ACTION(softc, PROBE_INQUIRY);
+				xpt_release_ccb(done_ccb);
+				xpt_schedule(periph, priority);
+				return;
+			}
+		} 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_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 len;
+
+				/*
+				 * 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.
+				 */
+				len = inq_buf->additional_length
+				    + offsetof(struct scsi_inquiry_data,
+                                               additional_length) + 1;
+				if (softc->action == PROBE_INQUIRY
+				    && len > SHORT_INQUIRY_LENGTH) {
+					PROBE_SET_ACTION(softc, PROBE_FULL_INQUIRY);
+					xpt_release_ccb(done_ccb);
+					xpt_schedule(periph, priority);
+					return;
+				}
+
+				scsi_find_quirk(path->device);
 
-//			if ((softc->flags & PROBE_NO_ANNOUNCE) == 0) {
+//				scsi_devise_transport(path);
+				path->device->flags &= ~CAM_DEV_UNCONFIGURED;
 				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;
+				xpt_release_ccb(done_ccb);
+				return;
+			}
+			default:
+				break;
+			}
 		} else if (cam_periph_error(done_ccb, 0,
 					    done_ccb->ccb_h.target_lun > 0
 					    ? SF_RETRY_UA|SF_QUIET_IR



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