diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-14 16:23:44 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-14 16:23:44 -0800 |
commit | 670ffccb2f9183eb6cb32fe92257aea52b3f8a7d (patch) | |
tree | 54962412913a69e17cc680c57f3e26f7305d99d2 /drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | |
parent | 47f521ba18190e4bfbb65ead3977af5756884427 (diff) | |
parent | 341b2aa83368e6f23bf0cc3d04604896337ad7cb (diff) | |
download | linux-670ffccb2f9183eb6cb32fe92257aea52b3f8a7d.tar.bz2 |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This is mostly updates of the usual suspects: lpfc, qla2xxx, hisi_sas,
megaraid_sas, pm80xx, mpt3sas, be2iscsi, hpsa. and a host of minor
updates.
There's no major behaviour change or additions to the core in all of
this, so the potential for regressions should be small (biggest
potential being in the scsi error handler changes)"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (203 commits)
scsi: lpfc: Fix hard lock up NMI in els timeout handling.
scsi: mpt3sas: remove a stray KERN_INFO
scsi: mpt3sas: cleanup _scsih_pcie_enumeration_event()
scsi: aacraid: use timespec64 instead of timeval
scsi: scsi_transport_fc: add 64GBIT and 128GBIT port speed definitions
scsi: qla2xxx: Suppress a kernel complaint in qla_init_base_qpair()
scsi: mpt3sas: fix dma_addr_t casts
scsi: be2iscsi: Use kasprintf
scsi: storvsc: Avoid excessive host scan on controller change
scsi: lpfc: fix kzalloc-simple.cocci warnings
scsi: mpt3sas: Update mpt3sas driver version.
scsi: mpt3sas: Fix sparse warnings
scsi: mpt3sas: Fix nvme drives checking for tlr.
scsi: mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info
scsi: mpt3sas: Add-Task-management-debug-info-for-NVMe-drives.
scsi: mpt3sas: scan and add nvme device after controller reset
scsi: mpt3sas: Set NVMe device queue depth as 128
scsi: mpt3sas: Handle NVMe PCIe device related events generated from firmware.
scsi: mpt3sas: API's to remove nvme drive from sml
scsi: mpt3sas: API 's to support NVMe drive addition to SML
...
Diffstat (limited to 'drivers/scsi/hisi_sas/hisi_sas_v2_hw.c')
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 253 |
1 files changed, 107 insertions, 146 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index b1f097dabd01..d02c2a791981 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -406,80 +406,70 @@ static const struct hisi_sas_hw_error one_bit_ecc_errors[] = { .irq_msk = BIT(SAS_ECC_INTR_DQE_ECC_1B_OFF), .msk = HGC_DQE_ECC_1B_ADDR_MSK, .shift = HGC_DQE_ECC_1B_ADDR_OFF, - .msg = "hgc_dqe_acc1b_intr found: \ - Ram address is 0x%08X\n", + .msg = "hgc_dqe_acc1b_intr found: Ram address is 0x%08X\n", .reg = HGC_DQE_ECC_ADDR, }, { .irq_msk = BIT(SAS_ECC_INTR_IOST_ECC_1B_OFF), .msk = HGC_IOST_ECC_1B_ADDR_MSK, .shift = HGC_IOST_ECC_1B_ADDR_OFF, - .msg = "hgc_iost_acc1b_intr found: \ - Ram address is 0x%08X\n", + .msg = "hgc_iost_acc1b_intr found: Ram address is 0x%08X\n", .reg = HGC_IOST_ECC_ADDR, }, { .irq_msk = BIT(SAS_ECC_INTR_ITCT_ECC_1B_OFF), .msk = HGC_ITCT_ECC_1B_ADDR_MSK, .shift = HGC_ITCT_ECC_1B_ADDR_OFF, - .msg = "hgc_itct_acc1b_intr found: \ - Ram address is 0x%08X\n", + .msg = "hgc_itct_acc1b_intr found: am address is 0x%08X\n", .reg = HGC_ITCT_ECC_ADDR, }, { .irq_msk = BIT(SAS_ECC_INTR_IOSTLIST_ECC_1B_OFF), .msk = HGC_LM_DFX_STATUS2_IOSTLIST_MSK, .shift = HGC_LM_DFX_STATUS2_IOSTLIST_OFF, - .msg = "hgc_iostl_acc1b_intr found: \ - memory address is 0x%08X\n", + .msg = "hgc_iostl_acc1b_intr found: memory address is 0x%08X\n", .reg = HGC_LM_DFX_STATUS2, }, { .irq_msk = BIT(SAS_ECC_INTR_ITCTLIST_ECC_1B_OFF), .msk = HGC_LM_DFX_STATUS2_ITCTLIST_MSK, .shift = HGC_LM_DFX_STATUS2_ITCTLIST_OFF, - .msg = "hgc_itctl_acc1b_intr found: \ - memory address is 0x%08X\n", + .msg = "hgc_itctl_acc1b_intr found: memory address is 0x%08X\n", .reg = HGC_LM_DFX_STATUS2, }, { .irq_msk = BIT(SAS_ECC_INTR_CQE_ECC_1B_OFF), .msk = HGC_CQE_ECC_1B_ADDR_MSK, .shift = HGC_CQE_ECC_1B_ADDR_OFF, - .msg = "hgc_cqe_acc1b_intr found: \ - Ram address is 0x%08X\n", + .msg = "hgc_cqe_acc1b_intr found: Ram address is 0x%08X\n", .reg = HGC_CQE_ECC_ADDR, }, { .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM0_ECC_1B_OFF), .msk = HGC_RXM_DFX_STATUS14_MEM0_MSK, .shift = HGC_RXM_DFX_STATUS14_MEM0_OFF, - .msg = "rxm_mem0_acc1b_intr found: \ - memory address is 0x%08X\n", + .msg = "rxm_mem0_acc1b_intr found: memory address is 0x%08X\n", .reg = HGC_RXM_DFX_STATUS14, }, { .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM1_ECC_1B_OFF), .msk = HGC_RXM_DFX_STATUS14_MEM1_MSK, .shift = HGC_RXM_DFX_STATUS14_MEM1_OFF, - .msg = "rxm_mem1_acc1b_intr found: \ - memory address is 0x%08X\n", + .msg = "rxm_mem1_acc1b_intr found: memory address is 0x%08X\n", .reg = HGC_RXM_DFX_STATUS14, }, { .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM2_ECC_1B_OFF), .msk = HGC_RXM_DFX_STATUS14_MEM2_MSK, .shift = HGC_RXM_DFX_STATUS14_MEM2_OFF, - .msg = "rxm_mem2_acc1b_intr found: \ - memory address is 0x%08X\n", + .msg = "rxm_mem2_acc1b_intr found: memory address is 0x%08X\n", .reg = HGC_RXM_DFX_STATUS14, }, { .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM3_ECC_1B_OFF), .msk = HGC_RXM_DFX_STATUS15_MEM3_MSK, .shift = HGC_RXM_DFX_STATUS15_MEM3_OFF, - .msg = "rxm_mem3_acc1b_intr found: \ - memory address is 0x%08X\n", + .msg = "rxm_mem3_acc1b_intr found: memory address is 0x%08X\n", .reg = HGC_RXM_DFX_STATUS15, }, }; @@ -489,80 +479,70 @@ static const struct hisi_sas_hw_error multi_bit_ecc_errors[] = { .irq_msk = BIT(SAS_ECC_INTR_DQE_ECC_MB_OFF), .msk = HGC_DQE_ECC_MB_ADDR_MSK, .shift = HGC_DQE_ECC_MB_ADDR_OFF, - .msg = "hgc_dqe_accbad_intr (0x%x) found: \ - Ram address is 0x%08X\n", + .msg = "hgc_dqe_accbad_intr (0x%x) found: Ram address is 0x%08X\n", .reg = HGC_DQE_ECC_ADDR, }, { .irq_msk = BIT(SAS_ECC_INTR_IOST_ECC_MB_OFF), .msk = HGC_IOST_ECC_MB_ADDR_MSK, .shift = HGC_IOST_ECC_MB_ADDR_OFF, - .msg = "hgc_iost_accbad_intr (0x%x) found: \ - Ram address is 0x%08X\n", + .msg = "hgc_iost_accbad_intr (0x%x) found: Ram address is 0x%08X\n", .reg = HGC_IOST_ECC_ADDR, }, { .irq_msk = BIT(SAS_ECC_INTR_ITCT_ECC_MB_OFF), .msk = HGC_ITCT_ECC_MB_ADDR_MSK, .shift = HGC_ITCT_ECC_MB_ADDR_OFF, - .msg = "hgc_itct_accbad_intr (0x%x) found: \ - Ram address is 0x%08X\n", + .msg = "hgc_itct_accbad_intr (0x%x) found: Ram address is 0x%08X\n", .reg = HGC_ITCT_ECC_ADDR, }, { .irq_msk = BIT(SAS_ECC_INTR_IOSTLIST_ECC_MB_OFF), .msk = HGC_LM_DFX_STATUS2_IOSTLIST_MSK, .shift = HGC_LM_DFX_STATUS2_IOSTLIST_OFF, - .msg = "hgc_iostl_accbad_intr (0x%x) found: \ - memory address is 0x%08X\n", + .msg = "hgc_iostl_accbad_intr (0x%x) found: memory address is 0x%08X\n", .reg = HGC_LM_DFX_STATUS2, }, { .irq_msk = BIT(SAS_ECC_INTR_ITCTLIST_ECC_MB_OFF), .msk = HGC_LM_DFX_STATUS2_ITCTLIST_MSK, .shift = HGC_LM_DFX_STATUS2_ITCTLIST_OFF, - .msg = "hgc_itctl_accbad_intr (0x%x) found: \ - memory address is 0x%08X\n", + .msg = "hgc_itctl_accbad_intr (0x%x) found: memory address is 0x%08X\n", .reg = HGC_LM_DFX_STATUS2, }, { .irq_msk = BIT(SAS_ECC_INTR_CQE_ECC_MB_OFF), .msk = HGC_CQE_ECC_MB_ADDR_MSK, .shift = HGC_CQE_ECC_MB_ADDR_OFF, - .msg = "hgc_cqe_accbad_intr (0x%x) found: \ - Ram address is 0x%08X\n", + .msg = "hgc_cqe_accbad_intr (0x%x) found: Ram address is 0x%08X\n", .reg = HGC_CQE_ECC_ADDR, }, { .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM0_ECC_MB_OFF), .msk = HGC_RXM_DFX_STATUS14_MEM0_MSK, .shift = HGC_RXM_DFX_STATUS14_MEM0_OFF, - .msg = "rxm_mem0_accbad_intr (0x%x) found: \ - memory address is 0x%08X\n", + .msg = "rxm_mem0_accbad_intr (0x%x) found: memory address is 0x%08X\n", .reg = HGC_RXM_DFX_STATUS14, }, { .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM1_ECC_MB_OFF), .msk = HGC_RXM_DFX_STATUS14_MEM1_MSK, .shift = HGC_RXM_DFX_STATUS14_MEM1_OFF, - .msg = "rxm_mem1_accbad_intr (0x%x) found: \ - memory address is 0x%08X\n", + .msg = "rxm_mem1_accbad_intr (0x%x) found: memory address is 0x%08X\n", .reg = HGC_RXM_DFX_STATUS14, }, { .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM2_ECC_MB_OFF), .msk = HGC_RXM_DFX_STATUS14_MEM2_MSK, .shift = HGC_RXM_DFX_STATUS14_MEM2_OFF, - .msg = "rxm_mem2_accbad_intr (0x%x) found: \ - memory address is 0x%08X\n", + .msg = "rxm_mem2_accbad_intr (0x%x) found: memory address is 0x%08X\n", .reg = HGC_RXM_DFX_STATUS14, }, { .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM3_ECC_MB_OFF), .msk = HGC_RXM_DFX_STATUS15_MEM3_MSK, .shift = HGC_RXM_DFX_STATUS15_MEM3_OFF, - .msg = "rxm_mem3_accbad_intr (0x%x) found: \ - memory address is 0x%08X\n", + .msg = "rxm_mem3_accbad_intr (0x%x) found: memory address is 0x%08X\n", .reg = HGC_RXM_DFX_STATUS15, }, }; @@ -843,8 +823,9 @@ hisi_sas_device *alloc_dev_quirk_v2_hw(struct domain_device *device) struct hisi_sas_device *sas_dev = NULL; int i, sata_dev = dev_is_sata(device); int sata_idx = -1; + unsigned long flags; - spin_lock(&hisi_hba->lock); + spin_lock_irqsave(&hisi_hba->lock, flags); if (sata_dev) if (!sata_index_alloc_v2_hw(hisi_hba, &sata_idx)) @@ -874,7 +855,7 @@ hisi_sas_device *alloc_dev_quirk_v2_hw(struct domain_device *device) } out: - spin_unlock(&hisi_hba->lock); + spin_unlock_irqrestore(&hisi_hba->lock, flags); return sas_dev; } @@ -2376,7 +2357,9 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) if (unlikely(aborted)) { ts->stat = SAS_ABORTED_TASK; + spin_lock_irqsave(&hisi_hba->lock, flags); hisi_sas_slot_task_free(hisi_hba, task, slot); + spin_unlock_irqrestore(&hisi_hba->lock, flags); return -1; } @@ -2951,25 +2934,58 @@ static irqreturn_t fatal_ecc_int_v2_hw(int irq_no, void *p) return IRQ_HANDLED; } -#define AXI_ERR_NR 8 -static const char axi_err_info[AXI_ERR_NR][32] = { - "IOST_AXI_W_ERR", - "IOST_AXI_R_ERR", - "ITCT_AXI_W_ERR", - "ITCT_AXI_R_ERR", - "SATA_AXI_W_ERR", - "SATA_AXI_R_ERR", - "DQE_AXI_R_ERR", - "CQE_AXI_W_ERR" +static const struct hisi_sas_hw_error axi_error[] = { + { .msk = BIT(0), .msg = "IOST_AXI_W_ERR" }, + { .msk = BIT(1), .msg = "IOST_AXI_R_ERR" }, + { .msk = BIT(2), .msg = "ITCT_AXI_W_ERR" }, + { .msk = BIT(3), .msg = "ITCT_AXI_R_ERR" }, + { .msk = BIT(4), .msg = "SATA_AXI_W_ERR" }, + { .msk = BIT(5), .msg = "SATA_AXI_R_ERR" }, + { .msk = BIT(6), .msg = "DQE_AXI_R_ERR" }, + { .msk = BIT(7), .msg = "CQE_AXI_W_ERR" }, + {}, +}; + +static const struct hisi_sas_hw_error fifo_error[] = { + { .msk = BIT(8), .msg = "CQE_WINFO_FIFO" }, + { .msk = BIT(9), .msg = "CQE_MSG_FIFIO" }, + { .msk = BIT(10), .msg = "GETDQE_FIFO" }, + { .msk = BIT(11), .msg = "CMDP_FIFO" }, + { .msk = BIT(12), .msg = "AWTCTRL_FIFO" }, + {}, }; -#define FIFO_ERR_NR 5 -static const char fifo_err_info[FIFO_ERR_NR][32] = { - "CQE_WINFO_FIFO", - "CQE_MSG_FIFIO", - "GETDQE_FIFO", - "CMDP_FIFO", - "AWTCTRL_FIFO" +static const struct hisi_sas_hw_error fatal_axi_errors[] = { + { + .irq_msk = BIT(ENT_INT_SRC3_WP_DEPTH_OFF), + .msg = "write pointer and depth", + }, + { + .irq_msk = BIT(ENT_INT_SRC3_IPTT_SLOT_NOMATCH_OFF), + .msg = "iptt no match slot", + }, + { + .irq_msk = BIT(ENT_INT_SRC3_RP_DEPTH_OFF), + .msg = "read pointer and depth", + }, + { + .irq_msk = BIT(ENT_INT_SRC3_AXI_OFF), + .reg = HGC_AXI_FIFO_ERR_INFO, + .sub = axi_error, + }, + { + .irq_msk = BIT(ENT_INT_SRC3_FIFO_OFF), + .reg = HGC_AXI_FIFO_ERR_INFO, + .sub = fifo_error, + }, + { + .irq_msk = BIT(ENT_INT_SRC3_LM_OFF), + .msg = "LM add/fetch list", + }, + { + .irq_msk = BIT(ENT_INT_SRC3_ABT_OFF), + .msg = "SAS_HGC_ABT fetch LM list", + }, }; static irqreturn_t fatal_axi_int_v2_hw(int irq_no, void *p) @@ -2977,98 +2993,47 @@ static irqreturn_t fatal_axi_int_v2_hw(int irq_no, void *p) struct hisi_hba *hisi_hba = p; u32 irq_value, irq_msk, err_value; struct device *dev = hisi_hba->dev; + const struct hisi_sas_hw_error *axi_error; + int i; irq_msk = hisi_sas_read32(hisi_hba, ENT_INT_SRC_MSK3); hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, irq_msk | 0xfffffffe); irq_value = hisi_sas_read32(hisi_hba, ENT_INT_SRC3); - if (irq_value) { - if (irq_value & BIT(ENT_INT_SRC3_WP_DEPTH_OFF)) { - hisi_sas_write32(hisi_hba, ENT_INT_SRC3, - 1 << ENT_INT_SRC3_WP_DEPTH_OFF); - dev_warn(dev, "write pointer and depth error (0x%x) \ - found!\n", - irq_value); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } - - if (irq_value & BIT(ENT_INT_SRC3_IPTT_SLOT_NOMATCH_OFF)) { - hisi_sas_write32(hisi_hba, ENT_INT_SRC3, - 1 << - ENT_INT_SRC3_IPTT_SLOT_NOMATCH_OFF); - dev_warn(dev, "iptt no match slot error (0x%x) found!\n", - irq_value); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } - if (irq_value & BIT(ENT_INT_SRC3_RP_DEPTH_OFF)) { - dev_warn(dev, "read pointer and depth error (0x%x) \ - found!\n", - irq_value); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } - - if (irq_value & BIT(ENT_INT_SRC3_AXI_OFF)) { - int i; - - hisi_sas_write32(hisi_hba, ENT_INT_SRC3, - 1 << ENT_INT_SRC3_AXI_OFF); - err_value = hisi_sas_read32(hisi_hba, - HGC_AXI_FIFO_ERR_INFO); - - for (i = 0; i < AXI_ERR_NR; i++) { - if (err_value & BIT(i)) { - dev_warn(dev, "%s (0x%x) found!\n", - axi_err_info[i], irq_value); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } - } - } - - if (irq_value & BIT(ENT_INT_SRC3_FIFO_OFF)) { - int i; - - hisi_sas_write32(hisi_hba, ENT_INT_SRC3, - 1 << ENT_INT_SRC3_FIFO_OFF); - err_value = hisi_sas_read32(hisi_hba, - HGC_AXI_FIFO_ERR_INFO); + for (i = 0; i < ARRAY_SIZE(fatal_axi_errors); i++) { + axi_error = &fatal_axi_errors[i]; + if (!(irq_value & axi_error->irq_msk)) + continue; - for (i = 0; i < FIFO_ERR_NR; i++) { - if (err_value & BIT(AXI_ERR_NR + i)) { - dev_warn(dev, "%s (0x%x) found!\n", - fifo_err_info[i], irq_value); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } + hisi_sas_write32(hisi_hba, ENT_INT_SRC3, + 1 << axi_error->shift); + if (axi_error->sub) { + const struct hisi_sas_hw_error *sub = axi_error->sub; + + err_value = hisi_sas_read32(hisi_hba, axi_error->reg); + for (; sub->msk || sub->msg; sub++) { + if (!(err_value & sub->msk)) + continue; + dev_warn(dev, "%s (0x%x) found!\n", + sub->msg, irq_value); + queue_work(hisi_hba->wq, &hisi_hba->rst_work); } - - } - - if (irq_value & BIT(ENT_INT_SRC3_LM_OFF)) { - hisi_sas_write32(hisi_hba, ENT_INT_SRC3, - 1 << ENT_INT_SRC3_LM_OFF); - dev_warn(dev, "LM add/fetch list error (0x%x) found!\n", - irq_value); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } - - if (irq_value & BIT(ENT_INT_SRC3_ABT_OFF)) { - hisi_sas_write32(hisi_hba, ENT_INT_SRC3, - 1 << ENT_INT_SRC3_ABT_OFF); - dev_warn(dev, "SAS_HGC_ABT fetch LM list error (0x%x) found!\n", - irq_value); + } else { + dev_warn(dev, "%s (0x%x) found!\n", + axi_error->msg, irq_value); queue_work(hisi_hba->wq, &hisi_hba->rst_work); } + } - if (irq_value & BIT(ENT_INT_SRC3_ITC_INT_OFF)) { - u32 reg_val = hisi_sas_read32(hisi_hba, ITCT_CLR); - u32 dev_id = reg_val & ITCT_DEV_MSK; - struct hisi_sas_device *sas_dev = - &hisi_hba->devices[dev_id]; + if (irq_value & BIT(ENT_INT_SRC3_ITC_INT_OFF)) { + u32 reg_val = hisi_sas_read32(hisi_hba, ITCT_CLR); + u32 dev_id = reg_val & ITCT_DEV_MSK; + struct hisi_sas_device *sas_dev = &hisi_hba->devices[dev_id]; - hisi_sas_write32(hisi_hba, ITCT_CLR, 0); - dev_dbg(dev, "clear ITCT ok\n"); - complete(sas_dev->completion); - } + hisi_sas_write32(hisi_hba, ITCT_CLR, 0); + dev_dbg(dev, "clear ITCT ok\n"); + complete(sas_dev->completion); } hisi_sas_write32(hisi_hba, ENT_INT_SRC3, irq_value); @@ -3408,6 +3373,7 @@ static int soft_reset_v2_hw(struct hisi_hba *hisi_hba) interrupt_disable_v2_hw(hisi_hba); hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0); + hisi_sas_kill_tasklets(hisi_hba); hisi_sas_stop_phys(hisi_hba); @@ -3458,7 +3424,7 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = { .start_delivery = start_delivery_v2_hw, .slot_complete = slot_complete_v2_hw, .phys_init = phys_init_v2_hw, - .phy_enable = enable_phy_v2_hw, + .phy_start = start_phy_v2_hw, .phy_disable = disable_phy_v2_hw, .phy_hard_reset = phy_hard_reset_v2_hw, .get_events = phy_get_events_v2_hw, @@ -3491,16 +3457,11 @@ static int hisi_sas_v2_remove(struct platform_device *pdev) { struct sas_ha_struct *sha = platform_get_drvdata(pdev); struct hisi_hba *hisi_hba = sha->lldd_ha; - int i; if (timer_pending(&hisi_hba->timer)) del_timer(&hisi_hba->timer); - for (i = 0; i < hisi_hba->queue_count; i++) { - struct hisi_sas_cq *cq = &hisi_hba->cq[i]; - - tasklet_kill(&cq->tasklet); - } + hisi_sas_kill_tasklets(hisi_hba); return hisi_sas_remove(pdev); } |