PERFORCE change 109009 for review
Matt Jacob
mjacob at FreeBSD.org
Thu Nov 2 04:45:46 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=109009
Change 109009 by mjacob at 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
More information about the p4-projects
mailing list