Rather than re-using the failed command the snic driver should reserve one command for TMFs. Signed-off-by: Hannes Reinecke <hare@xxxxxxxx> --- drivers/scsi/snic/snic.h | 3 ++- drivers/scsi/snic/snic_main.c | 3 +++ drivers/scsi/snic/snic_scsi.c | 51 +++++++++++++++-------------------- 3 files changed, 26 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/snic/snic.h b/drivers/scsi/snic/snic.h index f4c666285bba..f88ecf73f708 100644 --- a/drivers/scsi/snic/snic.h +++ b/drivers/scsi/snic/snic.h @@ -310,6 +310,7 @@ struct snic { struct list_head spl_cmd_list; unsigned int max_tag_id; + unsigned int tmf_tag_id; atomic_t ios_inflight; /* io in flight counter */ struct vnic_snic_config config; @@ -380,7 +381,7 @@ int snic_queuecommand(struct Scsi_Host *, struct scsi_cmnd *); int snic_abort_cmd(struct scsi_cmnd *); int snic_device_reset(struct scsi_cmnd *); int snic_host_reset(struct scsi_cmnd *); -int snic_reset(struct Scsi_Host *, struct scsi_cmnd *); +int snic_reset(struct Scsi_Host *); void snic_shutdown_scsi_cleanup(struct snic *); diff --git a/drivers/scsi/snic/snic_main.c b/drivers/scsi/snic/snic_main.c index 14f4ce665e58..65f50057c66e 100644 --- a/drivers/scsi/snic/snic_main.c +++ b/drivers/scsi/snic/snic_main.c @@ -512,6 +512,9 @@ snic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) max_t(u32, SNIC_MIN_IO_REQ, max_ios)); snic->max_tag_id = shost->can_queue; + /* Reserve one reset command */ + shost->can_queue--; + snic->tmf_tag_id = shost->can_queue; shost->max_lun = snic->config.luns_per_tgt; shost->max_id = SNIC_MAX_TARGET; diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c index 6dd0ff188bb4..1e59d59130d6 100644 --- a/drivers/scsi/snic/snic_scsi.c +++ b/drivers/scsi/snic/snic_scsi.c @@ -1021,17 +1021,6 @@ snic_hba_reset_cmpl_handler(struct snic *snic, struct snic_fw_req *fwreq) "reset_cmpl: type = %x, hdr_stat = %x, cmnd_id = %x, hid = %x, ctx = %lx\n", typ, hdr_stat, cmnd_id, hid, ctx); - /* spl case, host reset issued through ioctl */ - if (cmnd_id == SCSI_NO_TAG) { - rqi = (struct snic_req_info *) ctx; - SNIC_HOST_INFO(snic->shost, - "reset_cmpl:Tag %d ctx %lx cmpl stat %s\n", - cmnd_id, ctx, snic_io_status_to_str(hdr_stat)); - sc = rqi->sc; - - goto ioctl_hba_rst; - } - if (cmnd_id >= snic->max_tag_id) { SNIC_HOST_ERR(snic->shost, "reset_cmpl: Tag 0x%x out of Range,HdrStat %s\n", @@ -1042,7 +1031,6 @@ snic_hba_reset_cmpl_handler(struct snic *snic, struct snic_fw_req *fwreq) } sc = scsi_host_find_tag(snic->shost, cmnd_id); -ioctl_hba_rst: if (!sc) { atomic64_inc(&snic->s_stats.io.sc_null); SNIC_HOST_ERR(snic->shost, @@ -1728,7 +1716,7 @@ snic_dr_clean_single_req(struct snic *snic, { struct snic_req_info *rqi = NULL; struct snic_tgt *tgt = NULL; - struct scsi_cmnd *sc = NULL; + struct scsi_cmnd *sc; spinlock_t *io_lock = NULL; u32 sv_state = 0, tmf = 0; DECLARE_COMPLETION_ONSTACK(tm_done); @@ -2241,13 +2229,6 @@ snic_issue_hba_reset(struct snic *snic, struct scsi_cmnd *sc) goto hba_rst_end; } - if (snic_cmd_tag(sc) == SCSI_NO_TAG) { - memset(scsi_cmd_priv(sc), 0, - sizeof(struct snic_internal_io_state)); - SNIC_HOST_INFO(snic->shost, "issu_hr:Host reset thru ioctl.\n"); - rqi->sc = sc; - } - req = rqi_to_req(rqi); io_lock = snic_io_lock_hash(snic, sc); @@ -2322,11 +2303,13 @@ snic_issue_hba_reset(struct snic *snic, struct scsi_cmnd *sc) } /* end of snic_issue_hba_reset */ int -snic_reset(struct Scsi_Host *shost, struct scsi_cmnd *sc) +snic_reset(struct Scsi_Host *shost) { struct snic *snic = shost_priv(shost); + struct scsi_cmnd *sc = NULL; enum snic_state sv_state; unsigned long flags; + u32 start_time = jiffies; int ret = FAILED; /* Set snic state as SNIC_FWRESET*/ @@ -2351,6 +2334,18 @@ snic_reset(struct Scsi_Host *shost, struct scsi_cmnd *sc) while (atomic_read(&snic->ios_inflight)) schedule_timeout(msecs_to_jiffies(1)); + sc = scsi_host_find_tag(shost, snic->tmf_tag_id); + if (!sc) { + SNIC_HOST_ERR(shost, + "reset:Host Reset Failed to allocate sc.\n"); + spin_lock_irqsave(&snic->snic_lock, flags); + snic_set_state(snic, sv_state); + spin_unlock_irqrestore(&snic->snic_lock, flags); + atomic64_inc(&snic->s_stats.reset.hba_reset_fail); + ret = FAILED; + + goto reset_end; + } ret = snic_issue_hba_reset(snic, sc); if (ret) { SNIC_HOST_ERR(shost, @@ -2368,6 +2363,10 @@ snic_reset(struct Scsi_Host *shost, struct scsi_cmnd *sc) ret = SUCCESS; reset_end: + SNIC_TRC(shost->host_no, sc ? snic_cmd_tag(sc) : SCSI_NO_TAG, + (ulong) sc, jiffies_to_msecs(jiffies - start_time), + 0, 0, 0); + return ret; } /* end of snic_reset */ @@ -2382,21 +2381,13 @@ int snic_host_reset(struct scsi_cmnd *sc) { struct Scsi_Host *shost = sc->device->host; - u32 start_time = jiffies; - int ret = FAILED; SNIC_SCSI_DBG(shost, "host reset:sc %p sc_cmd 0x%x req %p tag %d flags 0x%llx\n", sc, sc->cmnd[0], sc->request, snic_cmd_tag(sc), CMD_FLAGS(sc)); - ret = snic_reset(shost, sc); - - SNIC_TRC(shost->host_no, snic_cmd_tag(sc), (ulong) sc, - jiffies_to_msecs(jiffies - start_time), - 0, SNIC_TRC_CMD(sc), SNIC_TRC_CMD_STATE_FLAGS(sc)); - - return ret; + return snic_reset(shost); } /* end of snic_host_reset */ /* -- 2.29.2