Skip to content

Commit 39c6332

Browse files
committed
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "All changes in drivers (well technically SES is enclosure services, but its change is minor). The biggest is the write combining change in lpfc followed by the additional NULL checks in mpi3mr" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: ufs: core: Fix shift out of bounds when MAXQ=32 scsi: ufs: core: Move link recovery for hibern8 exit failure to wl_resume scsi: ufs: core: Fix possible NULL pointer dereference in ufshcd_add_command_trace() scsi: snic: MAINTAINERS: Update snic maintainers scsi: snic: Remove unused linkstatus scsi: pm8001: Fix use-after-free in pm8001_queue_command() scsi: mpi3mr: Add NULL checks when resetting request and reply queues scsi: ufs: core: Reset urgent_bkops_lvl to allow runtime PM power mode scsi: ses: Fix devices attaching to different hosts scsi: ufs: core: Fix RPMB region size detection for UFS 2.2 scsi: storvsc: Fix scheduling while atomic on PREEMPT_RT scsi: lpfc: Properly set WC for DPP mapping
2 parents eb71ab2 + 2f38fd9 commit 39c6332

File tree

10 files changed

+97
-50
lines changed

10 files changed

+97
-50
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6212,6 +6212,7 @@ F: drivers/scsi/fnic/
62126212

62136213
CISCO SCSI HBA DRIVER
62146214
M: Karan Tilak Kumar <kartilak@cisco.com>
6215+
M: Narsimhulu Musini <nmusini@cisco.com>
62156216
M: Sesidhar Baddela <sebaddel@cisco.com>
62166217
L: linux-scsi@vger.kernel.org
62176218
S: Supported

drivers/scsi/lpfc/lpfc_init.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12025,6 +12025,8 @@ lpfc_sli4_pci_mem_unset(struct lpfc_hba *phba)
1202512025
iounmap(phba->sli4_hba.conf_regs_memmap_p);
1202612026
if (phba->sli4_hba.dpp_regs_memmap_p)
1202712027
iounmap(phba->sli4_hba.dpp_regs_memmap_p);
12028+
if (phba->sli4_hba.dpp_regs_memmap_wc_p)
12029+
iounmap(phba->sli4_hba.dpp_regs_memmap_wc_p);
1202812030
break;
1202912031
case LPFC_SLI_INTF_IF_TYPE_1:
1203012032
break;

drivers/scsi/lpfc/lpfc_sli.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15977,6 +15977,32 @@ lpfc_dual_chute_pci_bar_map(struct lpfc_hba *phba, uint16_t pci_barset)
1597715977
return NULL;
1597815978
}
1597915979

15980+
static __maybe_unused void __iomem *
15981+
lpfc_dpp_wc_map(struct lpfc_hba *phba, uint8_t dpp_barset)
15982+
{
15983+
15984+
/* DPP region is supposed to cover 64-bit BAR2 */
15985+
if (dpp_barset != WQ_PCI_BAR_4_AND_5) {
15986+
lpfc_log_msg(phba, KERN_WARNING, LOG_INIT,
15987+
"3273 dpp_barset x%x != WQ_PCI_BAR_4_AND_5\n",
15988+
dpp_barset);
15989+
return NULL;
15990+
}
15991+
15992+
if (!phba->sli4_hba.dpp_regs_memmap_wc_p) {
15993+
void __iomem *dpp_map;
15994+
15995+
dpp_map = ioremap_wc(phba->pci_bar2_map,
15996+
pci_resource_len(phba->pcidev,
15997+
PCI_64BIT_BAR4));
15998+
15999+
if (dpp_map)
16000+
phba->sli4_hba.dpp_regs_memmap_wc_p = dpp_map;
16001+
}
16002+
16003+
return phba->sli4_hba.dpp_regs_memmap_wc_p;
16004+
}
16005+
1598016006
/**
1598116007
* lpfc_modify_hba_eq_delay - Modify Delay Multiplier on EQs
1598216008
* @phba: HBA structure that EQs are on.
@@ -16940,9 +16966,6 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
1694016966
uint8_t dpp_barset;
1694116967
uint32_t dpp_offset;
1694216968
uint8_t wq_create_version;
16943-
#ifdef CONFIG_X86
16944-
unsigned long pg_addr;
16945-
#endif
1694616969

1694716970
/* sanity check on queue memory */
1694816971
if (!wq || !cq)
@@ -17128,14 +17151,15 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
1712817151

1712917152
#ifdef CONFIG_X86
1713017153
/* Enable combined writes for DPP aperture */
17131-
pg_addr = (unsigned long)(wq->dpp_regaddr) & PAGE_MASK;
17132-
rc = set_memory_wc(pg_addr, 1);
17133-
if (rc) {
17154+
bar_memmap_p = lpfc_dpp_wc_map(phba, dpp_barset);
17155+
if (!bar_memmap_p) {
1713417156
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1713517157
"3272 Cannot setup Combined "
1713617158
"Write on WQ[%d] - disable DPP\n",
1713717159
wq->queue_id);
1713817160
phba->cfg_enable_dpp = 0;
17161+
} else {
17162+
wq->dpp_regaddr = bar_memmap_p + dpp_offset;
1713917163
}
1714017164
#else
1714117165
phba->cfg_enable_dpp = 0;

drivers/scsi/lpfc/lpfc_sli4.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,9 @@ struct lpfc_sli4_hba {
785785
void __iomem *dpp_regs_memmap_p; /* Kernel memory mapped address for
786786
* dpp registers
787787
*/
788+
void __iomem *dpp_regs_memmap_wc_p;/* Kernel memory mapped address for
789+
* dpp registers with write combining
790+
*/
788791
union {
789792
struct {
790793
/* IF Type 0, BAR 0 PCI cfg space reg mem map */

drivers/scsi/mpi3mr/mpi3mr_fw.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4807,21 +4807,25 @@ void mpi3mr_memset_buffers(struct mpi3mr_ioc *mrioc)
48074807
}
48084808

48094809
for (i = 0; i < mrioc->num_queues; i++) {
4810-
mrioc->op_reply_qinfo[i].qid = 0;
4811-
mrioc->op_reply_qinfo[i].ci = 0;
4812-
mrioc->op_reply_qinfo[i].num_replies = 0;
4813-
mrioc->op_reply_qinfo[i].ephase = 0;
4814-
atomic_set(&mrioc->op_reply_qinfo[i].pend_ios, 0);
4815-
atomic_set(&mrioc->op_reply_qinfo[i].in_use, 0);
4816-
mpi3mr_memset_op_reply_q_buffers(mrioc, i);
4817-
4818-
mrioc->req_qinfo[i].ci = 0;
4819-
mrioc->req_qinfo[i].pi = 0;
4820-
mrioc->req_qinfo[i].num_requests = 0;
4821-
mrioc->req_qinfo[i].qid = 0;
4822-
mrioc->req_qinfo[i].reply_qid = 0;
4823-
spin_lock_init(&mrioc->req_qinfo[i].q_lock);
4824-
mpi3mr_memset_op_req_q_buffers(mrioc, i);
4810+
if (mrioc->op_reply_qinfo) {
4811+
mrioc->op_reply_qinfo[i].qid = 0;
4812+
mrioc->op_reply_qinfo[i].ci = 0;
4813+
mrioc->op_reply_qinfo[i].num_replies = 0;
4814+
mrioc->op_reply_qinfo[i].ephase = 0;
4815+
atomic_set(&mrioc->op_reply_qinfo[i].pend_ios, 0);
4816+
atomic_set(&mrioc->op_reply_qinfo[i].in_use, 0);
4817+
mpi3mr_memset_op_reply_q_buffers(mrioc, i);
4818+
}
4819+
4820+
if (mrioc->req_qinfo) {
4821+
mrioc->req_qinfo[i].ci = 0;
4822+
mrioc->req_qinfo[i].pi = 0;
4823+
mrioc->req_qinfo[i].num_requests = 0;
4824+
mrioc->req_qinfo[i].qid = 0;
4825+
mrioc->req_qinfo[i].reply_qid = 0;
4826+
spin_lock_init(&mrioc->req_qinfo[i].q_lock);
4827+
mpi3mr_memset_op_req_q_buffers(mrioc, i);
4828+
}
48254829
}
48264830

48274831
atomic_set(&mrioc->pend_large_data_sz, 0);

drivers/scsi/pm8001/pm8001_sas.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,9 @@ int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags)
525525
} else {
526526
task->task_done(task);
527527
}
528-
rc = -ENODEV;
529-
goto err_out;
528+
spin_unlock_irqrestore(&pm8001_ha->lock, flags);
529+
pm8001_dbg(pm8001_ha, IO, "pm8001_task_exec device gone\n");
530+
return 0;
530531
}
531532

532533
ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, task);

drivers/scsi/ses.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -528,9 +528,8 @@ struct efd {
528528
};
529529

530530
static int ses_enclosure_find_by_addr(struct enclosure_device *edev,
531-
void *data)
531+
struct efd *efd)
532532
{
533-
struct efd *efd = data;
534533
int i;
535534
struct ses_component *scomp;
536535

@@ -683,7 +682,7 @@ static void ses_match_to_enclosure(struct enclosure_device *edev,
683682
if (efd.addr) {
684683
efd.dev = &sdev->sdev_gendev;
685684

686-
enclosure_for_each_device(ses_enclosure_find_by_addr, &efd);
685+
ses_enclosure_find_by_addr(edev, &efd);
687686
}
688687
}
689688

drivers/scsi/snic/vnic_dev.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ struct vnic_dev {
4242
struct vnic_devcmd_notify *notify;
4343
struct vnic_devcmd_notify notify_copy;
4444
dma_addr_t notify_pa;
45-
u32 *linkstatus;
46-
dma_addr_t linkstatus_pa;
4745
struct vnic_stats *stats;
4846
dma_addr_t stats_pa;
4947
struct vnic_devcmd_fw_info *fw_info;
@@ -650,8 +648,6 @@ int svnic_dev_init(struct vnic_dev *vdev, int arg)
650648

651649
int svnic_dev_link_status(struct vnic_dev *vdev)
652650
{
653-
if (vdev->linkstatus)
654-
return *vdev->linkstatus;
655651

656652
if (!vnic_dev_notify_ready(vdev))
657653
return 0;
@@ -686,11 +682,6 @@ void svnic_dev_unregister(struct vnic_dev *vdev)
686682
sizeof(struct vnic_devcmd_notify),
687683
vdev->notify,
688684
vdev->notify_pa);
689-
if (vdev->linkstatus)
690-
dma_free_coherent(&vdev->pdev->dev,
691-
sizeof(u32),
692-
vdev->linkstatus,
693-
vdev->linkstatus_pa);
694685
if (vdev->stats)
695686
dma_free_coherent(&vdev->pdev->dev,
696687
sizeof(struct vnic_stats),

drivers/scsi/storvsc_drv.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,8 +1856,9 @@ static enum scsi_qc_status storvsc_queuecommand(struct Scsi_Host *host,
18561856
cmd_request->payload_sz = payload_sz;
18571857

18581858
/* Invokes the vsc to start an IO */
1859-
ret = storvsc_do_io(dev, cmd_request, get_cpu());
1860-
put_cpu();
1859+
migrate_disable();
1860+
ret = storvsc_do_io(dev, cmd_request, smp_processor_id());
1861+
migrate_enable();
18611862

18621863
if (ret)
18631864
scsi_dma_unmap(scmnd);

drivers/ufs/core/ufshcd.c

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <linux/pm_opp.h>
2525
#include <linux/regulator/consumer.h>
2626
#include <linux/sched/clock.h>
27+
#include <linux/sizes.h>
2728
#include <linux/iopoll.h>
2829
#include <scsi/scsi_cmnd.h>
2930
#include <scsi/scsi_dbg.h>
@@ -517,8 +518,8 @@ static void ufshcd_add_command_trace(struct ufs_hba *hba, struct scsi_cmnd *cmd,
517518

518519
if (hba->mcq_enabled) {
519520
struct ufs_hw_queue *hwq = ufshcd_mcq_req_to_hwq(hba, rq);
520-
521-
hwq_id = hwq->id;
521+
if (hwq)
522+
hwq_id = hwq->id;
522523
} else {
523524
doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
524525
}
@@ -4389,14 +4390,6 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd)
43894390
spin_unlock_irqrestore(hba->host->host_lock, flags);
43904391
mutex_unlock(&hba->uic_cmd_mutex);
43914392

4392-
/*
4393-
* If the h8 exit fails during the runtime resume process, it becomes
4394-
* stuck and cannot be recovered through the error handler. To fix
4395-
* this, use link recovery instead of the error handler.
4396-
*/
4397-
if (ret && hba->pm_op_in_progress)
4398-
ret = ufshcd_link_recovery(hba);
4399-
44004393
return ret;
44014394
}
44024395

@@ -5249,6 +5242,25 @@ static void ufshcd_lu_init(struct ufs_hba *hba, struct scsi_device *sdev)
52495242
hba->dev_info.rpmb_region_size[1] = desc_buf[RPMB_UNIT_DESC_PARAM_REGION1_SIZE];
52505243
hba->dev_info.rpmb_region_size[2] = desc_buf[RPMB_UNIT_DESC_PARAM_REGION2_SIZE];
52515244
hba->dev_info.rpmb_region_size[3] = desc_buf[RPMB_UNIT_DESC_PARAM_REGION3_SIZE];
5245+
5246+
if (hba->dev_info.wspecversion <= 0x0220) {
5247+
/*
5248+
* These older spec chips have only one RPMB region,
5249+
* sized between 128 kB minimum and 16 MB maximum.
5250+
* No per region size fields are provided (respective
5251+
* REGIONX_SIZE fields always contain zeros), so get
5252+
* it from the logical block count and size fields for
5253+
* compatibility
5254+
*
5255+
* (See JESD220C-2_2 Section 14.1.4.6
5256+
* RPMB Unit Descriptor,* offset 13h, 4 bytes)
5257+
*/
5258+
hba->dev_info.rpmb_region_size[0] =
5259+
(get_unaligned_be64(desc_buf
5260+
+ RPMB_UNIT_DESC_PARAM_LOGICAL_BLK_COUNT)
5261+
<< desc_buf[RPMB_UNIT_DESC_PARAM_LOGICAL_BLK_SIZE])
5262+
/ SZ_128K;
5263+
}
52525264
}
52535265

52545266

@@ -5963,6 +5975,7 @@ static int ufshcd_disable_auto_bkops(struct ufs_hba *hba)
59635975

59645976
hba->auto_bkops_enabled = false;
59655977
trace_ufshcd_auto_bkops_state(hba, "Disabled");
5978+
hba->urgent_bkops_lvl = BKOPS_STATUS_PERF_IMPACT;
59665979
hba->is_urgent_bkops_lvl_checked = false;
59675980
out:
59685981
return err;
@@ -6066,7 +6079,7 @@ static void ufshcd_bkops_exception_event_handler(struct ufs_hba *hba)
60666079
* impacted or critical. Handle these device by determining their urgent
60676080
* bkops status at runtime.
60686081
*/
6069-
if (curr_status < BKOPS_STATUS_PERF_IMPACT) {
6082+
if ((curr_status > BKOPS_STATUS_NO_OP) && (curr_status < BKOPS_STATUS_PERF_IMPACT)) {
60706083
dev_err(hba->dev, "%s: device raised urgent BKOPS exception for bkops status %d\n",
60716084
__func__, curr_status);
60726085
/* update the current status as the urgent bkops level */
@@ -7097,7 +7110,7 @@ static irqreturn_t ufshcd_handle_mcq_cq_events(struct ufs_hba *hba)
70977110

70987111
ret = ufshcd_vops_get_outstanding_cqs(hba, &outstanding_cqs);
70997112
if (ret)
7100-
outstanding_cqs = (1U << hba->nr_hw_queues) - 1;
7113+
outstanding_cqs = (1ULL << hba->nr_hw_queues) - 1;
71017114

71027115
/* Exclude the poll queues */
71037116
nr_queues = hba->nr_hw_queues - hba->nr_queues[HCTX_TYPE_POLL];
@@ -10179,7 +10192,15 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
1017910192
} else {
1018010193
dev_err(hba->dev, "%s: hibern8 exit failed %d\n",
1018110194
__func__, ret);
10182-
goto vendor_suspend;
10195+
/*
10196+
* If the h8 exit fails during the runtime resume
10197+
* process, it becomes stuck and cannot be recovered
10198+
* through the error handler. To fix this, use link
10199+
* recovery instead of the error handler.
10200+
*/
10201+
ret = ufshcd_link_recovery(hba);
10202+
if (ret)
10203+
goto vendor_suspend;
1018310204
}
1018410205
} else if (ufshcd_is_link_off(hba)) {
1018510206
/*

0 commit comments

Comments
 (0)