summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorDanilo Krummrich <dakr@kernel.org>2026-01-26 13:23:52 +0100
committerDanilo Krummrich <dakr@kernel.org>2026-01-26 13:23:52 +0100
commiteb3dad518e4da48ab6c6df16aa8895b8b0bd6ecf (patch)
treef960c8ab666af10bccacc947aa42f0bf3b8b54dd /drivers/scsi
parent1cab0874875a1c37f71edf1e1e3029b1cf31d81e (diff)
parent63804fed149a6750ffd28610c5c1c98cce6bd377 (diff)
Merge tag 'v6.19-rc7' into driver-core-next
We need the driver-core fixes in here as well to build on top of. Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c7
-rw-r--r--drivers/scsi/scsi_error.c35
-rw-r--r--drivers/scsi/scsi_lib.c10
-rw-r--r--drivers/scsi/storvsc_drv.c3
5 files changed, 53 insertions, 4 deletions
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
index e52ce9b01f49..9b57312f43f5 100644
--- a/drivers/scsi/bfa/bfa_fcs.c
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -1169,7 +1169,7 @@ bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn)
* This function should be used only if there is any requirement
* to check for FOS version below 6.3.
* To check if the attached fabric is a brocade fabric, use
- * bfa_lps_is_brcd_fabric() which works for FOS versions 6.3
+ * fabric->lps->brcd_switch which works for FOS versions 6.3
* or above only.
*/
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index a3971afc2dd1..a04a5aa0d005 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -878,6 +878,9 @@ qla27xx_copy_multiple_pkt(struct scsi_qla_host *vha, void **pkt,
payload_size = sizeof(purex->els_frame_payload);
}
+ if (total_bytes > sizeof(item->iocb.iocb))
+ total_bytes = sizeof(item->iocb.iocb);
+
pending_bytes = total_bytes;
no_bytes = (pending_bytes > payload_size) ? payload_size :
pending_bytes;
@@ -1163,6 +1166,10 @@ qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt,
total_bytes = (le16_to_cpu(purex->frame_size) & 0x0FFF)
- PURX_ELS_HEADER_SIZE;
+
+ if (total_bytes > sizeof(item->iocb.iocb))
+ total_bytes = sizeof(item->iocb.iocb);
+
pending_bytes = total_bytes;
entry_count = entry_count_remaining = purex->entry_count;
no_bytes = (pending_bytes > sizeof(purex->els_frame_payload)) ?
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index f869108fd969..b6e8730e049e 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -282,11 +282,20 @@ static void scsi_eh_inc_host_failed(struct rcu_head *head)
{
struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu);
struct Scsi_Host *shost = scmd->device->host;
- unsigned int busy = scsi_host_busy(shost);
+ unsigned int busy;
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
shost->host_failed++;
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ /*
+ * The counting of busy requests needs to occur after adding to
+ * host_failed or after the lock acquire for adding to host_failed
+ * to prevent a race with host unbusy and missing an eh wakeup.
+ */
+ busy = scsi_host_busy(shost);
+
+ spin_lock_irqsave(shost->host_lock, flags);
scsi_eh_wakeup(shost, busy);
spin_unlock_irqrestore(shost->host_lock, flags);
}
@@ -1063,6 +1072,9 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
unsigned char *cmnd, int cmnd_size, unsigned sense_bytes)
{
struct scsi_device *sdev = scmd->device;
+#ifdef CONFIG_BLK_INLINE_ENCRYPTION
+ struct request *rq = scsi_cmd_to_rq(scmd);
+#endif
/*
* We need saved copies of a number of fields - this is because
@@ -1115,6 +1127,18 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
(sdev->lun << 5 & 0xe0);
/*
+ * Encryption must be disabled for the commands submitted by the error handler.
+ * Hence, clear the encryption context information.
+ */
+#ifdef CONFIG_BLK_INLINE_ENCRYPTION
+ ses->rq_crypt_keyslot = rq->crypt_keyslot;
+ ses->rq_crypt_ctx = rq->crypt_ctx;
+
+ rq->crypt_keyslot = NULL;
+ rq->crypt_ctx = NULL;
+#endif
+
+ /*
* Zero the sense buffer. The scsi spec mandates that any
* untransferred sense data should be interpreted as being zero.
*/
@@ -1131,6 +1155,10 @@ EXPORT_SYMBOL(scsi_eh_prep_cmnd);
*/
void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)
{
+#ifdef CONFIG_BLK_INLINE_ENCRYPTION
+ struct request *rq = scsi_cmd_to_rq(scmd);
+#endif
+
/*
* Restore original data
*/
@@ -1143,6 +1171,11 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)
scmd->underflow = ses->underflow;
scmd->prot_op = ses->prot_op;
scmd->eh_eflags = ses->eh_eflags;
+
+#ifdef CONFIG_BLK_INLINE_ENCRYPTION
+ rq->crypt_keyslot = ses->rq_crypt_keyslot;
+ rq->crypt_ctx = ses->rq_crypt_ctx;
+#endif
}
EXPORT_SYMBOL(scsi_eh_restore_cmnd);
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 93031326ac3e..4a902c9dfd8b 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -376,6 +376,14 @@ static void scsi_dec_host_busy(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
rcu_read_lock();
__clear_bit(SCMD_STATE_INFLIGHT, &cmd->state);
if (unlikely(scsi_host_in_recovery(shost))) {
+ /*
+ * Ensure the clear of SCMD_STATE_INFLIGHT is visible to
+ * other CPUs before counting busy requests. Otherwise,
+ * reordering can cause CPUs to race and miss an eh wakeup
+ * when no CPU sees all busy requests as done or timed out.
+ */
+ smp_mb();
+
unsigned int busy = scsi_host_busy(shost);
spin_lock_irqsave(shost->host_lock, flags);
@@ -2459,7 +2467,7 @@ EXPORT_SYMBOL(scsi_mode_sense);
* @retries: number of retries before failing
* @sshdr: outpout pointer for decoded sense information.
*
- * Returns zero if unsuccessful or an error if TUR failed. For
+ * Returns zero if successful or an error if TUR failed. For
* removable media, UNIT_ATTENTION sets ->changed flag.
**/
int
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 6e4112143c76..b43d876747b7 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1144,7 +1144,7 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device,
* The current SCSI handling on the host side does
* not correctly handle:
* INQUIRY command with page code parameter set to 0x80
- * MODE_SENSE command with cmd[2] == 0x1c
+ * MODE_SENSE and MODE_SENSE_10 command with cmd[2] == 0x1c
* MAINTENANCE_IN is not supported by HyperV FC passthrough
*
* Setup srb and scsi status so this won't be fatal.
@@ -1154,6 +1154,7 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device,
if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) ||
(stor_pkt->vm_srb.cdb[0] == MODE_SENSE) ||
+ (stor_pkt->vm_srb.cdb[0] == MODE_SENSE_10) ||
(stor_pkt->vm_srb.cdb[0] == MAINTENANCE_IN &&
hv_dev_is_fc(device))) {
vstor_packet->vm_srb.scsi_status = 0;