diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-04-03 03:03:53 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-04-03 03:03:53 +0300 |
commit | 79f51b7b9c4719303f758ae8406c4e5997ed6aa3 (patch) | |
tree | 33ca1c3ee11848e75d90f811038fcd149e69d258 /drivers/scsi/aacraid/linit.c | |
parent | e109f506074152b7241bcbd3949a099e776cb802 (diff) | |
parent | ff275db92c935858454b721f0d960fff421634d3 (diff) | |
download | linux-79f51b7b9c4719303f758ae8406c4e5997ed6aa3.tar.xz |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This series has a huge amount of churn because it pulls in Mauro's doc
update changing all our txt files to rst ones.
Excluding that, we have the usual driver updates (qla2xxx, ufs, lpfc,
zfcp, ibmvfc, pm80xx, aacraid), a treewide update for scnprintf and
some other minor updates.
The major core change is Hannes moving functions out of the aacraid
driver and into the core"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (223 commits)
scsi: aic7xxx: aic97xx: Remove FreeBSD-specific code
scsi: ufs: Do not rely on prefetched data
scsi: dc395x: remove dc395x_bios_param
scsi: libiscsi: Fix error count for active session
scsi: hpsa: correct race condition in offload enabled
scsi: message: fusion: Replace zero-length array with flexible-array member
scsi: qedi: Add PCI shutdown handler support
scsi: qedi: Add MFW error recovery process
scsi: ufs: Enable block layer runtime PM for well-known logical units
scsi: ufs-qcom: Override devfreq parameters
scsi: ufshcd: Let vendor override devfreq parameters
scsi: ufshcd: Update the set frequency to devfreq
scsi: ufs: Resume ufs host before accessing ufs device
scsi: ufs-mediatek: customize the delay for enabling host
scsi: ufs: make HCE polling more compact to improve initialization latency
scsi: ufs: allow custom delay prior to host enabling
scsi: ufs-mediatek: use common delay function
scsi: ufs: introduce common and flexible delay function
scsi: ufs: use an enum for host capabilities
scsi: ufs: fix uninitialized tx_lanes in ufshcd_disable_tx_lcc()
...
Diffstat (limited to 'drivers/scsi/aacraid/linit.c')
-rw-r--r-- | drivers/scsi/aacraid/linit.c | 171 |
1 files changed, 83 insertions, 88 deletions
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 0443b74390cf..83a60b0a8cd8 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -623,54 +623,56 @@ static int aac_ioctl(struct scsi_device *sdev, unsigned int cmd, return aac_do_ioctl(dev, cmd, arg); } -static int get_num_of_incomplete_fibs(struct aac_dev *aac) +struct fib_count_data { + int mlcnt; + int llcnt; + int ehcnt; + int fwcnt; + int krlcnt; +}; + +static bool fib_count_iter(struct scsi_cmnd *scmnd, void *data, bool reserved) { + struct fib_count_data *fib_count = data; - unsigned long flags; - struct scsi_device *sdev = NULL; + switch (scmnd->SCp.phase) { + case AAC_OWNER_FIRMWARE: + fib_count->fwcnt++; + break; + case AAC_OWNER_ERROR_HANDLER: + fib_count->ehcnt++; + break; + case AAC_OWNER_LOWLEVEL: + fib_count->llcnt++; + break; + case AAC_OWNER_MIDLEVEL: + fib_count->mlcnt++; + break; + default: + fib_count->krlcnt++; + break; + } + return true; +} + +/* Called during SCSI EH, so we don't need to block requests */ +static int get_num_of_incomplete_fibs(struct aac_dev *aac) +{ struct Scsi_Host *shost = aac->scsi_host_ptr; - struct scsi_cmnd *scmnd = NULL; struct device *ctrl_dev; + struct fib_count_data fcnt = { }; - int mlcnt = 0; - int llcnt = 0; - int ehcnt = 0; - int fwcnt = 0; - int krlcnt = 0; - - __shost_for_each_device(sdev, shost) { - spin_lock_irqsave(&sdev->list_lock, flags); - list_for_each_entry(scmnd, &sdev->cmd_list, list) { - switch (scmnd->SCp.phase) { - case AAC_OWNER_FIRMWARE: - fwcnt++; - break; - case AAC_OWNER_ERROR_HANDLER: - ehcnt++; - break; - case AAC_OWNER_LOWLEVEL: - llcnt++; - break; - case AAC_OWNER_MIDLEVEL: - mlcnt++; - break; - default: - krlcnt++; - break; - } - } - spin_unlock_irqrestore(&sdev->list_lock, flags); - } + scsi_host_busy_iter(shost, fib_count_iter, &fcnt); ctrl_dev = &aac->pdev->dev; - dev_info(ctrl_dev, "outstanding cmd: midlevel-%d\n", mlcnt); - dev_info(ctrl_dev, "outstanding cmd: lowlevel-%d\n", llcnt); - dev_info(ctrl_dev, "outstanding cmd: error handler-%d\n", ehcnt); - dev_info(ctrl_dev, "outstanding cmd: firmware-%d\n", fwcnt); - dev_info(ctrl_dev, "outstanding cmd: kernel-%d\n", krlcnt); + dev_info(ctrl_dev, "outstanding cmd: midlevel-%d\n", fcnt.mlcnt); + dev_info(ctrl_dev, "outstanding cmd: lowlevel-%d\n", fcnt.llcnt); + dev_info(ctrl_dev, "outstanding cmd: error handler-%d\n", fcnt.ehcnt); + dev_info(ctrl_dev, "outstanding cmd: firmware-%d\n", fcnt.fwcnt); + dev_info(ctrl_dev, "outstanding cmd: kernel-%d\n", fcnt.krlcnt); - return mlcnt + llcnt + ehcnt + fwcnt; + return fcnt.mlcnt + fcnt.llcnt + fcnt.ehcnt + fcnt.fwcnt; } static int aac_eh_abort(struct scsi_cmnd* cmd) @@ -732,7 +734,11 @@ static int aac_eh_abort(struct scsi_cmnd* cmd) status = aac_hba_send(HBA_IU_TYPE_SCSI_TM_REQ, fib, (fib_callback) aac_hba_callback, (void *) cmd); - + if (status != -EINPROGRESS) { + aac_fib_complete(fib); + aac_fib_free(fib); + return ret; + } /* Wait up to 15 secs for completion */ for (count = 0; count < 15; ++count) { if (cmd->SCp.sent_command) { @@ -911,11 +917,11 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd) info = &aac->hba_map[bus][cid]; - if (info->devtype != AAC_DEVTYPE_NATIVE_RAW && - info->reset_state > 0) + if (!(info->devtype == AAC_DEVTYPE_NATIVE_RAW && + !(info->reset_state > 0))) return FAILED; - pr_err("%s: Host adapter reset request. SCSI hang ?\n", + pr_err("%s: Host device reset request. SCSI hang ?\n", AAC_DRIVERNAME); fib = aac_fib_alloc(aac); @@ -930,7 +936,12 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd) status = aac_hba_send(command, fib, (fib_callback) aac_tmf_callback, (void *) info); - + if (status != -EINPROGRESS) { + info->reset_state = 0; + aac_fib_complete(fib); + aac_fib_free(fib); + return ret; + } /* Wait up to 15 seconds for completion */ for (count = 0; count < 15; ++count) { if (info->reset_state == 0) { @@ -969,11 +980,11 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd) info = &aac->hba_map[bus][cid]; - if (info->devtype != AAC_DEVTYPE_NATIVE_RAW && - info->reset_state > 0) + if (!(info->devtype == AAC_DEVTYPE_NATIVE_RAW && + !(info->reset_state > 0))) return FAILED; - pr_err("%s: Host adapter reset request. SCSI hang ?\n", + pr_err("%s: Host target reset request. SCSI hang ?\n", AAC_DRIVERNAME); fib = aac_fib_alloc(aac); @@ -990,6 +1001,13 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd) (fib_callback) aac_tmf_callback, (void *) info); + if (status != -EINPROGRESS) { + info->reset_state = 0; + aac_fib_complete(fib); + aac_fib_free(fib); + return ret; + } + /* Wait up to 15 seconds for completion */ for (count = 0; count < 15; ++count) { if (info->reset_state <= 0) { @@ -1042,7 +1060,7 @@ static int aac_eh_bus_reset(struct scsi_cmnd* cmd) } } - pr_err("%s: Host adapter reset request. SCSI hang ?\n", AAC_DRIVERNAME); + pr_err("%s: Host bus reset request. SCSI hang ?\n", AAC_DRIVERNAME); /* * Check the health of the controller @@ -1270,20 +1288,21 @@ static ssize_t aac_show_flags(struct device *cdev, if (nblank(dprintk(x))) len = snprintf(buf, PAGE_SIZE, "dprintk\n"); #ifdef AAC_DETAILED_STATUS_INFO - len += snprintf(buf + len, PAGE_SIZE - len, - "AAC_DETAILED_STATUS_INFO\n"); + len += scnprintf(buf + len, PAGE_SIZE - len, + "AAC_DETAILED_STATUS_INFO\n"); #endif if (dev->raw_io_interface && dev->raw_io_64) - len += snprintf(buf + len, PAGE_SIZE - len, - "SAI_READ_CAPACITY_16\n"); + len += scnprintf(buf + len, PAGE_SIZE - len, + "SAI_READ_CAPACITY_16\n"); if (dev->jbod) - len += snprintf(buf + len, PAGE_SIZE - len, "SUPPORTED_JBOD\n"); + len += scnprintf(buf + len, PAGE_SIZE - len, + "SUPPORTED_JBOD\n"); if (dev->supplement_adapter_info.supported_options2 & AAC_OPTION_POWER_MANAGEMENT) - len += snprintf(buf + len, PAGE_SIZE - len, - "SUPPORTED_POWER_MANAGEMENT\n"); + len += scnprintf(buf + len, PAGE_SIZE - len, + "SUPPORTED_POWER_MANAGEMENT\n"); if (dev->msi) - len += snprintf(buf + len, PAGE_SIZE - len, "PCI_HAS_MSI\n"); + len += scnprintf(buf + len, PAGE_SIZE - len, "PCI_HAS_MSI\n"); return len; } @@ -1676,7 +1695,6 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) shost->irq = pdev->irq; shost->unique_id = unique_id; shost->max_cmd_len = 16; - shost->use_cmd_list = 1; if (aac_cfg_major == AAC_CHARDEV_NEEDS_REINIT) aac_init_char(); @@ -1895,7 +1913,7 @@ static int aac_suspend(struct pci_dev *pdev, pm_message_t state) struct Scsi_Host *shost = pci_get_drvdata(pdev); struct aac_dev *aac = (struct aac_dev *)shost->hostdata; - scsi_block_requests(shost); + scsi_host_block(shost); aac_cancel_rescan_worker(aac); aac_send_shutdown(aac); @@ -1931,7 +1949,7 @@ static int aac_resume(struct pci_dev *pdev) * aac_send_shutdown() to block ioctls from upperlayer */ aac->adapter_shutdown = 0; - scsi_unblock_requests(shost); + scsi_host_unblock(shost, SDEV_RUNNING); return 0; @@ -1946,7 +1964,8 @@ fail_device: static void aac_shutdown(struct pci_dev *dev) { struct Scsi_Host *shost = pci_get_drvdata(dev); - scsi_block_requests(shost); + + scsi_host_block(shost); __aac_shutdown((struct aac_dev *)shost->hostdata); } @@ -1978,26 +1997,6 @@ static void aac_remove_one(struct pci_dev *pdev) } } -static void aac_flush_ios(struct aac_dev *aac) -{ - int i; - struct scsi_cmnd *cmd; - - for (i = 0; i < aac->scsi_host_ptr->can_queue; i++) { - cmd = (struct scsi_cmnd *)aac->fibs[i].callback_data; - if (cmd && (cmd->SCp.phase == AAC_OWNER_FIRMWARE)) { - scsi_dma_unmap(cmd); - - if (aac->handle_pci_error) - cmd->result = DID_NO_CONNECT << 16; - else - cmd->result = DID_RESET << 16; - - cmd->scsi_done(cmd); - } - } -} - static pci_ers_result_t aac_pci_error_detected(struct pci_dev *pdev, enum pci_channel_state error) { @@ -2012,9 +2011,9 @@ static pci_ers_result_t aac_pci_error_detected(struct pci_dev *pdev, case pci_channel_io_frozen: aac->handle_pci_error = 1; - scsi_block_requests(aac->scsi_host_ptr); + scsi_host_block(shost); aac_cancel_rescan_worker(aac); - aac_flush_ios(aac); + scsi_host_complete_all_commands(shost, DID_NO_CONNECT); aac_release_resources(aac); pci_disable_pcie_error_reporting(pdev); @@ -2024,7 +2023,7 @@ static pci_ers_result_t aac_pci_error_detected(struct pci_dev *pdev, case pci_channel_io_perm_failure: aac->handle_pci_error = 1; - aac_flush_ios(aac); + scsi_host_complete_all_commands(shost, DID_NO_CONNECT); return PCI_ERS_RESULT_DISCONNECT; } @@ -2065,7 +2064,6 @@ fail_device: static void aac_pci_resume(struct pci_dev *pdev) { struct Scsi_Host *shost = pci_get_drvdata(pdev); - struct scsi_device *sdev = NULL; struct aac_dev *aac = (struct aac_dev *)shost_priv(shost); if (aac_adapter_ioremap(aac, aac->base_size)) { @@ -2092,10 +2090,7 @@ static void aac_pci_resume(struct pci_dev *pdev) aac->adapter_shutdown = 0; aac->handle_pci_error = 0; - shost_for_each_device(sdev, shost) - if (sdev->sdev_state == SDEV_OFFLINE) - sdev->sdev_state = SDEV_RUNNING; - scsi_unblock_requests(aac->scsi_host_ptr); + scsi_host_unblock(shost, SDEV_RUNNING); aac_scan_host(aac); pci_save_state(pdev); |