OSDN Git Service

scsi: libsas: Insert PORTE_BROADCAST_RCVD event for resuming host
authorXiang Chen <chenxiang66@hisilicon.com>
Mon, 20 Dec 2021 11:21:30 +0000 (19:21 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 23 Dec 2021 04:38:30 +0000 (23:38 -0500)
If a new disk is inserted through an expander when the host was suspended,
it will not necessarily be detected as the topology is not re-scanned
during resume.  To detect possible changes in topology during suspension,
insert a PORTE_BROADCAST_RCVD event per port when resuming to trigger a
revalidation.

Link: https://lore.kernel.org/r/1639999298-244569-8-git-send-email-chenxiang66@hisilicon.com
Reviewed-by: John Garry <john.garry@huawei.com>
Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/libsas/sas_init.c

index 43509d1..974c4a3 100644 (file)
@@ -387,6 +387,30 @@ static int phys_suspended(struct sas_ha_struct *ha)
        return rc;
 }
 
+static void sas_resume_insert_broadcast_ha(struct sas_ha_struct *ha)
+{
+       int i;
+
+       for (i = 0; i < ha->num_phys; i++) {
+               struct asd_sas_port *port = ha->sas_port[i];
+               struct domain_device *dev = port->port_dev;
+
+               if (dev && dev_is_expander(dev->dev_type)) {
+                       struct asd_sas_phy *first_phy;
+
+                       spin_lock(&port->phy_list_lock);
+                       first_phy = list_first_entry_or_null(
+                               &port->phy_list, struct asd_sas_phy,
+                               port_phy_el);
+                       spin_unlock(&port->phy_list_lock);
+
+                       if (first_phy)
+                               sas_notify_port_event(first_phy,
+                                       PORTE_BROADCAST_RCVD, GFP_KERNEL);
+               }
+       }
+}
+
 static void _sas_resume_ha(struct sas_ha_struct *ha, bool drain)
 {
        const unsigned long tmo = msecs_to_jiffies(25000);
@@ -419,6 +443,11 @@ static void _sas_resume_ha(struct sas_ha_struct *ha, bool drain)
        scsi_unblock_requests(ha->core.shost);
        if (drain)
                sas_drain_work(ha);
+
+       /* send event PORTE_BROADCAST_RCVD to identify some new inserted
+        * disks for expander
+        */
+       sas_resume_insert_broadcast_ha(ha);
 }
 
 void sas_resume_ha(struct sas_ha_struct *ha)