aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/cam/ctl/ctl.c20
-rw-r--r--sys/cam/ctl/ctl_cmd_table.c6
-rw-r--r--sys/cam/scsi/scsi_all.h11
3 files changed, 33 insertions, 4 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 7438e79f9999..e8b7a5696dc2 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -6672,6 +6672,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;
@@ -7465,7 +7483,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 43ad742fe4a8..dbaa3c86d07c 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];