PERFORCE change 109010 for review

Matt Jacob mjacob at FreeBSD.org
Thu Nov 2 07:05:44 UTC 2006


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

Change 109010 by mjacob at newisp on 2006/11/02 07:05:26

	More Domain Validation work- sync backoff works like you'd expect
	after some fault injection testing.

Affected files ...

.. //depot/projects/newisp/cam/cam_xpt.c#6 edit

Differences ...

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

@@ -150,6 +150,7 @@
 #define CAM_DEV_RESIZE_QUEUE_NEEDED	0x10
 #define CAM_DEV_TAG_AFTER_COUNT		0x20
 #define CAM_DEV_INQUIRY_DATA_VALID	0x40
+#define	CAM_DEV_IN_DV			0x80
 	u_int32_t	 tag_delay_count;
 #define	CAM_TAG_DELAY_COUNT		5
 	u_int32_t	 tag_saved_openings;
@@ -5863,20 +5864,76 @@
 }
 
 /*
- * Backoff Negotiation Code
+ * Backoff Negotiation Code- only pertinent for SPI devices.
  */
 static int
 proberequestbackoff(struct cam_periph *periph)
 {
 	struct ccb_trans_settings cts;
+	struct ccb_trans_settings_spi *spi;
 
 	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) {
+		xpt_print_path(periph->path);
+		printf("failed to get current settings\n");
+		return (0);
+	}
+	if (cts.transport != XPORT_SPI) {
+		xpt_print_path(periph->path);
+		printf("not SPI transport\n");
+		return (0);
+	}
+	spi = &cts.xport_specific.spi;
+
+	/*
+	 * We cannot renegotiate sync rate if we don't have one.
+	 */
+	if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) {
+		xpt_print_path(periph->path);
+		printf("no sync rate known\n");
+		return (0);
+	}
+
+	/*
+	 * XXX: skipping PPR options
+	 */
+	if ((spi->valid & CTS_SPI_VALID_PPR_OPTIONS) != 0) {
+		xpt_print_path(periph->path);
+		printf("PPR options not handled yet\n");
+		return (0);
+	}
+
+	/*
+	 * A sync rate with unknown or zero offset is nonsensical.
+	 */
+	if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0
+	 && ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0
+	 || ((spi->sync_offset == 0)))) {
+		xpt_print_path(periph->path);
+		printf("nonsensical sync rate/offset validity\n");
 		return (0);
 	}
+
+	/*
+	 * Jump sync_period up by one, but stop at 5MHz and fall back to Async.
+	 */
+	spi->valid = CTS_SPI_VALID_SYNC_RATE | CTS_SPI_VALID_SYNC_OFFSET;
+	for (;;) {
+		spi->sync_period++;
+		if (spi->sync_period >= 0xf) {
+			spi->sync_period = 0;
+			spi->sync_offset = 0;
+		}
+		cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
+		cts.type = CTS_TYPE_CURRENT_SETTINGS;
+		xpt_action((union ccb *)&cts);
+		if ((cts.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
+			break;
+		}
+	}
 	return (1);
 }
 
@@ -6147,13 +6204,15 @@
 		 */
 	 	if (softc->action == PROBE_TUR_FOR_NEGOTIATION
 		 && done_ccb->ccb_h.target_lun == 0
-		 && (path->device->inq_data.flags & SID_Sync) != 0) {
+		 && (path->device->inq_data.flags & SID_Sync) != 0
+                 && (path->device->flags & CAM_DEV_IN_DV) == 0) {
+			path->device->flags |= CAM_DEV_IN_DV;
 			xpt_release_ccb(done_ccb);
 			softc->action = PROBE_INQUIRY_BASIC_DV1;
 			xpt_schedule(periph, priority);
 			return;
 		}
-		path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+		path->device->flags &= ~(CAM_DEV_UNCONFIGURED|CAM_DEV_IN_DV);
 		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;
@@ -6177,15 +6236,14 @@
 		}
 		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_TUR_FOR_NEGOTIATION;
+			} else {
 				softc->action = PROBE_DV_EXIT;
-			} else {
-				softc->action = PROBE_TUR_FOR_NEGOTIATION;
 			}
 			free(nbuf, M_TEMP);
 			xpt_release_ccb(done_ccb);


More information about the p4-projects mailing list