diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-11-05 16:42:02 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-11-05 16:42:02 +0100 |
commit | fe91c4725aeed35023ba4f7a1e1adfebb6878c23 (patch) | |
tree | 7f0e5cbbbe3a1e24d3e3b66ae290625d48ec4b2f /drivers/scsi/hisi_sas | |
parent | Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid... (diff) | |
parent | scsi: lpfc: Update lpfc version to 14.0.0.3 (diff) | |
download | linux-fe91c4725aeed35023ba4f7a1e1adfebb6878c23.tar.xz linux-fe91c4725aeed35023ba4f7a1e1adfebb6878c23.zip |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This consists of the usual driver updates (ufs, smartpqi, lpfc,
target, megaraid_sas, hisi_sas, qla2xxx) and minor updates and bug
fixes.
Notable core changes are the removal of scsi->tag which caused some
churn in obsolete drivers and a sweep through all drivers to call
scsi_done() directly instead of scsi->done() which removes a pointer
indirection from the hot path and a move to register core sysfs files
earlier, which means they're available to KOBJ_ADD processing, which
necessitates switching all drivers to using attribute groups"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (279 commits)
scsi: lpfc: Update lpfc version to 14.0.0.3
scsi: lpfc: Allow fabric node recovery if recovery is in progress before devloss
scsi: lpfc: Fix link down processing to address NULL pointer dereference
scsi: lpfc: Allow PLOGI retry if previous PLOGI was aborted
scsi: lpfc: Fix use-after-free in lpfc_unreg_rpi() routine
scsi: lpfc: Correct sysfs reporting of loop support after SFP status change
scsi: lpfc: Wait for successful restart of SLI3 adapter during host sg_reset
scsi: lpfc: Revert LOG_TRACE_EVENT back to LOG_INIT prior to driver_resource_setup()
scsi: ufs: ufshcd-pltfrm: Fix memory leak due to probe defer
scsi: ufs: mediatek: Avoid sched_clock() misuse
scsi: mpt3sas: Make mpt3sas_dev_attrs static
scsi: scsi_transport_sas: Add 22.5 Gbps link rate definitions
scsi: target: core: Stop using bdevname()
scsi: aha1542: Use memcpy_{from,to}_bvec()
scsi: sr: Add error handling support for add_disk()
scsi: sd: Add error handling support for add_disk()
scsi: target: Perform ALUA group changes in one step
scsi: target: Replace lun_tg_pt_gp_lock with rcu in I/O path
scsi: target: Fix alua_tg_pt_gps_count tracking
scsi: target: Fix ordered tag handling
...
Diffstat (limited to 'drivers/scsi/hisi_sas')
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas.h | 3 | ||||
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_main.c | 113 | ||||
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 23 | ||||
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 35 | ||||
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 62 |
5 files changed, 132 insertions, 104 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 436d174f2194..2213a91923a5 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -35,7 +35,7 @@ #define HISI_SAS_QUEUE_SLOTS 4096 #define HISI_SAS_MAX_ITCT_ENTRIES 1024 #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES -#define HISI_SAS_RESET_BIT 0 +#define HISI_SAS_RESETTING_BIT 0 #define HISI_SAS_REJECT_CMD_BIT 1 #define HISI_SAS_PM_BIT 2 #define HISI_SAS_HW_FAULT_BIT 3 @@ -649,6 +649,7 @@ extern int hisi_sas_probe(struct platform_device *pdev, extern int hisi_sas_remove(struct platform_device *pdev); extern int hisi_sas_slave_configure(struct scsi_device *sdev); +extern int hisi_sas_slave_alloc(struct scsi_device *sdev); extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time); extern void hisi_sas_scan_start(struct Scsi_Host *shost); extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type); diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 9515c45affa5..f206c433de32 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -724,7 +724,7 @@ static int hisi_sas_init_device(struct domain_device *device) */ local_phy = sas_get_local_phy(device); if (!scsi_is_sas_phy_local(local_phy) && - !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) { + !test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) { unsigned long deadline = ata_deadline(jiffies, 20000); struct sata_device *sata_dev = &device->sata_dev; struct ata_host *ata_host = sata_dev->ata_host; @@ -756,6 +756,20 @@ static int hisi_sas_init_device(struct domain_device *device) return rc; } +int hisi_sas_slave_alloc(struct scsi_device *sdev) +{ + struct domain_device *ddev; + int rc; + + rc = sas_slave_alloc(sdev); + if (rc) + return rc; + ddev = sdev_to_domain_dev(sdev); + + return hisi_sas_init_device(ddev); +} +EXPORT_SYMBOL_GPL(hisi_sas_slave_alloc); + static int hisi_sas_dev_found(struct domain_device *device) { struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); @@ -802,9 +816,6 @@ static int hisi_sas_dev_found(struct domain_device *device) dev_info(dev, "dev[%d:%x] found\n", sas_dev->device_id, sas_dev->dev_type); - rc = hisi_sas_init_device(device); - if (rc) - goto err_out; sas_dev->dev_status = HISI_SAS_DEV_NORMAL; return 0; @@ -1072,7 +1083,7 @@ static void hisi_sas_dev_gone(struct domain_device *device) sas_dev->device_id, sas_dev->dev_type); down(&hisi_hba->sem); - if (!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) { + if (!test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) { hisi_sas_internal_task_abort(hisi_hba, device, HISI_SAS_INT_ABT_DEV, 0, true); @@ -1135,9 +1146,17 @@ static int hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no, static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, void *funcdata) { + struct hisi_sas_phy *phy = container_of(sas_phy, + struct hisi_sas_phy, sas_phy); struct sas_ha_struct *sas_ha = sas_phy->ha; struct hisi_hba *hisi_hba = sas_ha->lldd_ha; + struct device *dev = hisi_hba->dev; + DECLARE_COMPLETION_ONSTACK(completion); int phy_no = sas_phy->id; + u8 sts = phy->phy_attached; + int ret = 0; + + phy->reset_completion = &completion; switch (func) { case PHY_FUNC_HARD_RESET: @@ -1152,26 +1171,40 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, case PHY_FUNC_DISABLE: hisi_sas_phy_enable(hisi_hba, phy_no, 0); - break; + goto out; case PHY_FUNC_SET_LINK_RATE: - return hisi_sas_phy_set_linkrate(hisi_hba, phy_no, funcdata); + ret = hisi_sas_phy_set_linkrate(hisi_hba, phy_no, funcdata); + break; + case PHY_FUNC_GET_EVENTS: if (hisi_hba->hw->get_events) { hisi_hba->hw->get_events(hisi_hba, phy_no); - break; + goto out; } fallthrough; case PHY_FUNC_RELEASE_SPINUP_HOLD: default: - return -EOPNOTSUPP; + ret = -EOPNOTSUPP; + goto out; } - return 0; + + if (sts && !wait_for_completion_timeout(&completion, 2 * HZ)) { + dev_warn(dev, "phy%d wait phyup timed out for func %d\n", + phy_no, func); + if (phy->in_reset) + ret = -ETIMEDOUT; + } + +out: + phy->reset_completion = NULL; + + return ret; } static void hisi_sas_task_done(struct sas_task *task) { - del_timer(&task->slow_task->timer); + del_timer_sync(&task->slow_task->timer); complete(&task->slow_task->completion); } @@ -1229,7 +1262,7 @@ static int hisi_sas_exec_internal_tmf_task(struct domain_device *device, res = hisi_sas_task_exec(task, GFP_KERNEL, 1, tmf); if (res) { - del_timer(&task->slow_task->timer); + del_timer_sync(&task->slow_task->timer); dev_err(dev, "abort tmf: executing internal task failed: %d\n", res); goto ex_err; @@ -1554,8 +1587,7 @@ void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba) scsi_block_requests(shost); hisi_hba->hw->wait_cmds_complete_timeout(hisi_hba, 100, 5000); - if (timer_pending(&hisi_hba->timer)) - del_timer_sync(&hisi_hba->timer); + del_timer_sync(&hisi_hba->timer); set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); } @@ -1576,7 +1608,7 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba) hisi_sas_reset_init_all_devices(hisi_hba); up(&hisi_hba->sem); scsi_unblock_requests(shost); - clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); hisi_sas_rescan_topology(hisi_hba, hisi_hba->phy_state); } @@ -1587,7 +1619,7 @@ static int hisi_sas_controller_prereset(struct hisi_hba *hisi_hba) if (!hisi_hba->hw->soft_reset) return -1; - if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + if (test_and_set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) return -1; if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) @@ -1611,7 +1643,7 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); up(&hisi_hba->sem); scsi_unblock_requests(shost); - clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); return rc; } @@ -1773,7 +1805,6 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) struct hisi_sas_device *sas_dev = device->lldd_dev; struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); struct sas_ha_struct *sas_ha = &hisi_hba->sha; - DECLARE_COMPLETION_ONSTACK(phyreset); int rc, reset_type; if (!local_phy->enabled) { @@ -1786,8 +1817,11 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) sas_ha->sas_phy[local_phy->number]; struct hisi_sas_phy *phy = container_of(sas_phy, struct hisi_sas_phy, sas_phy); + unsigned long flags; + + spin_lock_irqsave(&phy->lock, flags); phy->in_reset = 1; - phy->reset_completion = &phyreset; + spin_unlock_irqrestore(&phy->lock, flags); } reset_type = (sas_dev->dev_status == HISI_SAS_DEV_INIT || @@ -1801,17 +1835,14 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) sas_ha->sas_phy[local_phy->number]; struct hisi_sas_phy *phy = container_of(sas_phy, struct hisi_sas_phy, sas_phy); - int ret = wait_for_completion_timeout(&phyreset, - I_T_NEXUS_RESET_PHYUP_TIMEOUT); unsigned long flags; spin_lock_irqsave(&phy->lock, flags); - phy->reset_completion = NULL; phy->in_reset = 0; spin_unlock_irqrestore(&phy->lock, flags); /* report PHY down if timed out */ - if (!ret) + if (rc == -ETIMEDOUT) hisi_sas_phy_down(hisi_hba, sas_phy->id, 0, GFP_KERNEL); } else if (sas_dev->dev_status != HISI_SAS_DEV_INIT) { /* @@ -1839,14 +1870,33 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device) } hisi_sas_dereg_device(hisi_hba, device); - if (dev_is_sata(device)) { + rc = hisi_sas_debug_I_T_nexus_reset(device); + if (rc == TMF_RESP_FUNC_COMPLETE && dev_is_sata(device)) { + struct sas_phy *local_phy; + rc = hisi_sas_softreset_ata_disk(device); - if (rc == TMF_RESP_FUNC_FAILED) - return TMF_RESP_FUNC_FAILED; + switch (rc) { + case -ECOMM: + rc = -ENODEV; + break; + case TMF_RESP_FUNC_FAILED: + case -EMSGSIZE: + case -EIO: + local_phy = sas_get_local_phy(device); + rc = sas_phy_enable(local_phy, 0); + if (!rc) { + local_phy->enabled = 0; + dev_err(dev, "Disabled local phy of ATA disk %016llx due to softreset fail (%d)\n", + SAS_ADDR(device->sas_addr), rc); + rc = -ENODEV; + } + sas_put_local_phy(local_phy); + break; + default: + break; + } } - rc = hisi_sas_debug_I_T_nexus_reset(device); - if ((rc == TMF_RESP_FUNC_COMPLETE) || (rc == -ENODEV)) hisi_sas_release_task(hisi_hba, device); @@ -2097,7 +2147,7 @@ _hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, res = hisi_sas_internal_abort_task_exec(hisi_hba, sas_dev->device_id, task, abort_flag, tag, dq); if (res) { - del_timer(&task->slow_task->timer); + del_timer_sync(&task->slow_task->timer); dev_err(dev, "internal task abort: executing internal task failed: %d\n", res); goto exit; @@ -2251,7 +2301,7 @@ void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy, } else { struct hisi_sas_port *port = phy->port; - if (test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags) || + if (test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags) || phy->in_reset) { dev_info(dev, "ignore flutter phy%d down\n", phy_no); return; @@ -2769,8 +2819,7 @@ int hisi_sas_remove(struct platform_device *pdev) struct hisi_hba *hisi_hba = sha->lldd_ha; struct Scsi_Host *shost = sha->core.shost; - if (timer_pending(&hisi_hba->timer)) - del_timer(&hisi_hba->timer); + del_timer_sync(&hisi_hba->timer); sas_unregister_ha(sha); sas_remove_host(sha->core.shost); diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index afe639994f3d..3059d19e4368 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1327,7 +1327,6 @@ static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) u32 *frame_rcvd = (u32 *)sas_phy->frame_rcvd; struct sas_identify_frame *id = (struct sas_identify_frame *)frame_rcvd; irqreturn_t res = IRQ_HANDLED; - unsigned long flags; irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2); if (!(irq_value & CHL_INT2_SL_PHY_ENA_MSK)) { @@ -1380,15 +1379,9 @@ static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) phy->identify.target_port_protocols = SAS_PROTOCOL_SMP; hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); - - spin_lock_irqsave(&phy->lock, flags); - if (phy->reset_completion) { - phy->in_reset = 0; - complete(phy->reset_completion); - } - spin_unlock_irqrestore(&phy->lock, flags); - end: + if (phy->reset_completion) + complete(phy->reset_completion); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, CHL_INT2_SL_PHY_ENA_MSK); @@ -1422,7 +1415,7 @@ static irqreturn_t int_bcast_v1_hw(int irq, void *p) goto end; } - if (!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + if (!test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, GFP_ATOMIC); @@ -1749,11 +1742,13 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) return 0; } -static struct device_attribute *host_attrs_v1_hw[] = { - &dev_attr_phy_event_threshold, +static struct attribute *host_v1_hw_attrs[] = { + &dev_attr_phy_event_threshold.attr, NULL }; +ATTRIBUTE_GROUPS(host_v1_hw); + static struct scsi_host_template sht_v1_hw = { .name = DRV_NAME, .proc_name = DRV_NAME, @@ -1771,13 +1766,13 @@ static struct scsi_host_template sht_v1_hw = { .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, - .slave_alloc = sas_slave_alloc, + .slave_alloc = hisi_sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = sas_ioctl, #endif - .shost_attrs = host_attrs_v1_hw, + .shost_groups = host_v1_hw_groups, .host_reset = hisi_sas_host_reset, }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index b0b2361e63fe..64ed3e472e65 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -2368,18 +2368,18 @@ static void slot_complete_v2_hw(struct hisi_hba *hisi_hba, case STAT_IO_COMPLETE: /* internal abort command complete */ ts->stat = TMF_RESP_FUNC_SUCC; - del_timer(&slot->internal_abort_timer); + del_timer_sync(&slot->internal_abort_timer); goto out; case STAT_IO_NO_DEVICE: ts->stat = TMF_RESP_FUNC_COMPLETE; - del_timer(&slot->internal_abort_timer); + del_timer_sync(&slot->internal_abort_timer); goto out; case STAT_IO_NOT_VALID: /* abort single io, controller don't find * the io need to abort */ ts->stat = TMF_RESP_FUNC_FAILED; - del_timer(&slot->internal_abort_timer); + del_timer_sync(&slot->internal_abort_timer); goto out; default: break; @@ -2641,7 +2641,6 @@ static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba) struct device *dev = hisi_hba->dev; u32 *frame_rcvd = (u32 *)sas_phy->frame_rcvd; struct sas_identify_frame *id = (struct sas_identify_frame *)frame_rcvd; - unsigned long flags; hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1); @@ -2696,14 +2695,9 @@ static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba) set_link_timer_quirk(hisi_hba); } hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); - spin_lock_irqsave(&phy->lock, flags); - if (phy->reset_completion) { - phy->in_reset = 0; - complete(phy->reset_completion); - } - spin_unlock_irqrestore(&phy->lock, flags); - end: + if (phy->reset_completion) + complete(phy->reset_completion); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, CHL_INT0_SL_PHY_ENABLE_MSK); hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 0); @@ -2824,7 +2818,7 @@ static void phy_bcast_v2_hw(int phy_no, struct hisi_hba *hisi_hba) hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1); bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS); if ((bcast_status & RX_BCAST_CHG_MSK) && - !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + !test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, GFP_ATOMIC); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, @@ -3204,7 +3198,6 @@ static irqreturn_t sata_int_v2_hw(int irq_no, void *p) u32 ent_tmp, ent_msk, ent_int, port_id, link_rate, hard_phy_linkrate; irqreturn_t res = IRQ_HANDLED; u8 attached_sas_addr[SAS_ADDR_SIZE] = {0}; - unsigned long flags; int phy_no, offset; del_timer(&phy->timer); @@ -3280,12 +3273,8 @@ static irqreturn_t sata_int_v2_hw(int irq_no, void *p) phy->identify.target_port_protocols = SAS_PROTOCOL_SATA; hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); - spin_lock_irqsave(&phy->lock, flags); - if (phy->reset_completion) { - phy->in_reset = 0; + if (phy->reset_completion) complete(phy->reset_completion); - } - spin_unlock_irqrestore(&phy->lock, flags); end: hisi_sas_write32(hisi_hba, ENT_INT_SRC1 + offset, ent_tmp); hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1 + offset, ent_msk); @@ -3542,11 +3531,13 @@ static void wait_cmds_complete_timeout_v2_hw(struct hisi_hba *hisi_hba, } -static struct device_attribute *host_attrs_v2_hw[] = { - &dev_attr_phy_event_threshold, +static struct attribute *host_v2_hw_attrs[] = { + &dev_attr_phy_event_threshold.attr, NULL }; +ATTRIBUTE_GROUPS(host_v2_hw); + static int map_queues_v2_hw(struct Scsi_Host *shost) { struct hisi_hba *hisi_hba = shost_priv(shost); @@ -3584,13 +3575,13 @@ static struct scsi_host_template sht_v2_hw = { .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, - .slave_alloc = sas_slave_alloc, + .slave_alloc = hisi_sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = sas_ioctl, #endif - .shost_attrs = host_attrs_v2_hw, + .shost_groups = host_v2_hw_groups, .host_reset = hisi_sas_host_reset, .map_queues = map_queues_v2_hw, .host_tagset = 1, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 27884f3106ab..0ef6c21bf081 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -519,6 +519,8 @@ struct hisi_sas_err_record_v3 { #define CHNL_INT_STS_INT2_MSK BIT(3) #define CHNL_WIDTH 4 +#define BAR_NO_V3_HW 5 + enum { DSM_FUNC_ERR_HANDLE_MSI = 0, }; @@ -1481,7 +1483,6 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; struct asd_sas_phy *sas_phy = &phy->sas_phy; struct device *dev = hisi_hba->dev; - unsigned long flags; del_timer(&phy->timer); hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1); @@ -1563,13 +1564,9 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) phy->phy_attached = 1; hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); res = IRQ_HANDLED; - spin_lock_irqsave(&phy->lock, flags); - if (phy->reset_completion) { - phy->in_reset = 0; - complete(phy->reset_completion); - } - spin_unlock_irqrestore(&phy->lock, flags); end: + if (phy->reset_completion) + complete(phy->reset_completion); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, CHL_INT0_SL_PHY_ENABLE_MSK); hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 0); @@ -1616,7 +1613,7 @@ static irqreturn_t phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba) hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1); bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS); if ((bcast_status & RX_BCAST_CHG_MSK) && - !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + !test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, GFP_ATOMIC); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, @@ -2770,14 +2767,16 @@ static int slave_configure_v3_hw(struct scsi_device *sdev) return 0; } -static struct device_attribute *host_attrs_v3_hw[] = { - &dev_attr_phy_event_threshold, - &dev_attr_intr_conv_v3_hw, - &dev_attr_intr_coal_ticks_v3_hw, - &dev_attr_intr_coal_count_v3_hw, +static struct attribute *host_v3_hw_attrs[] = { + &dev_attr_phy_event_threshold.attr, + &dev_attr_intr_conv_v3_hw.attr, + &dev_attr_intr_coal_ticks_v3_hw.attr, + &dev_attr_intr_coal_count_v3_hw.attr, NULL }; +ATTRIBUTE_GROUPS(host_v3_hw); + #define HISI_SAS_DEBUGFS_REG(x) {#x, x} struct hisi_sas_debugfs_reg_lu { @@ -3156,13 +3155,13 @@ static struct scsi_host_template sht_v3_hw = { .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, - .slave_alloc = sas_slave_alloc, + .slave_alloc = hisi_sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = sas_ioctl, #endif - .shost_attrs = host_attrs_v3_hw, + .shost_groups = host_v3_hw_groups, .tag_alloc_policy = BLK_TAG_ALLOC_RR, .host_reset = hisi_sas_host_reset, .host_tagset = 1, @@ -3687,7 +3686,6 @@ static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba) do_div(timestamp, NSEC_PER_MSEC); hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; - hisi_hba->debugfs_dump_index++; debugfs_snapshot_prepare_v3_hw(hisi_hba); @@ -3703,6 +3701,7 @@ static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba) debugfs_create_files_v3_hw(hisi_hba); debugfs_snapshot_restore_v3_hw(hisi_hba); + hisi_hba->debugfs_dump_index++; } static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file, @@ -4677,15 +4676,15 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) struct sas_ha_struct *sha; int rc, phy_nr, port_nr, i; - rc = pci_enable_device(pdev); + rc = pcim_enable_device(pdev); if (rc) goto err_out; pci_set_master(pdev); - rc = pci_request_regions(pdev, DRV_NAME); + rc = pcim_iomap_regions(pdev, 1 << BAR_NO_V3_HW, DRV_NAME); if (rc) - goto err_out_disable_device; + goto err_out; rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); if (rc) @@ -4693,20 +4692,20 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (rc) { dev_err(dev, "No usable DMA addressing method\n"); rc = -ENODEV; - goto err_out_regions; + goto err_out; } shost = hisi_sas_shost_alloc_pci(pdev); if (!shost) { rc = -ENOMEM; - goto err_out_regions; + goto err_out; } sha = SHOST_TO_SAS_HA(shost); hisi_hba = shost_priv(shost); dev_set_drvdata(dev, sha); - hisi_hba->regs = pcim_iomap(pdev, 5, 0); + hisi_hba->regs = pcim_iomap_table(pdev)[BAR_NO_V3_HW]; if (!hisi_hba->regs) { dev_err(dev, "cannot map register\n"); rc = -ENOMEM; @@ -4761,7 +4760,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) rc = interrupt_preinit_v3_hw(hisi_hba); if (rc) goto err_out_debugfs; - dev_err(dev, "%d hw queues\n", shost->nr_hw_queues); + rc = scsi_add_host(shost, dev); if (rc) goto err_out_free_irq_vectors; @@ -4800,10 +4799,6 @@ err_out_debugfs: err_out_ha: hisi_sas_free(hisi_hba); scsi_host_put(shost); -err_out_regions: - pci_release_regions(pdev); -err_out_disable_device: - pci_disable_device(pdev); err_out: return rc; } @@ -4833,16 +4828,13 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev) struct Scsi_Host *shost = sha->core.shost; pm_runtime_get_noresume(dev); - if (timer_pending(&hisi_hba->timer)) - del_timer(&hisi_hba->timer); + del_timer_sync(&hisi_hba->timer); sas_unregister_ha(sha); flush_workqueue(hisi_hba->wq); sas_remove_host(sha->core.shost); hisi_sas_v3_destroy_irqs(pdev, hisi_hba); - pci_release_regions(pdev); - pci_disable_device(pdev); hisi_sas_free(hisi_hba); debugfs_exit_v3_hw(hisi_hba); scsi_host_put(shost); @@ -4856,7 +4848,7 @@ static void hisi_sas_reset_prepare_v3_hw(struct pci_dev *pdev) int rc; dev_info(dev, "FLR prepare\n"); - set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); hisi_sas_controller_reset_prepare(hisi_hba); rc = disable_host_v3_hw(hisi_hba); @@ -4902,7 +4894,7 @@ static int _suspend_v3_hw(struct device *device) return -ENODEV; } - if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + if (test_and_set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) return -1; scsi_block_requests(shost); @@ -4913,7 +4905,7 @@ static int _suspend_v3_hw(struct device *device) if (rc) { dev_err(dev, "PM suspend: disable host failed rc=%d\n", rc); clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); - clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); scsi_unblock_requests(shost); return rc; } @@ -4952,7 +4944,7 @@ static int _resume_v3_hw(struct device *device) } phys_init_v3_hw(hisi_hba); sas_resume_ha(sha); - clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); return 0; } |