[PATCH v7 0/6] libata-scsi: multi-LUN ATAPI device support
From: Phil Pemberton
Date: Wed Jun 10 2026 - 22:44:49 EST
Some ATAPI devices expose more than one logical unit behind a single ATA
target: Panasonic/COMPAQ PD/CD combo drives (LUN 0 = CD-ROM, LUN 1 =
PD), and Nakamichi CD changers (one LUN per disc slot, up to 7).
libata has historically hard-coded shost->max_lun = 1, so the SCSI
layer never scans past LUN 0 on any ATA-attached device. This series
lifts that restriction for ATAPI devices gated by BLIST_FORCELUN.
Changes since v6
================
Addressing review from Hannes Reinecke (v6 review) and automated
analysis (Sashiko):
Patch 1: MODULE_PARM_DESC clarified to describe the parameter as a
count of LUNs (not a maximum LUN number), and the range corrected from
"1..7" to "1..8" (eight LUN slots, values 0..7).
Patch 2:
- Drop the nr_luns companion field. The ATAPI_MAX_LUN constant (8)
is the correct fixed bound for all iterations; nr_luns adds
complexity without benefit since sdev[] slots not populated are
always NULL. Use ATAPI_MAX_LUN throughout (Hannes Reinecke).
- Fix ata_port_detach UAF window: clear dev->sdev[lun] to NULL before
the spin_unlock, then pass the saved pointer to scsi_remove_device()
(Hannes Reinecke).
- ata_scsi_sdev_destroy: trigger ATA-level detach only when all LUN
slots are NULL, not only on LUN 0 destruction.
- ZPODD: iterate all LUN slots in zpodd_enable_run_wake(),
zpodd_post_poweron(), and zpodd_wake_dev() (Hannes Reinecke).
- ata_scsi_dev_rescan: snapshot all LUN sdevs under the spinlock
before releasing it; release remaining refs on early exit paths.
Patch 3:
- atapi_xlat(): always clear CDB byte 1 bits 7:5 first, then set them
only for non-zero LUNs. This avoids silently zeroing those bits on
every LUN-0 command regardless of LUN, and separates the "zero for
LUN 0" from the "encode LUN" paths.
- On WARN_ON_ONCE overflow, set scmd->result = DID_ERROR before
returning so the SCSI layer does not treat the aborted command as
a success.
Patch 4:
- Move the BLIST_NO_LUN_1F -> pdt_1f_for_no_lun assignment from
scsi_add_lun() to scsi_probe_and_add_lun(), immediately before the
PDT=0x1f check. scsi_add_lun() is called after that check, so the
v6 placement was too late to suppress LUN 0 if it returned
PDT=0x1f.
Patch 5:
- Call ata_scsi_assign_ofnode() before scsi_device_put(), so the
reference to dev->sdev[0] is still held during the OF node
assignment.
Patches 3/6, 4/6, and 5/6 carry Reviewed-by from Hannes Reinecke
(unchanged from v6).
Series structure
================
1/6 ata: libata-scsi: add atapi_max_lun module parameter
2/6 ata: libata-scsi: convert dev->sdev to per-LUN array
3/6 ata: libata-scsi: route non-zero LUN commands for multi-LUN ATAPI
4/6 scsi: add BLIST_NO_LUN_1F blacklist flag
5/6 ata: libata-scsi: probe additional LUNs for multi-LUN ATAPI devices
6/6 scsi: scsi_devinfo: add COMPAQ PD-1 multi-LUN ATAPI device quirk
Testing
=======
Tested on real hardware (Panasonic/COMPAQ LF-1195C on Intel ICH5 PATA):
[x] Boot with CD inserted: sr0 attaches, mount and read files
[x] Boot with PD inserted: sda attaches at correct capacity
(1298496 x 512 B = 634 MiB)
[x] All seven LUNs scanned (atapi_max_lun=7); LUNs 2..6 correctly
report PDT 0x1f and are silently skipped
[x] Single-LUN ATAPI CD-ROM (LITE-ON iHAS124): no regression,
only LUN 0 scanned
Known limitations
=================
Media-change events are not propagated across LUNs of a SINGLELUN
multi-LUN device. The SCSI layer's UA handling is per-sdev. On the
PD/CD combo, swapping media and then accessing the other LUN may return
stale capacity until a manual rescan:
echo 1 > /sys/class/scsi_device/H:0:0:1/device/rescan
A follow-up patch to propagate media-change events to sibling LUNs is
deferred to keep this series focused on the LUN-scanning core.
Phil Pemberton (6):
ata: libata-scsi: add atapi_max_lun module parameter
ata: libata-scsi: convert dev->sdev to per-LUN array
ata: libata-scsi: route non-zero LUN commands for multi-LUN ATAPI
scsi: add BLIST_NO_LUN_1F blacklist flag
ata: libata-scsi: probe additional LUNs for multi-LUN ATAPI devices
scsi: scsi_devinfo: add COMPAQ PD-1 multi-LUN ATAPI device quirk
drivers/ata/libata-acpi.c | 9 +-
drivers/ata/libata-core.c | 16 ++-
drivers/ata/libata-scsi.c | 226 ++++++++++++++++++++++++------------
drivers/ata/libata-zpodd.c | 27 ++++-
drivers/ata/libata.h | 1 +
drivers/scsi/scsi_devinfo.c | 2 +
drivers/scsi/scsi_scan.c | 3 +
include/linux/libata.h | 11 +-
include/scsi/scsi_devinfo.h | 6 +-
9 files changed, 210 insertions(+), 91 deletions(-)
base-commit: a3f75e5e6b023958c92ad03fa2e68e047b6169c4
--
2.43.0