From dcab9610fe2e1b87f31711e4413b53e4396696cf Mon Sep 17 00:00:00 2001 From: mav Date: Sat, 12 Jul 2014 02:26:11 +0000 Subject: [PATCH] MFC r267906: Allow MODE SENSE commands through Write Exclusive persistent reservation, as required by SPC-4. Report that fact in persistent reservation capabilities. --- sys/cam/ctl/ctl.c | 20 +++++++++++++++++++- sys/cam/ctl/ctl_cmd_table.c | 6 ++++-- sys/cam/scsi/scsi_all.h | 11 ++++++++++- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index f3ea899e0728..156af67ba8a7 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -6772,6 +6772,24 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) else control_dev = 0; + if (lun->flags & CTL_LUN_PR_RESERVED) { + uint32_t residx; + + /* + * XXX KDM need a lock here. + */ + residx = ctl_get_resindex(&ctsio->io_hdr.nexus); + if ((lun->res_type == SPR_TYPE_EX_AC + && residx != lun->pr_res_idx) + || ((lun->res_type == SPR_TYPE_EX_AC_RO + || lun->res_type == SPR_TYPE_EX_AC_AR) + && !lun->per_res[residx].registered)) { + ctl_set_reservation_conflict(ctsio); + ctl_done((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); + } + } + switch (ctsio->cdb[0]) { case MODE_SENSE_6: { struct scsi_mode_sense_6 *cdb; @@ -7568,7 +7586,7 @@ retry: res_cap = (struct scsi_per_res_cap *)ctsio->kern_data_ptr; scsi_ulto2b(sizeof(*res_cap), res_cap->length); - res_cap->flags2 |= SPRI_TMV; + res_cap->flags2 |= SPRI_TMV | SPRI_ALLOW_3; type_mask = SPRI_TM_WR_EX_AR | SPRI_TM_EX_AC_RO | SPRI_TM_WR_EX_RO | diff --git a/sys/cam/ctl/ctl_cmd_table.c b/sys/cam/ctl/ctl_cmd_table.c index 7729b7e6760f..85bf52d730ab 100644 --- a/sys/cam/ctl/ctl_cmd_table.c +++ b/sys/cam/ctl/ctl_cmd_table.c @@ -192,7 +192,8 @@ struct ctl_cmd_entry ctl_cmd_table[] = CTL_CMD_FLAG_OK_ON_STOPPED | CTL_CMD_FLAG_OK_ON_INOPERABLE | CTL_CMD_FLAG_OK_ON_SECONDARY | - CTL_FLAG_DATA_IN, + CTL_FLAG_DATA_IN | + CTL_CMD_FLAG_ALLOW_ON_PR_RESV, CTL_LUN_PAT_NONE}, /* 1B START STOP UNIT */ @@ -436,7 +437,8 @@ struct ctl_cmd_entry ctl_cmd_table[] = CTL_CMD_FLAG_OK_ON_STOPPED | CTL_CMD_FLAG_OK_ON_INOPERABLE | CTL_CMD_FLAG_OK_ON_SECONDARY | - CTL_FLAG_DATA_IN, + CTL_FLAG_DATA_IN | + CTL_CMD_FLAG_ALLOW_ON_PR_RESV, CTL_LUN_PAT_NONE}, /* 5B CLOSE TRACK/SESSION */ diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h index be681fb6d69f..11a500c5b2b7 100644 --- a/sys/cam/scsi/scsi_all.h +++ b/sys/cam/scsi/scsi_all.h @@ -308,6 +308,11 @@ struct scsi_per_res_cap #define SPRI_PTPL_C 0x01 uint8_t flags2; #define SPRI_TMV 0x80 +#define SPRI_ALLOW_MASK 0x70 +#define SPRI_ALLOW_0 0x00 +#define SPRI_ALLOW_1 0x10 +#define SPRI_ALLOW_2 0x20 +#define SPRI_ALLOW_3 0x30 #define SPRI_PTPL_A 0x01 uint8_t type_mask[2]; #define SPRI_TM_WR_EX_AR 0x8000 @@ -746,12 +751,16 @@ struct scsi_read_buffer { u_int8_t opcode; u_int8_t byte2; -#define RWB_MODE 0x07 +#define RWB_MODE 0x1F #define RWB_MODE_HDR_DATA 0x00 #define RWB_MODE_VENDOR 0x01 #define RWB_MODE_DATA 0x02 +#define RWB_MODE_DESCR 0x03 #define RWB_MODE_DOWNLOAD 0x04 #define RWB_MODE_DOWNLOAD_SAVE 0x05 +#define RWB_MODE_ECHO 0x0A +#define RWB_MODE_ECHO_DESCR 0x0B +#define RWB_MODE_ERROR_HISTORY 0x1C u_int8_t buffer_id; u_int8_t offset[3]; u_int8_t length[3];