Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: mpi3mr: Fix device loss during enclosure reboot due to zero link speed

During enclosure reboot or expander reset, firmware may report a link
speed of 0 in "Device Add" events while the link is still coming up.
The driver drops such devices, leaving them missing even after the link
recovers.

Fix this by treating link speed 0 as 1.5 Gbps during device addition so
the device is exposed to the OS. The actual link speed will be updated
later when link-up events arrive.

Signed-off-by: Chandrakanth Patil <chandrakanth.patil@broadcom.com>
Link: https://lore.kernel.org/r/20250820084138.228471-2-chandrakanth.patil@broadcom.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Chandrakanth Patil and committed by
Martin K. Petersen
d6c8e8b7 8f5ae30d

+13 -6
+4 -4
drivers/scsi/mpi3mr/mpi3mr_os.c
··· 2049 2049 if (!fwevt->process_evt) 2050 2050 goto evt_ack; 2051 2051 2052 - dprint_event_bh(mrioc, "processing event(0x%02x) in the bottom half handler\n", 2053 - fwevt->event_id); 2052 + dprint_event_bh(mrioc, "processing event(0x%02x) -(0x%08x) in the bottom half handler\n", 2053 + fwevt->event_id, fwevt->evt_ctx); 2054 2054 2055 2055 switch (fwevt->event_id) { 2056 2056 case MPI3_EVENT_DEVICE_ADDED: ··· 3076 3076 } 3077 3077 if (process_evt_bh || ack_req) { 3078 3078 dprint_event_th(mrioc, 3079 - "scheduling bottom half handler for event(0x%02x),ack_required=%d\n", 3080 - evt_type, ack_req); 3079 + "scheduling bottom half handler for event(0x%02x) - (0x%08x), ack_required=%d\n", 3080 + evt_type, le32_to_cpu(event_reply->event_context), ack_req); 3081 3081 sz = event_reply->event_data_length * 4; 3082 3082 fwevt = mpi3mr_alloc_fwevt(sz); 3083 3083 if (!fwevt) {
+9 -2
drivers/scsi/mpi3mr/mpi3mr_transport.c
··· 413 413 sas_address, hba_port); 414 414 if (tgtdev) { 415 415 if (!list_empty(&tgtdev->list)) { 416 - list_del_init(&tgtdev->list); 417 416 was_on_tgtdev_list = 1; 418 - mpi3mr_tgtdev_put(tgtdev); 417 + if (tgtdev->state == MPI3MR_DEV_REMOVE_HS_STARTED) { 418 + list_del_init(&tgtdev->list); 419 + mpi3mr_tgtdev_put(tgtdev); 420 + } 419 421 } 420 422 } 421 423 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); ··· 2081 2079 link_rate = (expander_pg1.negotiated_link_rate & 2082 2080 MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >> 2083 2081 MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT; 2082 + if (link_rate < MPI3_SAS_NEG_LINK_RATE_1_5) 2083 + link_rate = MPI3_SAS_NEG_LINK_RATE_1_5; 2084 2084 mpi3mr_update_links(mrioc, sas_address_parent, 2085 2085 handle, i, link_rate, hba_port); 2086 2086 } ··· 2391 2387 tgtdev->dev_spec.sas_sata_inf.hba_port = hba_port; 2392 2388 2393 2389 link_rate = mpi3mr_get_sas_negotiated_logical_linkrate(mrioc, tgtdev); 2390 + 2391 + if (link_rate < MPI3_SAS_NEG_LINK_RATE_1_5) 2392 + link_rate = MPI3_SAS_NEG_LINK_RATE_1_5; 2394 2393 2395 2394 mpi3mr_update_links(mrioc, sas_address_parent, tgtdev->dev_handle, 2396 2395 parent_phy_number, link_rate, hba_port);