From owner-p4-projects@FreeBSD.ORG Thu Nov 2 04:45:46 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 142EF16A412; Thu, 2 Nov 2006 04:45:46 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C929516A407 for ; Thu, 2 Nov 2006 04:45:45 +0000 (UTC) (envelope-from mjacob@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 97C2443D49 for ; Thu, 2 Nov 2006 04:45:45 +0000 (GMT) (envelope-from mjacob@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id kA24jjah046076 for ; Thu, 2 Nov 2006 04:45:45 GMT (envelope-from mjacob@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id kA24jjLV046073 for perforce@freebsd.org; Thu, 2 Nov 2006 04:45:45 GMT (envelope-from mjacob@freebsd.org) Date: Thu, 2 Nov 2006 04:45:45 GMT Message-Id: <200611020445.kA24jjLV046073@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mjacob@freebsd.org using -f From: Matt Jacob To: Perforce Change Reviews Cc: Subject: PERFORCE change 109009 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Nov 2006 04:45:46 -0000 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