Skip to content

Commit 37c4e72

Browse files
Ranjan Kumarmartinkpetersen
authored andcommitted
scsi: Fix sas_user_scan() to handle wildcard and multi-channel scans
sas_user_scan() did not fully process wildcard channel scans (SCAN_WILD_CARD) when a transport-specific user_scan() callback was present. Only channel 0 would be scanned via user_scan(), while the remaining channels were skipped, potentially missing devices. user_scan() invokes updated sas_user_scan() for channel 0, and if successful, iteratively scans remaining channels (1 to shost->max_channel) via scsi_scan_host_selected(). This ensures complete wildcard scanning without affecting transport-specific scanning behavior. Signed-off-by: Ranjan Kumar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 6e0f6aa commit 37c4e72

File tree

2 files changed

+49
-13
lines changed

2 files changed

+49
-13
lines changed

drivers/scsi/scsi_scan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1900,7 +1900,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
19001900

19011901
return 0;
19021902
}
1903-
1903+
EXPORT_SYMBOL(scsi_scan_host_selected);
19041904
static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
19051905
{
19061906
struct scsi_device *sdev;

drivers/scsi/scsi_transport_sas.c

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
#include <scsi/scsi_transport_sas.h>
4141

4242
#include "scsi_sas_internal.h"
43+
#include "scsi_priv.h"
44+
4345
struct sas_host_attrs {
4446
struct list_head rphy_list;
4547
struct mutex lock;
@@ -1683,32 +1685,66 @@ int scsi_is_sas_rphy(const struct device *dev)
16831685
}
16841686
EXPORT_SYMBOL(scsi_is_sas_rphy);
16851687

1686-
1687-
/*
1688-
* SCSI scan helper
1689-
*/
1690-
1691-
static int sas_user_scan(struct Scsi_Host *shost, uint channel,
1692-
uint id, u64 lun)
1688+
static void scan_channel_zero(struct Scsi_Host *shost, uint id, u64 lun)
16931689
{
16941690
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
16951691
struct sas_rphy *rphy;
16961692

1697-
mutex_lock(&sas_host->lock);
16981693
list_for_each_entry(rphy, &sas_host->rphy_list, list) {
16991694
if (rphy->identify.device_type != SAS_END_DEVICE ||
17001695
rphy->scsi_target_id == -1)
17011696
continue;
17021697

1703-
if ((channel == SCAN_WILD_CARD || channel == 0) &&
1704-
(id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) {
1698+
if (id == SCAN_WILD_CARD || id == rphy->scsi_target_id) {
17051699
scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id,
17061700
lun, SCSI_SCAN_MANUAL);
17071701
}
17081702
}
1709-
mutex_unlock(&sas_host->lock);
1703+
}
17101704

1711-
return 0;
1705+
/*
1706+
* SCSI scan helper
1707+
*/
1708+
1709+
static int sas_user_scan(struct Scsi_Host *shost, uint channel,
1710+
uint id, u64 lun)
1711+
{
1712+
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
1713+
int res = 0;
1714+
int i;
1715+
1716+
switch (channel) {
1717+
case 0:
1718+
mutex_lock(&sas_host->lock);
1719+
scan_channel_zero(shost, id, lun);
1720+
mutex_unlock(&sas_host->lock);
1721+
break;
1722+
1723+
case SCAN_WILD_CARD:
1724+
mutex_lock(&sas_host->lock);
1725+
scan_channel_zero(shost, id, lun);
1726+
mutex_unlock(&sas_host->lock);
1727+
1728+
for (i = 1; i <= shost->max_channel; i++) {
1729+
res = scsi_scan_host_selected(shost, i, id, lun,
1730+
SCSI_SCAN_MANUAL);
1731+
if (res)
1732+
goto exit_scan;
1733+
}
1734+
break;
1735+
1736+
default:
1737+
if (channel < shost->max_channel) {
1738+
res = scsi_scan_host_selected(shost, channel, id, lun,
1739+
SCSI_SCAN_MANUAL);
1740+
} else {
1741+
res = -EINVAL;
1742+
}
1743+
break;
1744+
}
1745+
1746+
exit_scan:
1747+
return res;
17121748
}
17131749

17141750

0 commit comments

Comments
 (0)