[PATCH v10 13/15] scsi: add BLIST_NO_LUN_1F blacklist flag

From: Phil Pemberton

Date: Fri Oct 09 2026 - 12:34:18 EST


Some multi-LUN devices report unpopulated LUNs with PQ=0/PDT=0x1f.
SCSI scanning adds these as spurious "No Device" entries.

Add BLIST_NO_LUN_1F to set pdt_1f_for_no_lun from scsi_devinfo before
scsi_probe_and_add_lun() checks PDT=0x1f. Setting it here also covers
LUN 0.

Give pdt_1f_for_no_lun its own bool. Sharing bitfield storage with
expecting_lun_change allows scan-time writes and concurrent I/O updates
to overwrite each other.

Assisted-by: LLM
Signed-off-by: Phil Pemberton <philpem@xxxxxxxxxxxxx>
---
drivers/scsi/scsi_scan.c | 3 +++
include/scsi/scsi_device.h | 4 ++--
include/scsi/scsi_devinfo.h | 6 +++---
3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 0f0f243c2561..e34824623294 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1298,6 +1298,9 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *shost,
* PDT=00h Direct-access device (floppy)
* PDT=1Fh none (no FDD connected to the requested logical unit)
*/
+ if (bflags & BLIST_NO_LUN_1F)
+ starget->pdt_1f_for_no_lun = 1;
+
if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) &&
(result[0] & 0x1f) == 0x1f &&
!scsi_is_wlun(lun)) {
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 8694eeadd753..a81a7c8cce18 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -360,13 +360,13 @@ struct scsi_target {
unsigned int single_lun:1; /* Indicates we should only
* allow I/O to one of the luns
* for the device at a time. */
- unsigned int pdt_1f_for_no_lun:1; /* PDT = 0x1f
- * means no lun present. */
unsigned int no_report_luns:1; /* Don't use
* REPORT LUNS for scanning. */
unsigned int expecting_lun_change:1; /* A device has reported
* a 3F/0E UA, other devices on
* the same target will also. */
+ /* Keep scan-time writes separate from I/O-updated bitfields. */
+ bool pdt_1f_for_no_lun; /* PDT = 0x1f means no LUN. */
/* commands actually active on LLD. */
atomic_t target_busy;
atomic_t target_blocked;
diff --git a/include/scsi/scsi_devinfo.h b/include/scsi/scsi_devinfo.h
index 1d79a3b536ce..6957b0705510 100644
--- a/include/scsi/scsi_devinfo.h
+++ b/include/scsi/scsi_devinfo.h
@@ -34,7 +34,8 @@
#define BLIST_NOSTARTONADD ((__force blist_flags_t)(1ULL << 12))
/* do not ask for VPD page size first on some broken targets */
#define BLIST_NO_VPD_SIZE ((__force blist_flags_t)(1ULL << 13))
-#define __BLIST_UNUSED_14 ((__force blist_flags_t)(1ULL << 14))
+/* PDT 0x1f with PQ 0 means no LUN present (e.g. some ATAPI multi-LUN) */
+#define BLIST_NO_LUN_1F ((__force blist_flags_t)(1ULL << 14))
#define __BLIST_UNUSED_15 ((__force blist_flags_t)(1ULL << 15))
#define __BLIST_UNUSED_16 ((__force blist_flags_t)(1ULL << 16))
/* try REPORT_LUNS even for SCSI-2 devs (if HBA supports more than 8 LUNs) */
@@ -77,8 +78,7 @@
#define __BLIST_HIGH_UNUSED (~(__BLIST_LAST_USED | \
(__force blist_flags_t) \
((__force __u64)__BLIST_LAST_USED - 1ULL)))
-#define __BLIST_UNUSED_MASK (__BLIST_UNUSED_14 | \
- __BLIST_UNUSED_15 | \
+#define __BLIST_UNUSED_MASK (__BLIST_UNUSED_15 | \
__BLIST_UNUSED_16 | \
__BLIST_UNUSED_24 | \
__BLIST_UNUSED_27 | \
--
2.43.0