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
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to