summaryrefslogtreecommitdiffstats
path: root/sys/cam/ctl
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2014-11-03 03:44:59 +0000
committermav <mav@FreeBSD.org>2014-11-03 03:44:59 +0000
commit131eff3491079fe85625cc77ef46a79f1b1f9962 (patch)
treeb80a6812600f6497373518d93a46b2d460f3359c /sys/cam/ctl
parent58bf3496235842d014ccc9f806040eaec8ec98ab (diff)
downloadFreeBSD-src-131eff3491079fe85625cc77ef46a79f1b1f9962.zip
FreeBSD-src-131eff3491079fe85625cc77ef46a79f1b1f9962.tar.gz
MFC r273730, r273731:
Reduce code duplication around Write Exclusive persistent reservation. While there, allow some more commands to pass persistent reservation.
Diffstat (limited to 'sys/cam/ctl')
-rw-r--r--sys/cam/ctl/ctl.c94
-rw-r--r--sys/cam/ctl/ctl_cmd_table.c42
-rw-r--r--sys/cam/ctl/ctl_private.h1
3 files changed, 37 insertions, 100 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 4609f28..0dc9d37 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -5343,8 +5343,7 @@ ctl_scsi_reserve(struct ctl_scsiio *ctsio)
mtx_lock(&lun->lun_lock);
if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx != residx)) {
- ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT;
- ctsio->io_hdr.status = CTL_SCSI_ERROR;
+ ctl_set_reservation_conflict(ctsio);
goto bailout;
}
@@ -5695,24 +5694,6 @@ ctl_read_buffer(struct ctl_scsiio *ctsio)
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_read_buffer *)ctsio->cdb;
- 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->pr_keys[residx] == 0)) {
- ctl_set_reservation_conflict(ctsio);
- ctl_done((union ctl_io *)ctsio);
- return (CTL_RETVAL_COMPLETE);
- }
- }
-
if ((cdb->byte2 & RWB_MODE) != RWB_MODE_DATA &&
(cdb->byte2 & RWB_MODE) != RWB_MODE_ECHO_DESCR &&
(cdb->byte2 & RWB_MODE) != RWB_MODE_DESCR) {
@@ -6644,24 +6625,6 @@ 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->pr_keys[residx] == 0)) {
- 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;
@@ -7198,23 +7161,6 @@ ctl_read_defect(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_read_defect\n"));
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
- 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->pr_keys[residx] == 0)) {
- ctl_set_reservation_conflict(ctsio);
- ctl_done((union ctl_io *)ctsio);
- return (CTL_RETVAL_COMPLETE);
- }
- }
if (ctsio->cdb[0] == READ_DEFECT_DATA_10) {
ccb10 = (struct scsi_read_defect_data_10 *)&ctsio->cdb;
@@ -8908,24 +8854,6 @@ ctl_read_write(struct ctl_scsiio *ctsio)
isread = ctsio->cdb[0] == READ_6 || ctsio->cdb[0] == READ_10
|| ctsio->cdb[0] == READ_12 || ctsio->cdb[0] == READ_16;
- if (lun->flags & CTL_LUN_PR_RESERVED && isread) {
- 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->pr_keys[residx] == 0)) {
- ctl_set_reservation_conflict(ctsio);
- ctl_done((union ctl_io *)ctsio);
- return (CTL_RETVAL_COMPLETE);
- }
- }
-
switch (ctsio->cdb[0]) {
case READ_6:
case WRITE_6: {
@@ -11227,27 +11155,29 @@ ctl_scsiio_lun_check(struct ctl_softc *ctl_softc, struct ctl_lun *lun,
if ((lun->flags & CTL_LUN_RESERVED)
&& ((entry->flags & CTL_CMD_FLAG_ALLOW_ON_RESV) == 0)) {
if (lun->res_idx != residx) {
- ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT;
- ctsio->io_hdr.status = CTL_SCSI_ERROR;
+ ctl_set_reservation_conflict(ctsio);
retval = 1;
goto bailout;
}
}
- if ((lun->flags & CTL_LUN_PR_RESERVED)
- && ((entry->flags & CTL_CMD_FLAG_ALLOW_ON_PR_RESV) == 0)) {
+ if ((lun->flags & CTL_LUN_PR_RESERVED) == 0 ||
+ (entry->flags & CTL_CMD_FLAG_ALLOW_ON_PR_RESV)) {
+ /* No reservation or command is allowed. */;
+ } else if ((entry->flags & CTL_CMD_FLAG_ALLOW_ON_PR_WRESV) &&
+ (lun->res_type == SPR_TYPE_WR_EX ||
+ lun->res_type == SPR_TYPE_WR_EX_RO ||
+ lun->res_type == SPR_TYPE_WR_EX_AR)) {
+ /* The command is allowed for Write Exclusive resv. */;
+ } else {
/*
* if we aren't registered or it's a res holder type
* reservation and this isn't the res holder then set a
* conflict.
- * NOTE: Commands which might be allowed on write exclusive
- * type reservations are checked in the particular command
- * for a conflict. Read and SSU are the only ones.
*/
if (lun->pr_keys[residx] == 0
|| (residx != lun->pr_res_idx && lun->res_type < 4)) {
- ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT;
- ctsio->io_hdr.status = CTL_SCSI_ERROR;
+ ctl_set_reservation_conflict(ctsio);
retval = 1;
goto bailout;
}
diff --git a/sys/cam/ctl/ctl_cmd_table.c b/sys/cam/ctl/ctl_cmd_table.c
index a9bd500..0180cec 100644
--- a/sys/cam/ctl/ctl_cmd_table.c
+++ b/sys/cam/ctl/ctl_cmd_table.c
@@ -259,7 +259,8 @@ const struct ctl_cmd_entry ctl_cmd_table_83[32] =
/* 10 POPULATE TOKEN */
{ctl_populate_token, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_SLUN |
- CTL_FLAG_DATA_OUT,
+ CTL_FLAG_DATA_OUT |
+ CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_NONE,
16, { 0x10, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@@ -347,7 +348,8 @@ const struct ctl_cmd_entry ctl_cmd_table_84[32] =
/* 05 RECEIVE COPY STATUS (LID4) */
{ctl_receive_copy_status_lid4, CTL_SERIDX_RD_CAP,
CTL_CMD_FLAG_OK_ON_BOTH |
- CTL_FLAG_DATA_IN,
+ CTL_FLAG_DATA_IN |
+ CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_LUN_PAT_NONE,
16, {0x05, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@@ -357,14 +359,16 @@ const struct ctl_cmd_entry ctl_cmd_table_84[32] =
/* 07 RECEIVE ROD TOKEN INFORMATION */
{ctl_receive_rod_token_information, CTL_SERIDX_RD_CAP,
CTL_CMD_FLAG_OK_ON_BOTH |
- CTL_FLAG_DATA_IN,
+ CTL_FLAG_DATA_IN |
+ CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_LUN_PAT_NONE,
16, {0x07, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
/* 08 REPORT ALL ROD TOKENS */
{ctl_report_all_rod_tokens, CTL_SERIDX_RD_CAP,
CTL_CMD_FLAG_OK_ON_BOTH |
- CTL_FLAG_DATA_IN,
+ CTL_FLAG_DATA_IN |
+ CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_LUN_PAT_NONE,
16, {0x08, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
};
@@ -472,7 +476,8 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
CTL_CMD_FLAG_OK_ON_INOPERABLE |
CTL_CMD_FLAG_OK_ON_OFFLINE |
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,
12, {0x0a, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@@ -510,7 +515,8 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
CTL_CMD_FLAG_OK_ON_INOPERABLE |
CTL_CMD_FLAG_OK_ON_OFFLINE |
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,
12, {0x0f, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@@ -561,7 +567,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* 08 READ(6) */
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_IN |
- CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE, 6, {0x1f, 0xff, 0xff, 0xff, 0x07}},
/* 09 */
@@ -653,7 +659,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN |
- CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_NONE, 6, {0x08, 0xff, 0xff, 0xff, 0x07}},
/* 1B START STOP UNIT */
@@ -710,7 +716,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* 28 READ(10) */
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_IN |
- CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
10, {0x1a, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}},
@@ -739,7 +745,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* 2F VERIFY(10) */
{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_OUT |
- CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
10, {0x16, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}},
@@ -770,7 +776,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* 37 READ DEFECT DATA(10) */
{ctl_read_defect, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_IN |
- CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_NONE,
10, {0, 0x1f, 0, 0, 0, 0, 0xff, 0xff, 0x07}},
@@ -792,7 +798,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* 3C READ BUFFER */
{ctl_read_buffer, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_BOTH |
CTL_FLAG_DATA_IN |
- CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_NONE,
10, {0x1f, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07}},
@@ -918,7 +924,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN |
- CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_NONE, 10, {0x18, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0x07} },
/* 5B CLOSE TRACK/SESSION */
@@ -1062,7 +1068,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* 88 READ(16) */
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN | CTL_FLAG_DATA_IN |
- CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
16, {0x1a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@@ -1097,7 +1103,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* 8F VERIFY(16) */
{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_OUT |
- CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
16, {0x16, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@@ -1199,7 +1205,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* A8 READ(12) */
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN | CTL_FLAG_DATA_IN |
- CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
12, {0x1a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@@ -1228,7 +1234,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* AF VERIFY(12) */
{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_OUT |
- CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
12, {0x16, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@@ -1256,7 +1262,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* B7 READ DEFECT DATA(12) */
{ctl_read_defect, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_IN |
- CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_NONE,
12, {0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h
index bb9a32d..e3dcf70 100644
--- a/sys/cam/ctl/ctl_private.h
+++ b/sys/cam/ctl/ctl_private.h
@@ -144,6 +144,7 @@ typedef enum {
CTL_CMD_FLAG_NO_SENSE = 0x0010,
CTL_CMD_FLAG_OK_ON_ALL_LUNS = 0x0020,
CTL_CMD_FLAG_ALLOW_ON_RESV = 0x0040,
+ CTL_CMD_FLAG_ALLOW_ON_PR_WRESV = 0x0080,
CTL_CMD_FLAG_OK_ON_PROC = 0x0100,
CTL_CMD_FLAG_OK_ON_SLUN = 0x0200,
CTL_CMD_FLAG_OK_ON_BOTH = 0x0300,
OpenPOWER on IntegriCloud