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