diff options
author | mav <mav@FreeBSD.org> | 2014-07-08 16:38:05 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2014-07-08 16:38:05 +0000 |
commit | 5f1a6650c51565661c3059ced7251b55598b62ba (patch) | |
tree | 93f67b578d77786015296c7ad94fdfb58fe21ee7 | |
parent | b33aba701f3e20bdef20cfd65eb99d3959728c0c (diff) | |
download | FreeBSD-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.c | 41 | ||||
-rw-r--r-- | sys/cam/ctl/ctl_error.c | 12 | ||||
-rw-r--r-- | sys/cam/ctl/ctl_error.h | 1 | ||||
-rw-r--r-- | sys/cam/ctl/ctl_frontend_iscsi.c | 3 | ||||
-rw-r--r-- | sys/cam/ctl/ctl_io.h | 1 | ||||
-rw-r--r-- | sys/cam/ctl/scsi_ctl.c | 3 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_all.h | 11 |
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 { |