diff --git a/drivers/scsi/sssraid/sssraid.h b/drivers/scsi/sssraid/sssraid.h index f2a5979361187a43d99e6e696fb8cebf9f3da0cd..7fe485524da7a71b2456efb5fe8c780a00b13312 100644 --- a/drivers/scsi/sssraid/sssraid.h +++ b/drivers/scsi/sssraid/sssraid.h @@ -58,7 +58,8 @@ #define SSSRAID_ADM_QUEUE_NUM 1 #define SSSRAID_PTCMDS_PERQ 1 #define SSSRAID_IO_BLK_MQ_DEPTH (sdioc->scsi_qd) -#define SSSRAID_NR_IOQ_PTCMDS (SSSRAID_PTCMDS_PERQ * sdioc->shost->nr_hw_queues) +#define SSSRAID_NR_HW_QUEUES (sdioc->init_done_queue_cnt - 1) +#define SSSRAID_NR_IOQ_PTCMDS (SSSRAID_PTCMDS_PERQ * SSSRAID_NR_HW_QUEUES) #define FUA_MASK 0x08 #define SSSRAID_MINORS BIT(MINORBITS) diff --git a/drivers/scsi/sssraid/sssraid_fw.c b/drivers/scsi/sssraid/sssraid_fw.c index 6f553003e19f9a5ce37bbe5aa6bb7c7a885ee972..440b50fd5689341ab879731d0872d55ef13d55d1 100644 --- a/drivers/scsi/sssraid/sssraid_fw.c +++ b/drivers/scsi/sssraid/sssraid_fw.c @@ -1316,7 +1316,7 @@ int sssraid_init_ioc(struct sssraid_ioc *sdioc, u8 re_init) /* num_vecs no sense, abandon */ if (!re_init) { - for (i = sdioc->init_done_queue_cnt; i <= sdioc->intr_info_count; i++) { + for (i = sdioc->init_done_queue_cnt; i < sdioc->intr_info_count; i++) { retval = sssraid_alloc_qpair(sdioc, i, sdioc->ioq_depth); if (retval) { ioc_err(sdioc, "Failed to alloc io queue:error %d\n", @@ -1631,27 +1631,30 @@ void sssraid_complete_cqes(struct sssraid_ioc *sdioc, u16 midx, u16 start, u16 e } } -static void sssraid_disable_admin_queue(struct sssraid_ioc *sdioc, bool shutdown) +static int sssraid_disable_admin_queue(struct sssraid_ioc *sdioc, bool shutdown) { struct sssraid_cqueue *adm_cqinfo = &sdioc->cqinfo[0]; u16 start, end; + int ret = 0; if (pci_device_is_present(sdioc->pdev)) { if (shutdown) sssraid_shutdown_ctrl(sdioc); else - sssraid_disable_ctrl(sdioc); + ret = sssraid_disable_ctrl(sdioc); } if (sdioc->init_done_queue_cnt == 0) { ioc_err(sdioc, "err: admin queue has been delete\n"); - return; + return -ENODEV; } spin_lock_irq(&adm_cqinfo->cq_lock); sssraid_process_cq(sdioc, 0, &start, &end, -1); spin_unlock_irq(&adm_cqinfo->cq_lock); sssraid_complete_cqes(sdioc, 0, start, end); + + return ret; } static void sssraid_free_all_queues(struct sssraid_ioc *sdioc) @@ -1722,29 +1725,38 @@ int sssraid_soft_reset_handler(struct sssraid_ioc *sdioc) ioc_info(sdioc, "host reset entry\n"); - sssraid_ioc_disable_intr(sdioc); sssraid_cleanup_fwevt_list(sdioc); - /* realize above here: - * sssraid_dev_disable -> sssraid_back_all_io - */ - sssraid_back_all_io(sdioc); /* * realize sssraid_dev_disable, * i.e. sssraid_cleanup_ioc(1) */ if (sdioc->ctrl_config & SSSRAID_CC_ENABLE) { - ioc_info(sdioc, "start cleanup ioc\n"); - sssraid_cleanup_ioc(sdioc, 1); + ioc_info(sdioc, "start disable admin queue\n"); + retval = sssraid_disable_admin_queue(sdioc, 0); } + sssraid_cleanup_resources(sdioc); + + /* realize above here: + * sssraid_dev_disable -> sssraid_back_all_io + */ + sssraid_back_all_io(sdioc); + + if (retval) + goto host_reset_failed; + retval = sssraid_init_ioc(sdioc, 1); - if (retval) { - ioc_err(sdioc, "err: init ioc fail.\n"); - return retval; - } + if (retval) + goto cleanup_resources; sssraid_change_host_state(sdioc, SSSRAID_LIVE); + return 0; +cleanup_resources: + sssraid_cleanup_resources(sdioc); +host_reset_failed: + sssraid_change_host_state(sdioc, SSSRAID_DEAD); + ioc_err(sdioc, "err, host reset failed\n"); return retval; } diff --git a/drivers/scsi/sssraid/sssraid_os.c b/drivers/scsi/sssraid/sssraid_os.c index 45542dc0e0e1c4203548ba2d1389e64d14d72fd5..6b8f143190d17f68f7363dc14fed6ee258bfa7c2 100644 --- a/drivers/scsi/sssraid/sssraid_os.c +++ b/drivers/scsi/sssraid/sssraid_os.c @@ -566,7 +566,7 @@ static void sssraid_shost_init(struct sssraid_ioc *sdioc) bus = pdev->bus->number; dev_func = pdev->devfn; - sdioc->shost->nr_hw_queues = sdioc->init_done_queue_cnt - 1; + sdioc->shost->nr_hw_queues = SSSRAID_NR_HW_QUEUES; sdioc->shost->can_queue = (sdioc->ioq_depth - SSSRAID_PTCMDS_PERQ); sdioc->shost->sg_tablesize = le16_to_cpu(sdioc->ctrl_info->max_num_sge);