Author: mav
Date: Tue Sep  9 14:09:51 2014
New Revision: 271311
URL: http://svnweb.freebsd.org/changeset/base/271311

Log:
  Add support for Mode Page Policy (0x87) VPD page.

Modified:
  head/sys/cam/ctl/ctl.c

Modified: head/sys/cam/ctl/ctl.c
==============================================================================
--- head/sys/cam/ctl/ctl.c      Tue Sep  9 13:50:21 2014        (r271310)
+++ head/sys/cam/ctl/ctl.c      Tue Sep  9 14:09:51 2014        (r271311)
@@ -320,10 +320,11 @@ SYSCTL_INT(_kern_cam_ctl, OID_AUTO, verb
 
 /*
  * Supported pages (0x00), Serial number (0x80), Device ID (0x83),
+ * Mode Page Policy (0x87),
  * SCSI Ports (0x88), Third-party Copy (0x8F), Block limits (0xB0),
  * Block Device Characteristics (0xB1) and Logical Block Provisioning (0xB2)
  */
-#define SCSI_EVPD_NUM_SUPPORTED_PAGES  8
+#define SCSI_EVPD_NUM_SUPPORTED_PAGES  9
 
 static void ctl_isc_event_handler(ctl_ha_channel chanel, ctl_ha_event event,
                                  int param);
@@ -379,6 +380,7 @@ static void ctl_hndl_per_res_out_on_othe
 static int ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len);
 static int ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len);
 static int ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len);
+static int ctl_inquiry_evpd_mpp(struct ctl_scsiio *ctsio, int alloc_len);
 static int ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio,
                                         int alloc_len);
 static int ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio,
@@ -9831,16 +9833,18 @@ ctl_inquiry_evpd_supported(struct ctl_sc
        pages->page_list[1] = SVPD_UNIT_SERIAL_NUMBER;
        /* Device Identification */
        pages->page_list[2] = SVPD_DEVICE_ID;
+       /* Mode Page Policy */
+       pages->page_list[3] = SVPD_MODE_PAGE_POLICY;
        /* SCSI Ports */
-       pages->page_list[3] = SVPD_SCSI_PORTS;
+       pages->page_list[4] = SVPD_SCSI_PORTS;
        /* Third-party Copy */
-       pages->page_list[4] = SVPD_SCSI_TPC;
+       pages->page_list[5] = SVPD_SCSI_TPC;
        /* Block limits */
-       pages->page_list[5] = SVPD_BLOCK_LIMITS;
+       pages->page_list[6] = SVPD_BLOCK_LIMITS;
        /* Block Device Characteristics */
-       pages->page_list[6] = SVPD_BDC;
+       pages->page_list[7] = SVPD_BDC;
        /* Logical Block Provisioning */
-       pages->page_list[7] = SVPD_LBP;
+       pages->page_list[8] = SVPD_LBP;
 
        ctsio->scsi_status = SCSI_STATUS_OK;
 
@@ -9909,6 +9913,58 @@ ctl_inquiry_evpd_serial(struct ctl_scsii
 
 
 static int
+ctl_inquiry_evpd_mpp(struct ctl_scsiio *ctsio, int alloc_len)
+{
+       struct scsi_vpd_mode_page_policy *mpp_ptr;
+       struct ctl_lun *lun;
+       int data_len;
+
+       lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
+
+       data_len = sizeof(struct scsi_vpd_mode_page_policy) +
+           sizeof(struct scsi_vpd_mode_page_policy_descr);
+
+       ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
+       mpp_ptr = (struct scsi_vpd_mode_page_policy *)ctsio->kern_data_ptr;
+       ctsio->kern_sg_entries = 0;
+
+       if (data_len < alloc_len) {
+               ctsio->residual = alloc_len - data_len;
+               ctsio->kern_data_len = data_len;
+               ctsio->kern_total_len = data_len;
+       } else {
+               ctsio->residual = 0;
+               ctsio->kern_data_len = alloc_len;
+               ctsio->kern_total_len = alloc_len;
+       }
+       ctsio->kern_data_resid = 0;
+       ctsio->kern_rel_offset = 0;
+       ctsio->kern_sg_entries = 0;
+
+       /*
+        * The control device is always connected.  The disk device, on the
+        * other hand, may not be online all the time.
+        */
+       if (lun != NULL)
+               mpp_ptr->device = (SID_QUAL_LU_CONNECTED << 5) |
+                                    lun->be_lun->lun_type;
+       else
+               mpp_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT;
+       mpp_ptr->page_code = SVPD_MODE_PAGE_POLICY;
+       scsi_ulto2b(data_len - 4, mpp_ptr->page_length);
+       mpp_ptr->descr[0].page_code = 0x3f;
+       mpp_ptr->descr[0].subpage_code = 0xff;
+       mpp_ptr->descr[0].policy = SVPD_MPP_SHARED;
+
+       ctsio->scsi_status = SCSI_STATUS_OK;
+       ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
+       ctsio->be_move_done = ctl_config_move_done;
+       ctl_datamove((union ctl_io *)ctsio);
+
+       return (CTL_RETVAL_COMPLETE);
+}
+
+static int
 ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len)
 {
        struct scsi_vpd_device_id *devid_ptr;
@@ -10338,6 +10394,9 @@ ctl_inquiry_evpd(struct ctl_scsiio *ctsi
        case SVPD_DEVICE_ID:
                retval = ctl_inquiry_evpd_devid(ctsio, alloc_len);
                break;
+       case SVPD_MODE_PAGE_POLICY:
+               retval = ctl_inquiry_evpd_mpp(ctsio, alloc_len);
+               break;
        case SVPD_SCSI_PORTS:
                retval = ctl_inquiry_evpd_scsi_ports(ctsio, alloc_len);
                break;
_______________________________________________
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