summaryrefslogtreecommitdiff
path: root/drivers/scsi/aacraid/linit.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-04-03 03:03:53 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2020-04-03 03:03:53 +0300
commit79f51b7b9c4719303f758ae8406c4e5997ed6aa3 (patch)
tree33ca1c3ee11848e75d90f811038fcd149e69d258 /drivers/scsi/aacraid/linit.c
parente109f506074152b7241bcbd3949a099e776cb802 (diff)
parentff275db92c935858454b721f0d960fff421634d3 (diff)
downloadlinux-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.c171
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);