summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2014-07-08 16:38:05 +0000
committermav <mav@FreeBSD.org>2014-07-08 16:38:05 +0000
commit5f1a6650c51565661c3059ced7251b55598b62ba (patch)
tree93f67b578d77786015296c7ad94fdfb58fe21ee7
parentb33aba701f3e20bdef20cfd65eb99d3959728c0c (diff)
downloadFreeBSD-src-5f1a6650c51565661c3059ced7251b55598b62ba.zip
FreeBSD-src-5f1a6650c51565661c3059ced7251b55598b62ba.tar.gz
Enable TAS feature: notify initiator if its command was aborted by other.
That should make operation more kind to multi-initiator environment. Without this, other initiators may find out that something bad happened to their commands only via command timeout.
-rw-r--r--sys/cam/ctl/ctl.c41
-rw-r--r--sys/cam/ctl/ctl_error.c12
-rw-r--r--sys/cam/ctl/ctl_error.h1
-rw-r--r--sys/cam/ctl/ctl_frontend_iscsi.c3
-rw-r--r--sys/cam/ctl/ctl_io.h1
-rw-r--r--sys/cam/ctl/scsi_ctl.c3
-rw-r--r--sys/cam/scsi/scsi_all.h11
7 files changed, 55 insertions, 17 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index f65ec7e..2d9a8d8 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -282,8 +282,10 @@ static struct scsi_control_page control_page_default = {
/*rlec*/0,
/*queue_flags*/0,
/*eca_and_aen*/0,
- /*reserved*/0,
- /*aen_holdoff_period*/{0, 0}
+ /*flags4*/SCP_TAS,
+ /*aen_holdoff_period*/{0, 0},
+ /*busy_timeout_period*/{0, 0},
+ /*extended_selftest_completion_time*/{0, 0}
};
static struct scsi_control_page control_page_changeable = {
@@ -292,8 +294,10 @@ static struct scsi_control_page control_page_changeable = {
/*rlec*/SCP_DSENSE,
/*queue_flags*/0,
/*eca_and_aen*/0,
- /*reserved*/0,
- /*aen_holdoff_period*/{0, 0}
+ /*flags4*/0,
+ /*aen_holdoff_period*/{0, 0},
+ /*busy_timeout_period*/{0, 0},
+ /*extended_selftest_completion_time*/{0, 0}
};
@@ -7576,7 +7580,7 @@ ctl_report_supported_tmf(struct ctl_scsiio *ctsio)
ctsio->kern_rel_offset = 0;
data = (struct scsi_report_supported_tmf_data *)ctsio->kern_data_ptr;
- data->byte1 |= RST_ATS | RST_ATSS | RST_LURS | RST_TRS;
+ data->byte1 |= RST_ATS | RST_ATSS | RST_CTSS | RST_LURS | RST_TRS;
data->byte2 |= RST_ITNRS;
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
@@ -11793,7 +11797,7 @@ ctl_lun_reset(struct ctl_lun *lun, union ctl_io *io, ctl_ua_type ua_type)
#endif
for (xio = (union ctl_io *)TAILQ_FIRST(&lun->ooa_queue); xio != NULL;
xio = (union ctl_io *)TAILQ_NEXT(&xio->io_hdr, ooa_links)) {
- xio->io_hdr.flags |= CTL_FLAG_ABORT;
+ xio->io_hdr.flags |= CTL_FLAG_ABORT | CTL_FLAG_ABORT_STATUS;
}
/*
@@ -11846,8 +11850,13 @@ ctl_abort_tasks_lun(struct ctl_lun *lun, uint32_t targ_port, uint32_t init_id,
for (xio = (union ctl_io *)TAILQ_FIRST(&lun->ooa_queue); xio != NULL;
xio = (union ctl_io *)TAILQ_NEXT(&xio->io_hdr, ooa_links)) {
- if ((targ_port == xio->io_hdr.nexus.targ_port) &&
- (init_id == xio->io_hdr.nexus.initid.id)) {
+ if ((targ_port == UINT32_MAX ||
+ targ_port == xio->io_hdr.nexus.targ_port) &&
+ (init_id == UINT32_MAX ||
+ init_id == xio->io_hdr.nexus.initid.id)) {
+ if (targ_port != xio->io_hdr.nexus.targ_port ||
+ init_id != xio->io_hdr.nexus.initid.id)
+ xio->io_hdr.flags |= CTL_FLAG_ABORT_STATUS;
xio->io_hdr.flags |= CTL_FLAG_ABORT;
found = 1;
if (!other_sc && !(lun->flags & CTL_LUN_PRIMARY_SC)) {
@@ -11889,9 +11898,14 @@ ctl_abort_task_set(union ctl_io *io)
mtx_lock(&lun->lun_lock);
mtx_unlock(&softc->ctl_lock);
- ctl_abort_tasks_lun(lun, io->io_hdr.nexus.targ_port,
- io->io_hdr.nexus.initid.id,
- (io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC) != 0);
+ if (io->taskio.task_action == CTL_TASK_ABORT_TASK_SET) {
+ ctl_abort_tasks_lun(lun, io->io_hdr.nexus.targ_port,
+ io->io_hdr.nexus.initid.id,
+ (io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC) != 0);
+ } else { /* CTL_TASK_CLEAR_TASK_SET */
+ ctl_abort_tasks_lun(lun, UINT32_MAX, UINT32_MAX,
+ (io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC) != 0);
+ }
mtx_unlock(&lun->lun_lock);
return (0);
}
@@ -12111,12 +12125,11 @@ ctl_run_task(union ctl_io *io)
retval = ctl_abort_task(io);
break;
case CTL_TASK_ABORT_TASK_SET:
+ case CTL_TASK_CLEAR_TASK_SET:
retval = ctl_abort_task_set(io);
break;
case CTL_TASK_CLEAR_ACA:
break;
- case CTL_TASK_CLEAR_TASK_SET:
- break;
case CTL_TASK_I_T_NEXUS_RESET:
retval = ctl_i_t_nexus_reset(io);
break;
@@ -13474,7 +13487,7 @@ ctl_process_done(union ctl_io *io)
* whatever it needs to do to clean up its state.
*/
if (io->io_hdr.flags & CTL_FLAG_ABORT)
- io->io_hdr.status = CTL_CMD_ABORTED;
+ ctl_set_task_aborted(&io->scsiio);
/*
* We print out status for every task management command. For SCSI
diff --git a/sys/cam/ctl/ctl_error.c b/sys/cam/ctl/ctl_error.c
index 2109259..6ecb54b 100644
--- a/sys/cam/ctl/ctl_error.c
+++ b/sys/cam/ctl/ctl_error.c
@@ -795,6 +795,18 @@ ctl_set_busy(struct ctl_scsiio *ctsio)
}
void
+ctl_set_task_aborted(struct ctl_scsiio *ctsio)
+{
+ struct scsi_sense_data *sense;
+
+ sense = &ctsio->sense_data;
+ memset(sense, 0, sizeof(*sense));
+ ctsio->scsi_status = SCSI_STATUS_TASK_ABORTED;
+ ctsio->sense_len = 0;
+ ctsio->io_hdr.status = CTL_CMD_ABORTED;
+}
+
+void
ctl_set_success(struct ctl_scsiio *ctsio)
{
struct scsi_sense_data *sense;
diff --git a/sys/cam/ctl/ctl_error.h b/sys/cam/ctl/ctl_error.h
index 1d8bd9b..62596d0 100644
--- a/sys/cam/ctl/ctl_error.h
+++ b/sys/cam/ctl/ctl_error.h
@@ -80,6 +80,7 @@ void ctl_set_data_phase_error(struct ctl_scsiio *ctsio);
void ctl_set_reservation_conflict(struct ctl_scsiio *ctsio);
void ctl_set_queue_full(struct ctl_scsiio *ctsio);
void ctl_set_busy(struct ctl_scsiio *ctsio);
+void ctl_set_task_aborted(struct ctl_scsiio *ctsio);
void ctl_set_success(struct ctl_scsiio *ctsio);
#endif /* _CTL_ERROR_H_ */
diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c
index 406e625..beecdd9 100644
--- a/sys/cam/ctl/ctl_frontend_iscsi.c
+++ b/sys/cam/ctl/ctl_frontend_iscsi.c
@@ -2702,7 +2702,8 @@ cfiscsi_scsi_command_done(union ctl_io *io)
* Do not return status for aborted commands.
* There are exceptions, but none supported by CTL yet.
*/
- if (io->io_hdr.status == CTL_CMD_ABORTED) {
+ if (io->io_hdr.status == CTL_CMD_ABORTED &&
+ (io->io_hdr.flags & CTL_FLAG_ABORT_STATUS) == 0) {
ctl_free_io(io);
icl_pdu_free(request);
return;
diff --git a/sys/cam/ctl/ctl_io.h b/sys/cam/ctl/ctl_io.h
index af7876f..2e40665 100644
--- a/sys/cam/ctl/ctl_io.h
+++ b/sys/cam/ctl/ctl_io.h
@@ -96,6 +96,7 @@ typedef enum {
CTL_FLAG_CONTROL_DEV = 0x00000080, /* processor device */
CTL_FLAG_ALLOCATED = 0x00000100, /* data space allocated */
CTL_FLAG_BLOCKED = 0x00000200, /* on the blocked queue */
+ CTL_FLAG_ABORT_STATUS = 0x00000400, /* return TASK ABORTED status */
CTL_FLAG_ABORT = 0x00000800, /* this I/O should be aborted */
CTL_FLAG_DMA_INPROG = 0x00001000, /* DMA in progress */
CTL_FLAG_NO_DATASYNC = 0x00002000, /* don't cache flush data */
diff --git a/sys/cam/ctl/scsi_ctl.c b/sys/cam/ctl/scsi_ctl.c
index bb567de..cd3524a 100644
--- a/sys/cam/ctl/scsi_ctl.c
+++ b/sys/cam/ctl/scsi_ctl.c
@@ -805,7 +805,8 @@ ctlfestart(struct cam_periph *periph, union ccb *start_ccb)
scsi_status = SCSI_STATUS_BUSY;
csio->sense_len = 0;
} else if ((io->io_hdr.status & CTL_STATUS_MASK) ==
- CTL_CMD_ABORTED) {
+ CTL_CMD_ABORTED &&
+ (io->io_hdr.flags & CTL_FLAG_ABORT_STATUS) == 0) {
io->io_hdr.flags &= ~CTL_FLAG_STATUS_QUEUED;
/*
diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h
index c0f3aad..8ffbd82 100644
--- a/sys/cam/scsi/scsi_all.h
+++ b/sys/cam/scsi/scsi_all.h
@@ -630,15 +630,24 @@ struct scsi_control_page {
#define SCP_QUEUE_ALG_MASK 0xF0
#define SCP_QUEUE_ALG_RESTRICTED 0x00
#define SCP_QUEUE_ALG_UNRESTRICTED 0x10
+#define SCP_NUAR 0x08 /*No UA on release*/
#define SCP_QUEUE_ERR 0x02 /*Queued I/O aborted for CACs*/
#define SCP_QUEUE_DQUE 0x01 /*Queued I/O disabled*/
u_int8_t eca_and_aen;
#define SCP_EECA 0x80 /*Enable Extended CA*/
+#define SCP_RAC 0x40 /*Report a check*/
+#define SCP_SWP 0x08 /*Software Write Protect*/
#define SCP_RAENP 0x04 /*Ready AEN Permission*/
#define SCP_UAAENP 0x02 /*UA AEN Permission*/
#define SCP_EAENP 0x01 /*Error AEN Permission*/
- u_int8_t reserved;
+ u_int8_t flags4;
+#define SCP_ATO 0x80 /*Application tag owner*/
+#define SCP_TAS 0x40 /*Task aborted status*/
+#define SCP_ATMPE 0x20 /*Application tag mode page*/
+#define SCP_RWWP 0x10 /*Reject write without prot*/
u_int8_t aen_holdoff_period[2];
+ u_int8_t busy_timeout_period[2];
+ u_int8_t extended_selftest_completion_time[2];
};
struct scsi_cache_page {
OpenPOWER on IntegriCloud