mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 16:22:46 -04:00
Add reporting of SCSI Feature Sets VPD page from SPC-5.
CTL implements all defined feature sets except Drive Maintenance 2016, which is not very applicable to such a virtual device, and implemented only partially now. But may be it could be fixed later at least for completeness. MFC after: 2 weeks
This commit is contained in:
parent
0dbac71f19
commit
0ea67e7019
2 changed files with 81 additions and 5 deletions
|
|
@ -448,10 +448,11 @@ SYSCTL_INT(_kern_cam_ctl, OID_AUTO, max_ports, CTLFLAG_RDTUN,
|
|||
/*
|
||||
* Supported pages (0x00), Serial number (0x80), Device ID (0x83),
|
||||
* 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)
|
||||
* SCSI Ports (0x88), Third-party Copy (0x8F), SCSI Feature Sets (0x92),
|
||||
* Block limits (0xB0), Block Device Characteristics (0xB1) and
|
||||
* Logical Block Provisioning (0xB2)
|
||||
*/
|
||||
#define SCSI_EVPD_NUM_SUPPORTED_PAGES 10
|
||||
#define SCSI_EVPD_NUM_SUPPORTED_PAGES 11
|
||||
|
||||
static void ctl_isc_event_handler(ctl_ha_channel chanel, ctl_ha_event event,
|
||||
int param);
|
||||
|
|
@ -489,6 +490,7 @@ 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);
|
||||
static int ctl_inquiry_evpd_sfs(struct ctl_scsiio *ctsio, int alloc_len);
|
||||
static int ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio,
|
||||
int alloc_len);
|
||||
static int ctl_inquiry_evpd_bdc(struct ctl_scsiio *ctsio, int alloc_len);
|
||||
|
|
@ -9318,6 +9320,8 @@ ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len)
|
|||
pages->page_list[p++] = SVPD_SCSI_PORTS;
|
||||
/* Third-party Copy */
|
||||
pages->page_list[p++] = SVPD_SCSI_TPC;
|
||||
/* SCSI Feature Sets */
|
||||
pages->page_list[p++] = SVPD_SCSI_SFS;
|
||||
if (lun != NULL && lun->be_lun->lun_type == T_DIRECT) {
|
||||
/* Block limits */
|
||||
pages->page_list[p++] = SVPD_BLOCK_LIMITS;
|
||||
|
|
@ -9698,6 +9702,58 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len)
|
|||
return (CTL_RETVAL_COMPLETE);
|
||||
}
|
||||
|
||||
static int
|
||||
ctl_inquiry_evpd_sfs(struct ctl_scsiio *ctsio, int alloc_len)
|
||||
{
|
||||
struct ctl_lun *lun = CTL_LUN(ctsio);
|
||||
struct scsi_vpd_sfs *sfs_ptr;
|
||||
int sfs_page_size, n;
|
||||
|
||||
sfs_page_size = sizeof(*sfs_ptr) + 5 * 2;
|
||||
ctsio->kern_data_ptr = malloc(sfs_page_size, M_CTL, M_WAITOK | M_ZERO);
|
||||
sfs_ptr = (struct scsi_vpd_sfs *)ctsio->kern_data_ptr;
|
||||
ctsio->kern_sg_entries = 0;
|
||||
ctsio->kern_rel_offset = 0;
|
||||
ctsio->kern_sg_entries = 0;
|
||||
ctsio->kern_data_len = min(sfs_page_size, alloc_len);
|
||||
ctsio->kern_total_len = ctsio->kern_data_len;
|
||||
|
||||
/*
|
||||
* The control device is always connected. The disk device, on the
|
||||
* other hand, may not be online all the time. Need to change this
|
||||
* to figure out whether the disk device is actually online or not.
|
||||
*/
|
||||
if (lun != NULL)
|
||||
sfs_ptr->device = (SID_QUAL_LU_CONNECTED << 5) |
|
||||
lun->be_lun->lun_type;
|
||||
else
|
||||
sfs_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT;
|
||||
|
||||
sfs_ptr->page_code = SVPD_SCSI_SFS;
|
||||
n = 0;
|
||||
/* Discovery 2016 */
|
||||
scsi_ulto2b(0x0001, &sfs_ptr->codes[2 * n++]);
|
||||
if (lun != NULL && lun->be_lun->lun_type == T_DIRECT) {
|
||||
/* SBC Base 2016 */
|
||||
scsi_ulto2b(0x0101, &sfs_ptr->codes[2 * n++]);
|
||||
/* SBC Base 2010 */
|
||||
scsi_ulto2b(0x0102, &sfs_ptr->codes[2 * n++]);
|
||||
if (lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) {
|
||||
/* Basic Provisioning 2016 */
|
||||
scsi_ulto2b(0x0103, &sfs_ptr->codes[2 * n++]);
|
||||
}
|
||||
/* Drive Maintenance 2016 */
|
||||
//scsi_ulto2b(0x0104, &sfs_ptr->codes[2 * n++]);
|
||||
}
|
||||
scsi_ulto2b(4 + 2 * n, sfs_ptr->page_length);
|
||||
|
||||
ctl_set_success(ctsio);
|
||||
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_block_limits(struct ctl_scsiio *ctsio, int alloc_len)
|
||||
{
|
||||
|
|
@ -9811,7 +9867,7 @@ ctl_inquiry_evpd_bdc(struct ctl_scsiio *ctsio, int alloc_len)
|
|||
else
|
||||
i = 0;
|
||||
bdc_ptr->wab_wac_ff = (i & 0x0f);
|
||||
bdc_ptr->flags = SVPD_FUAB | SVPD_VBULS;
|
||||
bdc_ptr->flags = SVPD_RBWZ | SVPD_FUAB | SVPD_VBULS;
|
||||
|
||||
ctl_set_success(ctsio);
|
||||
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
|
||||
|
|
@ -9904,6 +9960,9 @@ ctl_inquiry_evpd(struct ctl_scsiio *ctsio)
|
|||
case SVPD_SCSI_TPC:
|
||||
retval = ctl_inquiry_evpd_tpc(ctsio, alloc_len);
|
||||
break;
|
||||
case SVPD_SCSI_SFS:
|
||||
retval = ctl_inquiry_evpd_sfs(ctsio, alloc_len);
|
||||
break;
|
||||
case SVPD_BLOCK_LIMITS:
|
||||
if (lun == NULL || lun->be_lun->lun_type != T_DIRECT)
|
||||
goto err;
|
||||
|
|
|
|||
|
|
@ -2762,6 +2762,19 @@ struct scsi_vpd_tpc
|
|||
struct scsi_vpd_tpc_descriptor descr[];
|
||||
};
|
||||
|
||||
/*
|
||||
* SCSI Feature Sets VPD Page
|
||||
*/
|
||||
struct scsi_vpd_sfs
|
||||
{
|
||||
uint8_t device;
|
||||
uint8_t page_code;
|
||||
#define SVPD_SCSI_SFS 0x92
|
||||
uint8_t page_length[2];
|
||||
uint8_t reserved[4];
|
||||
uint8_t codes[];
|
||||
};
|
||||
|
||||
/*
|
||||
* Block Device Characteristics VPD Page based on
|
||||
* T10/1799-D Revision 31
|
||||
|
|
@ -2803,11 +2816,15 @@ struct scsi_vpd_block_device_characteristics
|
|||
uint8_t flags;
|
||||
#define SVPD_VBULS 0x01
|
||||
#define SVPD_FUAB 0x02
|
||||
#define SVPD_BOCS 0x04
|
||||
#define SVPD_RBWZ 0x08
|
||||
#define SVPD_ZBC_NR 0x00 /* Not Reported */
|
||||
#define SVPD_HAW_ZBC 0x10 /* Host Aware */
|
||||
#define SVPD_DM_ZBC 0x20 /* Drive Managed */
|
||||
#define SVPD_ZBC_MASK 0x30 /* Zoned mask */
|
||||
uint8_t reserved[55];
|
||||
uint8_t reserved[3];
|
||||
uint8_t depopulation_time[4];
|
||||
uint8_t reserved2[48];
|
||||
};
|
||||
|
||||
#define SBDC_IS_PRESENT(bdc, length, field) \
|
||||
|
|
|
|||
Loading…
Reference in a new issue