summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2014-10-06 12:49:07 +0000
committermav <mav@FreeBSD.org>2014-10-06 12:49:07 +0000
commite2b4e0c24317bc05b7ea9897d40b909a7f1f425f (patch)
tree01b3a5d61f56f5ca3f0aebe64762e05e1d4aa71d
parent994e3ee5d09c92eee8f60a8711abbb9c7cdc4156 (diff)
downloadFreeBSD-src-e2b4e0c24317bc05b7ea9897d40b909a7f1f425f.zip
FreeBSD-src-e2b4e0c24317bc05b7ea9897d40b909a7f1f425f.tar.gz
MFC r271443: Add support for Extended INQUIRY Data (0x86) VPD page.
-rw-r--r--sys/cam/ctl/ctl.c73
-rw-r--r--sys/cam/scsi/scsi_all.h49
2 files changed, 114 insertions, 8 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index b898e16..e84bd16 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -322,11 +322,11 @@ SYSCTL_INT(_kern_cam_ctl, OID_AUTO, verbose, CTLFLAG_RWTUN,
/*
* Supported pages (0x00), Serial number (0x80), Device ID (0x83),
- * Mode Page Policy (0x87),
+ * Extended INQUIRY Data (0x86), 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 9
+#define SCSI_EVPD_NUM_SUPPORTED_PAGES 10
static void ctl_isc_event_handler(ctl_ha_channel chanel, ctl_ha_event event,
int param);
@@ -382,6 +382,7 @@ static void ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg);
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_eid(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);
@@ -9851,18 +9852,20 @@ ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len)
pages->page_list[1] = SVPD_UNIT_SERIAL_NUMBER;
/* Device Identification */
pages->page_list[2] = SVPD_DEVICE_ID;
+ /* Extended INQUIRY Data */
+ pages->page_list[3] = SVPD_EXTENDED_INQUIRY_DATA;
/* Mode Page Policy */
- pages->page_list[3] = SVPD_MODE_PAGE_POLICY;
+ pages->page_list[4] = SVPD_MODE_PAGE_POLICY;
/* SCSI Ports */
- pages->page_list[4] = SVPD_SCSI_PORTS;
+ pages->page_list[5] = SVPD_SCSI_PORTS;
/* Third-party Copy */
- pages->page_list[5] = SVPD_SCSI_TPC;
+ pages->page_list[6] = SVPD_SCSI_TPC;
/* Block limits */
- pages->page_list[6] = SVPD_BLOCK_LIMITS;
+ pages->page_list[7] = SVPD_BLOCK_LIMITS;
/* Block Device Characteristics */
- pages->page_list[7] = SVPD_BDC;
+ pages->page_list[8] = SVPD_BDC;
/* Logical Block Provisioning */
- pages->page_list[8] = SVPD_LBP;
+ pages->page_list[9] = SVPD_LBP;
ctsio->scsi_status = SCSI_STATUS_OK;
@@ -9931,6 +9934,57 @@ ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len)
static int
+ctl_inquiry_evpd_eid(struct ctl_scsiio *ctsio, int alloc_len)
+{
+ struct scsi_vpd_extended_inquiry_data *eid_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);
+ eid_ptr = (struct scsi_vpd_extended_inquiry_data *)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)
+ eid_ptr->device = (SID_QUAL_LU_CONNECTED << 5) |
+ lun->be_lun->lun_type;
+ 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;
+ eid_ptr->flags2 = SVPD_EID_HEADSUP | SVPD_EID_ORDSUP | SVPD_EID_SIMPSUP;
+ eid_ptr->flags3 = SVPD_EID_V_SUP;
+
+ 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_mpp(struct ctl_scsiio *ctsio, int alloc_len)
{
struct scsi_vpd_mode_page_policy *mpp_ptr;
@@ -10412,6 +10466,9 @@ ctl_inquiry_evpd(struct ctl_scsiio *ctsio)
case SVPD_DEVICE_ID:
retval = ctl_inquiry_evpd_devid(ctsio, alloc_len);
break;
+ case SVPD_EXTENDED_INQUIRY_DATA:
+ retval = ctl_inquiry_evpd_eid(ctsio, alloc_len);
+ break;
case SVPD_MODE_PAGE_POLICY:
retval = ctl_inquiry_evpd_mpp(ctsio, alloc_len);
break;
diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h
index 3d7b329..bd66ab3 100644
--- a/sys/cam/scsi/scsi_all.h
+++ b/sys/cam/scsi/scsi_all.h
@@ -2110,6 +2110,55 @@ struct scsi_service_action_in
uint8_t control;
};
+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 flags1;
+#define SVPD_EID_AM 0xC0
+#define SVPD_EID_SPT 0x38
+#define SVPD_EID_SPT_1 0x00
+#define SVPD_EID_SPT_12 0x08
+#define SVPD_EID_SPT_2 0x10
+#define SVPD_EID_SPT_13 0x18
+#define SVPD_EID_SPT_3 0x20
+#define SVPD_EID_SPT_23 0x28
+#define SVPD_EID_SPT_123 0x38
+#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
+#define SVPD_EID_PRIOR_SUP 0x08
+#define SVPD_EID_HEADSUP 0x04
+#define SVPD_EID_ORDSUP 0x02
+#define SVPD_EID_SIMPSUP 0x01
+ uint8_t flags3;
+#define SVPD_EID_WU_SUP 0x08
+#define SVPD_EID_CRD_SUP 0x04
+#define SVPD_EID_NV_SUP 0x02
+#define SVPD_EID_V_SUP 0x01
+ uint8_t flags4;
+#define SVPD_EID_P_I_I_SUP 0x10
+#define SVPD_EID_LUICLT 0x01
+ uint8_t flags5;
+#define SVPD_EID_R_SUP 0x10
+#define SVPD_EID_CBCS 0x01
+ uint8_t flags6;
+#define SVPD_EID_MULTI_I_T_FW 0x0F
+ uint8_t est[2];
+ uint8_t flags7;
+#define SVPD_EID_POA_SUP 0x80
+#define SVPD_EID_HRA_SUP 0x80
+#define SVPD_EID_VSA_SUP 0x80
+ uint8_t max_sense_length;
+ uint8_t reserved2[50];
+};
+
struct scsi_vpd_mode_page_policy_descr
{
uint8_t page_code;
OpenPOWER on IntegriCloud