summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJonathan Cameron <jic23@kernel.org>2026-06-02 15:24:19 +0100
committerJonathan Cameron <jic23@kernel.org>2026-06-02 15:24:19 +0100
commitc82228f76aaa3f77eca3ac22670aa69dd0e59d40 (patch)
treed04d0936d748104c004a69fe35fc63e0bd3cdfdd /drivers/scsi
parent3f2d03ecf22b09da1d92ba06e1ba6e20d16060e9 (diff)
parente43ffb69e0438cddd72aaa30898b4dc446f664f8 (diff)
downloadlinux-next-c82228f76aaa3f77eca3ac22670aa69dd0e59d40.tar.gz
linux-next-c82228f76aaa3f77eca3ac22670aa69dd0e59d40.zip
Merge tag 'v7.1-rc6' into work
Linux 7.1-rc6
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c2
-rw-r--r--drivers/scsi/fcoe/fcoe_ctlr.c2
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v3_hw.c2
-rw-r--r--drivers/scsi/isci/host.c3
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c9
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_scsih.c14
-rw-r--r--drivers/scsi/pmcraid.h2
-rw-r--r--drivers/scsi/scsi_debug.c2
-rw-r--r--drivers/scsi/scsi_devinfo.c1
-rw-r--r--drivers/scsi/scsi_lib.c27
-rw-r--r--drivers/scsi/scsi_transport_fc.c77
-rw-r--r--drivers/scsi/sd.c3
-rw-r--r--drivers/scsi/sg.c2
-rw-r--r--drivers/scsi/smartpqi/smartpqi_init.c1
-rw-r--r--drivers/scsi/sr.c11
-rw-r--r--drivers/scsi/sr.h1
16 files changed, 102 insertions, 57 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index efb08b9b145a..80ab0ff921d4 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -37,7 +37,7 @@
#define TPGS_MODE_EXPLICIT 0x2
#define ALUA_RTPG_SIZE 128
-#define ALUA_FAILOVER_TIMEOUT 60
+#define ALUA_FAILOVER_TIMEOUT 255 /* max 255 (8-bit value) */
#define ALUA_FAILOVER_RETRIES 5
#define ALUA_RTPG_DELAY_MSECS 5
#define ALUA_RTPG_RETRY_DELAY 2
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
index 02cd4410efca..496ddd45f74d 100644
--- a/drivers/scsi/fcoe/fcoe_ctlr.c
+++ b/drivers/scsi/fcoe/fcoe_ctlr.c
@@ -1385,7 +1385,7 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
while (rlen >= sizeof(*desc)) {
dlen = desc->fip_dlen * FIP_BPW;
- if (dlen > rlen)
+ if (dlen < sizeof(*desc) || dlen > rlen)
goto err;
/* Drop CVL if there are duplicate critical descriptors */
if ((desc->fip_dtype < 32) &&
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index fda07b193137..14d563e82d20 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -1491,7 +1491,7 @@ static void prep_ata_v3_hw(struct hisi_hba *hisi_hba,
phy_id = device->phy->identify.phy_identifier;
hdr->dw0 |= cpu_to_le32((1U << phy_id)
<< CMD_HDR_PHY_ID_OFF);
- hdr->dw0 |= CMD_HDR_FORCE_PHY_MSK;
+ hdr->dw0 |= cpu_to_le32(CMD_HDR_FORCE_PHY_MSK);
hdr->dw0 |= cpu_to_le32(4U << CMD_HDR_CMD_OFF);
}
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 6d2f4c831df7..ff199bab5d1a 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1252,6 +1252,9 @@ void isci_host_deinit(struct isci_host *ihost)
wait_for_stop(ihost);
+ /* No further IRQ-driven scheduling can happen past wait_for_stop(). */
+ tasklet_kill(&ihost->completion_tasklet);
+
/* phy stop is after controller stop to allow port and device to
* go idle before shutting down the phys, but the expectation is
* that i/o has been shut off well before we reach this
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 2699e4e09b5b..056cbe50e19e 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -3612,6 +3612,15 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex,
complete(&cmd_fusion->done);
break;
case MPI2_FUNCTION_SCSI_IO_REQUEST: /*Fast Path IO.*/
+ /*
+ * Firmware can send stale/duplicate completions for
+ * commands already returned to the pool. scmd_local
+ * would be NULL for such cases. Skip processing to
+ * avoid NULL pointer access.
+ */
+ if (!scmd_local)
+ break;
+
/* Update load balancing info */
if (fusion->load_balance_info &&
(megasas_priv(cmd_fusion->scmd)->status &
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 6ff788557294..12caffeed3a0 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2738,8 +2738,20 @@ scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim)
pcie_device->enclosure_level,
pcie_device->connector_name);
+ /*
+ * The HBA firmware passes the NVMe drive's MDTS
+ * (Maximum Data Transfer Size) up to the driver. However,
+ * the driver hardcodes a 4K buffer size for the PRP list,
+ * accommodating at most 512 entries. This strictly limits
+ * the maximum supported NVMe I/O transfer to 2 MiB.
+ *
+ * Cap max_hw_sectors to the smaller of the drive's reported
+ * MDTS or the 2 MiB driver limit to prevent kernel oopses.
+ */
+ lim->max_hw_sectors = SZ_2M >> SECTOR_SHIFT;
if (pcie_device->nvme_mdts)
- lim->max_hw_sectors = pcie_device->nvme_mdts / 512;
+ lim->max_hw_sectors = min(lim->max_hw_sectors,
+ pcie_device->nvme_mdts >> SECTOR_SHIFT);
pcie_device_put(pcie_device);
spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h
index 9f59930e8b4f..cd059b7599b4 100644
--- a/drivers/scsi/pmcraid.h
+++ b/drivers/scsi/pmcraid.h
@@ -657,7 +657,7 @@ struct pmcraid_hostrcb {
*/
struct pmcraid_instance {
/* Array of allowed-to-be-exposed resources, initialized from
- * Configutation Table, later updated with CCNs
+ * Configuration Table, later updated with CCNs
*/
struct pmcraid_resource_entry *res_entries;
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 1515495fd9ea..040c5e1e713a 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -6953,7 +6953,7 @@ static int scsi_debug_device_reset(struct scsi_cmnd *SCpnt)
++num_dev_resets;
if (SDEBUG_OPT_ALL_NOISE & sdebug_opts)
- sdev_printk(KERN_INFO, sdp, "doing device reset");
+ sdev_printk(KERN_INFO, sdp, "doing device reset\n");
scsi_debug_stop_all_queued(sdp);
if (devip) {
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index 68a992494b12..c6defe1c3152 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -218,6 +218,7 @@ static struct {
{"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"Promise", "VTrak E310f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC},
{"Promise", "VTrak E610f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC},
{"Promise", "", NULL, BLIST_SPARSELUN},
{"QEMU", "QEMU CD-ROM", NULL, BLIST_SKIP_VPD_PAGES},
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 6e8c7a42603e..85eef401925a 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -575,10 +575,33 @@ void scsi_requeue_run_queue(struct work_struct *work)
void scsi_run_host_queues(struct Scsi_Host *shost)
{
- struct scsi_device *sdev;
+ struct scsi_device *sdev, *prev = NULL;
+ unsigned long flags;
- shost_for_each_device(sdev, shost)
+ spin_lock_irqsave(shost->host_lock, flags);
+ __shost_for_each_device(sdev, shost) {
+ /*
+ * Only skip devices so deep into removal they will never need
+ * another kick to their queues. Thus scsi_device_get() cannot
+ * be used as it would skip devices in SDEV_CANCEL state which
+ * may need a queue kick.
+ */
+ if (sdev->sdev_state == SDEV_DEL ||
+ !get_device(&sdev->sdev_gendev))
+ continue;
+ spin_unlock_irqrestore(shost->host_lock, flags);
+
+ if (prev)
+ put_device(&prev->sdev_gendev);
scsi_run_queue(sdev->request_queue);
+
+ prev = sdev;
+
+ spin_lock_irqsave(shost->host_lock, flags);
+ }
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ if (prev)
+ put_device(&prev->sdev_gendev);
}
static void scsi_uninit_cmd(struct scsi_cmnd *cmd)
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index dce95e361daf..173ed6373f04 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -737,6 +737,37 @@ fc_cn_stats_update(u16 event_type, struct fc_fpin_stats *stats)
}
}
+static void
+fc_fpin_pname_stats_update(struct Scsi_Host *shost,
+ struct fc_rport *attach_rport, u16 event_type,
+ u32 desc_len, u32 fixed_len, u32 pname_count,
+ __be64 *pname_list,
+ void (*stats_update)(u16 event_type,
+ struct fc_fpin_stats *stats))
+{
+ u32 i;
+ struct fc_rport *rport;
+ u64 wwpn;
+
+ if (desc_len < fixed_len)
+ pname_count = 0;
+ else
+ pname_count = min(pname_count, (desc_len - fixed_len) /
+ sizeof(pname_list[0]));
+
+ for (i = 0; i < pname_count; i++) {
+ wwpn = be64_to_cpu(pname_list[i]);
+ rport = fc_find_rport_by_wwpn(shost, wwpn);
+ if (rport &&
+ (rport->roles & FC_PORT_ROLE_FCP_TARGET ||
+ rport->roles & FC_PORT_ROLE_NVME_TARGET)) {
+ if (rport == attach_rport)
+ continue;
+ stats_update(event_type, &rport->fpin_stats);
+ }
+ }
+}
+
/*
* fc_fpin_li_stats_update - routine to update Link Integrity
* event statistics.
@@ -747,13 +778,11 @@ fc_cn_stats_update(u16 event_type, struct fc_fpin_stats *stats)
static void
fc_fpin_li_stats_update(struct Scsi_Host *shost, struct fc_tlv_desc *tlv)
{
- u8 i;
struct fc_rport *rport = NULL;
struct fc_rport *attach_rport = NULL;
struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv;
u16 event_type = be16_to_cpu(li_desc->event_type);
- u64 wwpn;
rport = fc_find_rport_by_wwpn(shost,
be64_to_cpu(li_desc->attached_wwpn));
@@ -764,22 +793,11 @@ fc_fpin_li_stats_update(struct Scsi_Host *shost, struct fc_tlv_desc *tlv)
fc_li_stats_update(event_type, &attach_rport->fpin_stats);
}
- if (be32_to_cpu(li_desc->pname_count) > 0) {
- for (i = 0;
- i < be32_to_cpu(li_desc->pname_count);
- i++) {
- wwpn = be64_to_cpu(li_desc->pname_list[i]);
- rport = fc_find_rport_by_wwpn(shost, wwpn);
- if (rport &&
- (rport->roles & FC_PORT_ROLE_FCP_TARGET ||
- rport->roles & FC_PORT_ROLE_NVME_TARGET)) {
- if (rport == attach_rport)
- continue;
- fc_li_stats_update(event_type,
- &rport->fpin_stats);
- }
- }
- }
+ fc_fpin_pname_stats_update(shost, attach_rport, event_type,
+ be32_to_cpu(li_desc->desc_len),
+ FC_TLV_DESC_LENGTH_FROM_SZ(*li_desc),
+ be32_to_cpu(li_desc->pname_count),
+ li_desc->pname_list, fc_li_stats_update);
if (fc_host->port_name == be64_to_cpu(li_desc->attached_wwpn))
fc_li_stats_update(event_type, &fc_host->fpin_stats);
@@ -827,13 +845,11 @@ static void
fc_fpin_peer_congn_stats_update(struct Scsi_Host *shost,
struct fc_tlv_desc *tlv)
{
- u8 i;
struct fc_rport *rport = NULL;
struct fc_rport *attach_rport = NULL;
struct fc_fn_peer_congn_desc *pc_desc =
(struct fc_fn_peer_congn_desc *)tlv;
u16 event_type = be16_to_cpu(pc_desc->event_type);
- u64 wwpn;
rport = fc_find_rport_by_wwpn(shost,
be64_to_cpu(pc_desc->attached_wwpn));
@@ -844,22 +860,11 @@ fc_fpin_peer_congn_stats_update(struct Scsi_Host *shost,
fc_cn_stats_update(event_type, &attach_rport->fpin_stats);
}
- if (be32_to_cpu(pc_desc->pname_count) > 0) {
- for (i = 0;
- i < be32_to_cpu(pc_desc->pname_count);
- i++) {
- wwpn = be64_to_cpu(pc_desc->pname_list[i]);
- rport = fc_find_rport_by_wwpn(shost, wwpn);
- if (rport &&
- (rport->roles & FC_PORT_ROLE_FCP_TARGET ||
- rport->roles & FC_PORT_ROLE_NVME_TARGET)) {
- if (rport == attach_rport)
- continue;
- fc_cn_stats_update(event_type,
- &rport->fpin_stats);
- }
- }
- }
+ fc_fpin_pname_stats_update(shost, attach_rport, event_type,
+ be32_to_cpu(pc_desc->desc_len),
+ FC_TLV_DESC_LENGTH_FROM_SZ(*pc_desc),
+ be32_to_cpu(pc_desc->pname_count),
+ pc_desc->pname_list, fc_cn_stats_update);
}
/*
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index adc3fa55ca2c..599e75f33334 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2476,8 +2476,7 @@ sd_spinup_disk(struct scsi_disk *sdkp)
{
static const u8 cmd[10] = { TEST_UNIT_READY };
unsigned long spintime_expire = 0;
- int spintime, sense_valid = 0;
- unsigned int the_result;
+ int the_result, spintime, sense_valid = 0;
struct scsi_sense_hdr sshdr;
struct scsi_failure failure_defs[] = {
/* Do not retry Medium Not Present */
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 2b4b2a1a8e44..74cd4e8a61c2 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1801,7 +1801,7 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
}
res = blk_rq_map_user_io(rq, md, hp->dxferp, hp->dxfer_len,
- GFP_ATOMIC, iov_count, iov_count, 1, rw);
+ GFP_KERNEL, iov_count, iov_count, 1, rw);
if (!res) {
srp->bio = rq->bio;
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index b4ed991976d0..2026ac645d6a 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -9427,6 +9427,7 @@ static void pqi_shutdown(struct pci_dev *pci_dev)
pqi_crash_if_pending_command(ctrl_info);
pqi_reset(ctrl_info);
+ pqi_ctrl_unblock_device_reset(ctrl_info);
}
static void pqi_process_lockup_action_param(void)
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 7adb2573f50d..c36c54ecd354 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -395,7 +395,7 @@ static blk_status_t sr_init_command(struct scsi_cmnd *SCpnt)
switch (req_op(rq)) {
case REQ_OP_WRITE:
- if (!cd->writeable)
+ if (get_disk_ro(cd->disk))
goto out;
SCpnt->cmnd[0] = WRITE_10;
cd->cdi.media_written = 1;
@@ -681,6 +681,7 @@ static int sr_probe(struct scsi_device *sdev)
error = -ENOMEM;
if (get_capabilities(cd))
goto fail_minor;
+ cdrom_probe_write_features(&cd->cdi);
sr_vendor_init(cd);
set_capacity(disk, cd->capacity);
@@ -899,14 +900,6 @@ static int get_capabilities(struct scsi_cd *cd)
/*else I don't think it can close its tray
cd->cdi.mask |= CDC_CLOSE_TRAY; */
- /*
- * if DVD-RAM, MRW-W or CD-RW, we are randomly writable
- */
- if ((cd->cdi.mask & (CDC_DVD_RAM | CDC_MRW_W | CDC_RAM | CDC_CD_RW)) !=
- (CDC_DVD_RAM | CDC_MRW_W | CDC_RAM | CDC_CD_RW)) {
- cd->writeable = 1;
- }
-
kfree(buffer);
return 0;
}
diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h
index dc899277b3a4..2d92f9cb6fec 100644
--- a/drivers/scsi/sr.h
+++ b/drivers/scsi/sr.h
@@ -35,7 +35,6 @@ typedef struct scsi_cd {
struct scsi_device *device;
unsigned int vendor; /* vendor code, see sr_vendor.c */
unsigned long ms_offset; /* for reading multisession-CD's */
- unsigned writeable : 1;
unsigned use:1; /* is this device still supportable */
unsigned xa_flag:1; /* CD has XA sectors ? */
unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */