Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 15 Feb 2015 08:52:10 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r278796 - in stable/10/sys/cam: ctl scsi
Message-ID:  <201502150852.t1F8qAvC011047@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Sun Feb 15 08:52:09 2015
New Revision: 278796
URL: https://svnweb.freebsd.org/changeset/base/278796

Log:
  MFC r277917 (by ken), r278598:
  Improve SCSI Extended Inquiry VPD page (0x86) support.
  
  sys/cam/scsi/scsi_all.h:
          In struct scsi_extended_inquiry_data:
          - Increase the length field to 2 bytes, as it is 2 bytes in SPC-4.
          - Add bit definitions for the various Activiate Microcode actions.
          - Add the Sequential Access Logical Block Protection support bit,
            since we need that in the sa(4) driver.  (For modifications
            that will come later.)
          - Add definitions for the various Multi I_T Nexus Microcode
            Download modes.
  
  sys/cam/ctl/ctl.c:
          As of SPC-4, a single report of "REPORTED LUNS DATA HAS CHANGED"
          is to be given per I_T nexus.  Once it is reported, the unit
          attention condition should be cleared for all LUNS attached to
          an I_T nexus.
  
          Previously that only happened when a REPORT LUNS command was
          processed.
  
          This behavior may be different (according to SAM-5) when the
          UA_INTLCK_CTRL bits are non-zero in the control mode page but
          CTL does not currently support that.
  
          So, in view of the spec, whenever we report a LUN inventory
          change unit attention, clear it on all LUNs for that
          particular I_T nexus.
  
          Add a new function, ctl_clear_ua() that will clear a unit
          attention on all LUNs for the given I_T nexus.
  
          One field in the extended inquiry data that we could potentially
          report at some point is the maximum supported sense data length.
          To do that, we would the SIM to report (via path inquiry
          perhaps) how much sense data it is able to send.
  
          Add comments to explain some of the bits that are set in the
          Extended Inquiry VPD page.
  
          Add a few comments to make it more clear which functions handle
          various VPD pages.

Modified:
  stable/10/sys/cam/ctl/ctl.c
  stable/10/sys/cam/scsi/scsi_all.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/cam/ctl/ctl.c
==============================================================================
--- stable/10/sys/cam/ctl/ctl.c	Sun Feb 15 08:44:30 2015	(r278795)
+++ stable/10/sys/cam/ctl/ctl.c	Sun Feb 15 08:52:09 2015	(r278796)
@@ -31,7 +31,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl.c#8 $
+ * $Id$
  */
 /*
  * CAM Target Layer, a SCSI device emulation subsystem.
@@ -448,6 +448,8 @@ static int ctl_scsiio_lun_check(struct c
 				struct ctl_scsiio *ctsio);
 //static int ctl_check_rtr(union ctl_io *pending_io, struct ctl_softc *softc);
 static void ctl_failover(void);
+static void ctl_clear_ua(struct ctl_softc *ctl_softc, uint32_t initidx,
+			 ctl_ua_type ua_type);
 static int ctl_scsiio_precheck(struct ctl_softc *ctl_softc,
 			       struct ctl_scsiio *ctsio);
 static int ctl_scsiio(struct ctl_scsiio *ctsio);
@@ -9435,6 +9437,7 @@ ctl_request_sense(struct ctl_scsiio *cts
 {
 	struct scsi_request_sense *cdb;
 	struct scsi_sense_data *sense_ptr;
+	struct ctl_softc *ctl_softc;
 	struct ctl_lun *lun;
 	uint32_t initidx;
 	int have_error;
@@ -9443,6 +9446,7 @@ ctl_request_sense(struct ctl_scsiio *cts
 
 	cdb = (struct scsi_request_sense *)ctsio->cdb;
 
+	ctl_softc = control_softc;
 	lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
 
 	CTL_DEBUG_PRINT(("ctl_request_sense\n"));
@@ -9528,6 +9532,14 @@ ctl_request_sense(struct ctl_scsiio *cts
 		ua_type = ctl_build_ua(lun, initidx, sense_ptr, sense_format);
 		if (ua_type != CTL_UA_NONE)
 			have_error = 1;
+		if (ua_type == CTL_UA_LUN_CHANGE) {
+			mtx_unlock(&lun->lun_lock);
+			mtx_lock(&ctl_softc->ctl_lock);
+			ctl_clear_ua(ctl_softc, initidx, ua_type);
+			mtx_unlock(&ctl_softc->ctl_lock);
+			mtx_lock(&lun->lun_lock);
+		}
+
 	}
 	mtx_unlock(&lun->lun_lock);
 
@@ -9595,6 +9607,9 @@ ctl_cmddt_inquiry(struct ctl_scsiio *cts
 }
 #endif
 
+/*
+ * SCSI VPD page 0x00, the Supported VPD Pages page.
+ */
 static int
 ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len)
 {
@@ -9667,6 +9682,9 @@ ctl_inquiry_evpd_supported(struct ctl_sc
 	return (CTL_RETVAL_COMPLETE);
 }
 
+/*
+ * SCSI VPD page 0x80, the Unit Serial Number page.
+ */
 static int
 ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len)
 {
@@ -9723,6 +9741,9 @@ ctl_inquiry_evpd_serial(struct ctl_scsii
 }
 
 
+/*
+ * SCSI VPD page 0x86, the Extended INQUIRY Data page.
+ */
 static int
 ctl_inquiry_evpd_eid(struct ctl_scsiio *ctsio, int alloc_len)
 {
@@ -9760,10 +9781,33 @@ ctl_inquiry_evpd_eid(struct ctl_scsiio *
 	else
 		eid_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT;
 	eid_ptr->page_code = SVPD_EXTENDED_INQUIRY_DATA;
-	eid_ptr->page_length = data_len - 4;
+	scsi_ulto2b(data_len - 4, eid_ptr->page_length);
+	/*
+	 * We support head of queue, ordered and simple tags.
+	 */
 	eid_ptr->flags2 = SVPD_EID_HEADSUP | SVPD_EID_ORDSUP | SVPD_EID_SIMPSUP;
+	/*
+	 * Volatile cache supported.
+	 */
 	eid_ptr->flags3 = SVPD_EID_V_SUP;
 
+	/*
+	 * This means that we clear the REPORTED LUNS DATA HAS CHANGED unit
+	 * attention for a particular IT nexus on all LUNs once we report
+	 * it to that nexus once.  This bit is required as of SPC-4.
+	 */
+	eid_ptr->flags4 = SVPD_EID_LUICLT;
+
+	/*
+	 * XXX KDM in order to correctly answer this, we would need
+	 * information from the SIM to determine how much sense data it
+	 * can send.  So this would really be a path inquiry field, most
+	 * likely.  This can be set to a maximum of 252 according to SPC-4,
+	 * but the hardware may or may not be able to support that much.
+	 * 0 just means that the maximum sense data length is not reported.
+	 */
+	eid_ptr->max_sense_length = 0;
+
 	ctl_set_success(ctsio);
 	ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
 	ctsio->be_move_done = ctl_config_move_done;
@@ -9822,6 +9866,9 @@ ctl_inquiry_evpd_mpp(struct ctl_scsiio *
 	return (CTL_RETVAL_COMPLETE);
 }
 
+/*
+ * SCSI VPD page 0x83, the Device Identification page.
+ */
 static int
 ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len)
 {
@@ -10237,6 +10284,9 @@ ctl_inquiry_evpd_lbp(struct ctl_scsiio *
 	return (CTL_RETVAL_COMPLETE);
 }
 
+/*
+ * INQUIRY with the EVPD bit set.
+ */
 static int
 ctl_inquiry_evpd(struct ctl_scsiio *ctsio)
 {
@@ -10301,6 +10351,9 @@ err:
 	return (retval);
 }
 
+/*
+ * Standard INQUIRY data.
+ */
 static int
 ctl_inquiry_std(struct ctl_scsiio *ctsio)
 {
@@ -11470,6 +11523,24 @@ ctl_failover(void)
 	mtx_unlock(&softc->ctl_lock);
 }
 
+static void
+ctl_clear_ua(struct ctl_softc *ctl_softc, uint32_t initidx,
+	     ctl_ua_type ua_type)
+{
+	struct ctl_lun *lun;
+	ctl_ua_type *pu;
+
+	mtx_assert(&ctl_softc->ctl_lock, MA_OWNED);
+
+	STAILQ_FOREACH(lun, &ctl_softc->lun_list, links) {
+		mtx_lock(&lun->lun_lock);
+		pu = lun->pending_ua[initidx / CTL_MAX_INIT_PER_PORT];
+		if (pu != NULL)
+			pu[initidx % CTL_MAX_INIT_PER_PORT] &= ~ua_type;
+		mtx_unlock(&lun->lun_lock);
+	}
+}
+
 static int
 ctl_scsiio_precheck(struct ctl_softc *softc, struct ctl_scsiio *ctsio)
 {

Modified: stable/10/sys/cam/scsi/scsi_all.h
==============================================================================
--- stable/10/sys/cam/scsi/scsi_all.h	Sun Feb 15 08:44:30 2015	(r278795)
+++ stable/10/sys/cam/scsi/scsi_all.h	Sun Feb 15 08:52:09 2015	(r278796)
@@ -2112,10 +2112,15 @@ struct scsi_vpd_extended_inquiry_data
 	uint8_t device;
 	uint8_t page_code;
 #define	SVPD_EXTENDED_INQUIRY_DATA	0x86
-	uint8_t reserved;
-	uint8_t page_length;
+	uint8_t page_length[2];
 	uint8_t flags1;
-#define	SVPD_EID_AM		0xC0
+
+	/* These values are for direct access devices */
+#define	SVPD_EID_AM_MASK	0xC0
+#define	SVPD_EID_AM_DEFER	0x80
+#define	SVPD_EID_AM_IMMED	0x40
+#define	SVPD_EID_AM_UNDEFINED	0x00
+#define	SVPD_EID_AM_RESERVED	0xc0
 #define	SVPD_EID_SPT		0x38
 #define	SVPD_EID_SPT_1		0x00
 #define	SVPD_EID_SPT_12		0x08
@@ -2124,9 +2129,14 @@ struct scsi_vpd_extended_inquiry_data
 #define	SVPD_EID_SPT_3		0x20
 #define	SVPD_EID_SPT_23		0x28
 #define	SVPD_EID_SPT_123	0x38
+
+	/* These values are for sequential access devices */
+#define	SVPD_EID_SA_SPT_LBP	0x08
+
 #define	SVPD_EID_GRD_CHK	0x04
 #define	SVPD_EID_APP_CHK	0x02
 #define	SVPD_EID_REF_CHK	0x01
+
 	uint8_t flags2;
 #define	SVPD_EID_UASK_SUP	0x20
 #define	SVPD_EID_GROUP_SUP	0x10
@@ -2147,6 +2157,10 @@ struct scsi_vpd_extended_inquiry_data
 #define	SVPD_EID_CBCS		0x01
 	uint8_t flags6;
 #define	SVPD_EID_MULTI_I_T_FW	0x0F
+#define	SVPD_EID_MC_VENDOR_SPEC	0x00
+#define	SVPD_EID_MC_MODE_1	0x01
+#define	SVPD_EID_MC_MODE_2	0x02
+#define	SVPD_EID_MC_MODE_3	0x03
 	uint8_t est[2];
 	uint8_t flags7;
 #define	SVPD_EID_POA_SUP	0x80



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201502150852.t1F8qAvC011047>