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>