svn commit: r277917 - in head/sys/cam: ctl scsi

Kenneth D. Merry ken at FreeBSD.org
Fri Jan 30 05:23:41 UTC 2015


Author: ken
Date: Fri Jan 30 05:23:39 2015
New Revision: 277917
URL: https://svnweb.freebsd.org/changeset/base/277917

Log:
  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.
  
  Sponsored by:	Spectra Logic
  MFC after:	1 week

Modified:
  head/sys/cam/ctl/ctl.c
  head/sys/cam/scsi/scsi_all.h

Modified: head/sys/cam/ctl/ctl.c
==============================================================================
--- head/sys/cam/ctl/ctl.c	Fri Jan 30 05:14:01 2015	(r277916)
+++ head/sys/cam/ctl/ctl.c	Fri Jan 30 05:23:39 2015	(r277917)
@@ -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.
@@ -446,6 +446,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);
@@ -9433,6 +9435,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;
@@ -9441,6 +9444,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"));
@@ -9526,6 +9530,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);
 
@@ -9593,6 +9605,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)
 {
@@ -9665,6 +9680,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)
 {
@@ -9721,6 +9739,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)
 {
@@ -9758,10 +9779,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;
@@ -9820,6 +9864,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)
 {
@@ -10235,6 +10282,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)
 {
@@ -10299,6 +10349,9 @@ err:
 	return (retval);
 }
 
+/*
+ * Standard INQUIRY data.
+ */
 static int
 ctl_inquiry_std(struct ctl_scsiio *ctsio)
 {
@@ -11468,6 +11521,23 @@ 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];
+		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: head/sys/cam/scsi/scsi_all.h
==============================================================================
--- head/sys/cam/scsi/scsi_all.h	Fri Jan 30 05:14:01 2015	(r277916)
+++ head/sys/cam/scsi/scsi_all.h	Fri Jan 30 05:23:39 2015	(r277917)
@@ -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


More information about the svn-src-head mailing list