]> www.infradead.org Git - users/hch/misc.git/commitdiff
scsi: mpi3mr: Fix device loss during enclosure reboot due to zero link speed
authorChandrakanth Patil <chandrakanth.patil@broadcom.com>
Wed, 20 Aug 2025 08:41:33 +0000 (14:11 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 26 Aug 2025 01:39:37 +0000 (21:39 -0400)
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>
drivers/scsi/mpi3mr/mpi3mr_os.c
drivers/scsi/mpi3mr/mpi3mr_transport.c

index e467b56949e989436d5120715a4004b460b893af..1582cdbc663021fd4e0e281df9771d07c45380b1 100644 (file)
@@ -2049,8 +2049,8 @@ static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc,
        if (!fwevt->process_evt)
                goto evt_ack;
 
-       dprint_event_bh(mrioc, "processing event(0x%02x) in the bottom half handler\n",
-           fwevt->event_id);
+       dprint_event_bh(mrioc, "processing event(0x%02x) -(0x%08x) in the bottom half handler\n",
+                       fwevt->event_id, fwevt->evt_ctx);
 
        switch (fwevt->event_id) {
        case MPI3_EVENT_DEVICE_ADDED:
@@ -3076,8 +3076,8 @@ void mpi3mr_os_handle_events(struct mpi3mr_ioc *mrioc,
        }
        if (process_evt_bh || ack_req) {
                dprint_event_th(mrioc,
-                       "scheduling bottom half handler for event(0x%02x),ack_required=%d\n",
-                       evt_type, ack_req);
+                   "scheduling bottom half handler for event(0x%02x) - (0x%08x), ack_required=%d\n",
+                   evt_type, le32_to_cpu(event_reply->event_context), ack_req);
                sz = event_reply->event_data_length * 4;
                fwevt = mpi3mr_alloc_fwevt(sz);
                if (!fwevt) {
index c8d6ced5640e9405a28115f4843cc094fa941925..d70f002d6487d50d0fcdfafbdbbc9c7af7693b1c 100644 (file)
@@ -413,9 +413,11 @@ static void mpi3mr_remove_device_by_sas_address(struct mpi3mr_ioc *mrioc,
                         sas_address, hba_port);
        if (tgtdev) {
                if (!list_empty(&tgtdev->list)) {
-                       list_del_init(&tgtdev->list);
                        was_on_tgtdev_list = 1;
-                       mpi3mr_tgtdev_put(tgtdev);
+                       if (tgtdev->state == MPI3MR_DEV_REMOVE_HS_STARTED) {
+                               list_del_init(&tgtdev->list);
+                               mpi3mr_tgtdev_put(tgtdev);
+                       }
                }
        }
        spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);
@@ -2079,6 +2081,8 @@ int mpi3mr_expander_add(struct mpi3mr_ioc *mrioc, u16 handle)
                                link_rate = (expander_pg1.negotiated_link_rate &
                                    MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
                                    MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT;
+                               if (link_rate < MPI3_SAS_NEG_LINK_RATE_1_5)
+                                       link_rate = MPI3_SAS_NEG_LINK_RATE_1_5;
                                mpi3mr_update_links(mrioc, sas_address_parent,
                                    handle, i, link_rate, hba_port);
                        }
@@ -2388,6 +2392,9 @@ int mpi3mr_report_tgtdev_to_sas_transport(struct mpi3mr_ioc *mrioc,
 
        link_rate = mpi3mr_get_sas_negotiated_logical_linkrate(mrioc, tgtdev);
 
+       if (link_rate < MPI3_SAS_NEG_LINK_RATE_1_5)
+               link_rate = MPI3_SAS_NEG_LINK_RATE_1_5;
+
        mpi3mr_update_links(mrioc, sas_address_parent, tgtdev->dev_handle,
            parent_phy_number, link_rate, hba_port);