From nobody Sat Jun 13 15:26:30 2026 Received: from nick.sneptech.io (nick.sneptech.io [178.62.38.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 89F0F22F388; Wed, 6 May 2026 23:45:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.62.38.78 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778111157; cv=none; b=tcDuiXIr5ERtu+xs0xtyK6Km/syYAosYxloeAdJZdQs4zc0LFgCHQDi0nPUFuwVNL0DLjhOJgiPzUgLilXJLrhFwjph4MvJyCoKrBqgjyVxUajNT6yJj+njhAQihhtWf5nICWfPENivgyN9qe7adjE75AxZPFQUUKW1vpq0Np/g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778111157; c=relaxed/simple; bh=Ui1185AFfkku0MdzhMjt01W74TSAjdA+/L8qfGI0kN8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PqxABAUyGSIYy7cxfyAD6fq6fVIdMRcdgLXzFQUCDXwrKGevHqq0C0QVbVM1gsBQOiwqTpe8buSz1CzoTVqBaQp5LD2Qj7Afqni6rmDSlNN9NtZxWJsnW1BhWcyAfImczHa8V+NEOWD6eQZ+mOFB26ozF3MC5tcSdaPAvyo7ORM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=philpem.me.uk; spf=pass smtp.mailfrom=philpem.me.uk; dkim=pass (1024-bit key) header.d=philpem.me.uk header.i=@philpem.me.uk header.b=AH6xv1RP; arc=none smtp.client-ip=178.62.38.78 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=philpem.me.uk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=philpem.me.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=philpem.me.uk header.i=@philpem.me.uk header.b="AH6xv1RP" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1778111155; bh=Ui1185AFfkku0MdzhMjt01W74TSAjdA+/L8qfGI0kN8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AH6xv1RPGN8Umfa77NGr2DOEJMdMmQr5g0yU12azBfK2J0qavGmIcFWUCa7nQV+gT wQiUJNIprDT3/631YBNT0kq0LImdMfJrI3UYhH/rxDyhUTmNkxP6wzUAE4B6U+xPRi kLFu3mV/HywvmDppuX/T70hayKF0r3YH+urVS02M= Received: from wolf.philpem.me.uk (81-187-163-148.ip4.reverse-dns.uk [81.187.163.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) (Authenticated sender: mailrelay_wolf@philpem.me.uk) by nick.sneptech.io (Postfix) with ESMTPSA id 3ABA3BD71D; Wed, 6 May 2026 23:45:55 +0000 (UTC) Received: from cheetah.homenet.philpem.me.uk (cheetah.homenet.philpem.me.uk [10.0.0.32]) by wolf.philpem.me.uk (Postfix) with ESMTPSA id 031995F8AD; Thu, 7 May 2026 00:45:55 +0100 (BST) From: Phil Pemberton To: linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Damien Le Moal , Niklas Cassel , "James E . J . Bottomley" , "Martin K . Petersen" , Hannes Reinecke , Phil Pemberton Subject: [PATCH v4 1/7] ata: libata-scsi: add atapi_max_lun module parameter Date: Thu, 7 May 2026 00:45:42 +0100 Message-ID: <20260506234548.1974603-2-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260506234548.1974603-1-philpem@philpem.me.uk> References: <20260506234548.1974603-1-philpem@philpem.me.uk> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Until now libata has hard-coded shost->max_lun =3D 1 for every ATA host, so the SCSI layer never scans past LUN 0. This blocks support for the small handful of multi-LUN ATAPI devices (Panasonic LF-1195C and COMPAQ PD-1 PD/CD combos export CD on LUN 0 and PD on LUN 1; old Nakamichi MJ-x.y CD changers expose one LUN per disc slot, up to 7). Introduce a libata module parameter, atapi_max_lun, that controls the upper bound of the per-host SCSI LUN scan. Default is 1, preserving current behaviour exactly: out-of-the-box only LUN 0 is scanned. Range is clamped to 1..ATAPI_MAX_LUN (8, the SCSI-2 ceiling). Subsequent patches gate actual LUN>0 probing on BLIST_FORCELUN, so a device must both be on the SCSI device list (or carry the appropriate quirk) and run on a host whose atapi_max_lun has been raised before any extra LUNs are scanned. Reviewed-by: Hannes Reinecke Signed-off-by: Phil Pemberton --- drivers/ata/libata-core.c | 5 +++++ drivers/ata/libata-scsi.c | 2 +- drivers/ata/libata.h | 1 + include/linux/libata.h | 1 + 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 374993031895..8c279b6eb1fb 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -122,6 +122,11 @@ int atapi_passthru16 =3D 1; module_param(atapi_passthru16, int, 0444); MODULE_PARM_DESC(atapi_passthru16, "Enable ATA_16 passthru for ATAPI devic= es (0=3Doff, 1=3Don [default])"); =20 +int atapi_max_lun =3D 1; +module_param(atapi_max_lun, int, 0444); +MODULE_PARM_DESC(atapi_max_lun, + "Maximum LUN to scan on ATAPI devices flagged BLIST_FORCELUN (1 [default]= .. 7)"); + int libata_fua =3D 0; module_param_named(fua, libata_fua, int, 0444); MODULE_PARM_DESC(fua, "FUA support (0=3Doff [default], 1=3Don)"); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 3b65df914ebb..d1665305b552 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -4620,7 +4620,7 @@ int ata_scsi_add_hosts(struct ata_host *host, const s= truct scsi_host_template *s shost->transportt =3D ata_scsi_transport_template; shost->unique_id =3D ap->print_id; shost->max_id =3D 16; - shost->max_lun =3D 1; + shost->max_lun =3D clamp(atapi_max_lun, 1, ATAPI_MAX_LUN); shost->max_channel =3D 1; shost->max_cmd_len =3D 32; =20 diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index b5423b6e97de..96d804d02b99 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -33,6 +33,7 @@ enum { #define ATA_PORT_TYPE_NAME "ata_port" =20 extern int atapi_passthru16; +extern int atapi_max_lun; extern int libata_fua; extern int libata_noacpi; extern int libata_allow_tpm; diff --git a/include/linux/libata.h b/include/linux/libata.h index 00346ce3af5e..27b11577826e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -131,6 +131,7 @@ enum { ATA_SHORT_PAUSE =3D 16, =20 ATAPI_MAX_DRAIN =3D 16 << 10, + ATAPI_MAX_LUN =3D 8, /* SCSI-2 cap (LUN values 0..7) */ =20 ATA_ALL_DEVICES =3D (1 << ATA_MAX_DEVICES) - 1, =20 --=20 2.43.0 From nobody Sat Jun 13 15:26:30 2026 Received: from nick.sneptech.io (nick.sneptech.io [178.62.38.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C9DB32EC09F; Wed, 6 May 2026 23:45:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.62.38.78 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778111158; cv=none; b=bUc55hm7Fcfu6eNIqVgUp2Qe6Yj3l6o0HhucvCSek7SSnxc6n6qeadL71xbADv45RTgInR1xvzOPnEWggdrde/W7G6+JziUBbvXaH5ky12T8yhSEJKuv6BeBAQ04vJkhAqoTRZ1sCAtg+1neXnYSD2IRygVZgBjTL2y0QhnvT3U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778111158; c=relaxed/simple; bh=mVAmpxqV2qCE1As/qdwrTidqDy61MlpaEmn3HQ3cMlg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=L5cJZwDcRIG6azQztHICkKKhz1akSZaT0GmP6YfK1jQby9TxpIf87U5xEtkZqFKodLbE+lJiR1II2m8047kJCXSXBPrbIrPgIjgg+mtVuGR78Y2WrLthS+PldHxys1jG75QOSsCL4nzbccsPLjxgArGgZFEnI9Nxatf1BxQfpqg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=philpem.me.uk; spf=pass smtp.mailfrom=philpem.me.uk; dkim=pass (1024-bit key) header.d=philpem.me.uk header.i=@philpem.me.uk header.b=dfnmMqGk; arc=none smtp.client-ip=178.62.38.78 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=philpem.me.uk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=philpem.me.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=philpem.me.uk header.i=@philpem.me.uk header.b="dfnmMqGk" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1778111155; bh=mVAmpxqV2qCE1As/qdwrTidqDy61MlpaEmn3HQ3cMlg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dfnmMqGk8g+7qJLO1iMDXfbO7PxuUEamKvOsYNVo20QL6QyW4D4aUZnspjKetookd QenJ+X2clSMhsBJpHQn3hIxP0GZDbcaEmtZuwWG5xrBBd+lIC/TVQNzV+oWDWiruiz ouhASC8hqH3D90KiLDo78DITnj1eC6qW03JJMEUA= Received: from wolf.philpem.me.uk (81-187-163-148.ip4.reverse-dns.uk [81.187.163.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) (Authenticated sender: mailrelay_wolf@philpem.me.uk) by nick.sneptech.io (Postfix) with ESMTPSA id 5BDA5BE518; Wed, 6 May 2026 23:45:55 +0000 (UTC) Received: from cheetah.homenet.philpem.me.uk (cheetah.homenet.philpem.me.uk [10.0.0.32]) by wolf.philpem.me.uk (Postfix) with ESMTPSA id 1B13C5FB13; Thu, 7 May 2026 00:45:55 +0100 (BST) From: Phil Pemberton To: linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Damien Le Moal , Niklas Cassel , "James E . J . Bottomley" , "Martin K . Petersen" , Hannes Reinecke , Phil Pemberton Subject: [PATCH v4 2/7] ata: libata-scsi: convert dev->sdev to per-LUN array Date: Thu, 7 May 2026 00:45:43 +0100 Message-ID: <20260506234548.1974603-3-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260506234548.1974603-1-philpem@philpem.me.uk> References: <20260506234548.1974603-1-philpem@philpem.me.uk> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Multi-LUN ATAPI devices (PD/CD combos, CD changers) share a single ata_device but expose multiple scsi_devices. The previous single dev->sdev pointer could only track one LUN, making all other LUNs invisible to code that operates on sdevs: port detach, suspend/resume, ACPI uevent, ZPODD, media change notification, and EH teardown. Replace the scalar struct scsi_device *sdev with a fixed-size array dev->sdev[ATAPI_MAX_LUN] indexed by LUN number, where ATAPI_MAX_LUN is 8 (the SCSI-2 ceiling, LUN values 0..7). Add a companion field dev->nr_luns recording the number of valid entries -- defaults to 1 during ata_dev_init() and is bumped during multi-LUN probe -- so the common single-LUN case iterates one slot, not eight. Add an inline helper ata_dev_scsi_device(dev, lun) that returns dev->sdev[lun] guarded by a WARN_ON_ONCE(lun >=3D dev->nr_luns) bounds check. Use it for the hardcoded LUN-0 references in libata-acpi (uevent kobj), libata-zpodd (disk events, wake notify), and the door-lock and OF-node paths in libata-scsi. Key changes per call site: - ata_scsi_dev_config: assign sdev to dev->sdev[sdev->lun] - ata_scsi_sdev_destroy: clear dev->sdev[sdev->lun]; only trigger ATA-level detach when LUN 0 is destroyed, since removing a higher LUN should not tear down the underlying ATA device - ata_port_detach: iterate dev->nr_luns slots (high->low) - ata_scsi_offline_dev: iterate dev->nr_luns slots - ata_scsi_remove_dev: snapshot and remove all LUN slots, then scsi_remove_device each one outside the lock - ata_scsi_media_change_notify: send event to all populated LUNs - ata_scsi_dev_rescan: resume and rescan each populated LUN - ACPI, ZPODD, ofnode, door-lock: use ata_dev_scsi_device(dev, 0) For single-LUN devices (the vast majority) only dev->sdev[0] is ever populated and dev->nr_luns stays at 1, so existing call paths see no change in behaviour. Signed-off-by: Phil Pemberton --- drivers/ata/libata-acpi.c | 6 +- drivers/ata/libata-core.c | 11 ++- drivers/ata/libata-scsi.c | 151 +++++++++++++++++++------------------ drivers/ata/libata-zpodd.c | 6 +- include/linux/libata.h | 11 ++- 5 files changed, 103 insertions(+), 82 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 4433f626246b..8af35d0b1053 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -153,8 +153,10 @@ static void ata_acpi_uevent(struct ata_port *ap, struc= t ata_device *dev, char *envp[] =3D { event_string, NULL }; =20 if (dev) { - if (dev->sdev) - kobj =3D &dev->sdev->sdev_gendev.kobj; + struct scsi_device *sdev =3D ata_dev_scsi_device(dev, 0); + + if (sdev) + kobj =3D &sdev->sdev_gendev.kobj; } else kobj =3D &ap->dev->kobj; =20 diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 8c279b6eb1fb..ee5a7914c5fd 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5559,6 +5559,7 @@ void ata_dev_init(struct ata_device *dev) dev->pio_mask =3D UINT_MAX; dev->mwdma_mask =3D UINT_MAX; dev->udma_mask =3D UINT_MAX; + dev->nr_luns =3D 1; } =20 /** @@ -6270,11 +6271,15 @@ static void ata_port_detach(struct ata_port *ap) /* Remove scsi devices */ ata_for_each_link(link, ap, HOST_FIRST) { ata_for_each_dev(dev, link, ALL) { - if (dev->sdev) { + int lun; + + for (lun =3D dev->nr_luns - 1; lun >=3D 0; lun--) { + if (!dev->sdev[lun]) + continue; spin_unlock_irqrestore(ap->lock, flags); - scsi_remove_device(dev->sdev); + scsi_remove_device(dev->sdev[lun]); spin_lock_irqsave(ap->lock, flags); - dev->sdev =3D NULL; + dev->sdev[lun] =3D NULL; } } } diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index d1665305b552..59eb97433087 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1131,7 +1131,7 @@ int ata_scsi_dev_config(struct scsi_device *sdev, str= uct queue_limits *lim, if (dev->flags & ATA_DFLAG_TRUSTED) sdev->security_supported =3D 1; =20 - dev->sdev =3D sdev; + dev->sdev[sdev->lun] =3D sdev; return 0; } =20 @@ -1202,10 +1202,10 @@ EXPORT_SYMBOL_GPL(ata_scsi_sdev_configure); * * @sdev is about to be destroyed for hot/warm unplugging. If * this unplugging was initiated by libata as indicated by NULL - * dev->sdev, this function doesn't have to do anything. + * dev->sdev[], this function doesn't have to do anything. * Otherwise, SCSI layer initiated warm-unplug is in progress. - * Clear dev->sdev, schedule the device for ATA detach and invoke - * EH. + * Clear the per-LUN slot; when the last LUN (LUN 0) is destroyed, + * schedule ATA-level detach via EH. * * LOCKING: * Defined by SCSI layer. We don't really care. @@ -1220,11 +1220,12 @@ void ata_scsi_sdev_destroy(struct scsi_device *sdev) =20 spin_lock_irqsave(ap->lock, flags); dev =3D __ata_scsi_find_dev(ap, sdev); - if (dev && dev->sdev) { - /* SCSI device already in CANCEL state, no need to offline it */ - dev->sdev =3D NULL; - dev->flags |=3D ATA_DFLAG_DETACH; - ata_port_schedule_eh(ap); + if (dev && dev->sdev[sdev->lun] =3D=3D sdev) { + dev->sdev[sdev->lun] =3D NULL; + if (sdev->lun =3D=3D 0) { + dev->flags |=3D ATA_DFLAG_DETACH; + ata_port_schedule_eh(ap); + } } spin_unlock_irqrestore(ap->lock, flags); =20 @@ -2912,10 +2913,15 @@ static void atapi_qc_complete(struct ata_queued_cmd= *qc) * avoid this infinite loop. * * This may happen before SCSI scan is complete. Make - * sure qc->dev->sdev isn't NULL before dereferencing. + * sure the LUN-0 sdev isn't NULL before dereferencing. */ - if (qc->cdb[0] =3D=3D ALLOW_MEDIUM_REMOVAL && qc->dev->sdev) - qc->dev->sdev->locked =3D 0; + if (qc->cdb[0] =3D=3D ALLOW_MEDIUM_REMOVAL) { + struct scsi_device *sdev =3D + ata_dev_scsi_device(qc->dev, 0); + + if (sdev) + sdev->locked =3D 0; + } =20 qc->scsicmd->result =3D SAM_STAT_CHECK_CONDITION; ata_qc_done(qc); @@ -4651,7 +4657,7 @@ int ata_scsi_add_hosts(struct ata_host *host, const s= truct scsi_host_template *s #ifdef CONFIG_OF static void ata_scsi_assign_ofnode(struct ata_device *dev, struct ata_port= *ap) { - struct scsi_device *sdev =3D dev->sdev; + struct scsi_device *sdev =3D ata_dev_scsi_device(dev, 0); struct device *d =3D ap->host->dev; struct device_node *np =3D d->of_node; struct device_node *child; @@ -4689,7 +4695,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync) struct scsi_device *sdev; int channel =3D 0, id =3D 0; =20 - if (dev->sdev) + if (dev->sdev[0]) continue; =20 if (ata_is_host_link(link)) @@ -4700,11 +4706,11 @@ void ata_scsi_scan_host(struct ata_port *ap, int sy= nc) sdev =3D __scsi_add_device(ap->scsi_host, channel, id, 0, NULL); if (!IS_ERR(sdev)) { - dev->sdev =3D sdev; + dev->sdev[0] =3D sdev; ata_scsi_assign_ofnode(dev, ap); scsi_device_put(sdev); } else { - dev->sdev =3D NULL; + dev->sdev[0] =3D NULL; } } } @@ -4715,7 +4721,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync) */ ata_for_each_link(link, ap, EDGE) { ata_for_each_dev(dev, link, ENABLED) { - if (!dev->sdev) + if (!dev->sdev[0]) goto exit_loop; } } @@ -4756,7 +4762,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync) * * This function is called from ata_eh_detach_dev() and is responsible for * taking the SCSI device attached to @dev offline. This function is - * called with host lock which protects dev->sdev against clearing. + * called with host lock which protects dev->sdev[] against clearing. * * LOCKING: * spin_lock_irqsave(host lock) @@ -4766,11 +4772,16 @@ void ata_scsi_scan_host(struct ata_port *ap, int sy= nc) */ bool ata_scsi_offline_dev(struct ata_device *dev) { - if (dev->sdev) { - scsi_device_set_state(dev->sdev, SDEV_OFFLINE); - return true; + bool found =3D false; + int lun; + + for (lun =3D dev->nr_luns - 1; lun >=3D 0; lun--) { + if (dev->sdev[lun]) { + scsi_device_set_state(dev->sdev[lun], SDEV_OFFLINE); + found =3D true; + } } - return false; + return found; } =20 /** @@ -4786,49 +4797,38 @@ bool ata_scsi_offline_dev(struct ata_device *dev) static void ata_scsi_remove_dev(struct ata_device *dev) { struct ata_port *ap =3D dev->link->ap; - struct scsi_device *sdev; + struct scsi_device *sdevs[ATAPI_MAX_LUN] =3D {}; unsigned long flags; + int lun; =20 - /* Alas, we need to grab scan_mutex to ensure SCSI device - * state doesn't change underneath us and thus - * scsi_device_get() always succeeds. The mutex locking can - * be removed if there is __scsi_device_get() interface which - * increments reference counts regardless of device state. - */ mutex_lock(&ap->scsi_host->scan_mutex); spin_lock_irqsave(ap->lock, flags); =20 - /* clearing dev->sdev is protected by host lock */ - sdev =3D dev->sdev; - dev->sdev =3D NULL; + for (lun =3D dev->nr_luns - 1; lun >=3D 0; lun--) { + struct scsi_device *sdev =3D dev->sdev[lun]; + + dev->sdev[lun] =3D NULL; + if (!sdev) + continue; =20 - if (sdev) { - /* If user initiated unplug races with us, sdev can go - * away underneath us after the host lock and - * scan_mutex are released. Hold onto it. - */ if (scsi_device_get(sdev) =3D=3D 0) { - /* The following ensures the attached sdev is - * offline on return from ata_scsi_offline_dev() - * regardless it wins or loses the race - * against this function. - */ scsi_device_set_state(sdev, SDEV_OFFLINE); + sdevs[lun] =3D sdev; } else { WARN_ON(1); - sdev =3D NULL; } } =20 spin_unlock_irqrestore(ap->lock, flags); mutex_unlock(&ap->scsi_host->scan_mutex); =20 - if (sdev) { + for (lun =3D dev->nr_luns - 1; lun >=3D 0; lun--) { + if (!sdevs[lun]) + continue; ata_dev_info(dev, "detaching (SCSI %s)\n", - dev_name(&sdev->sdev_gendev)); - - scsi_remove_device(sdev); - scsi_device_put(sdev); + dev_name(&sdevs[lun]->sdev_gendev)); + scsi_remove_device(sdevs[lun]); + scsi_device_put(sdevs[lun]); } } =20 @@ -4865,9 +4865,12 @@ static void ata_scsi_handle_link_detach(struct ata_l= ink *link) */ void ata_scsi_media_change_notify(struct ata_device *dev) { - if (dev->sdev) - sdev_evt_send_simple(dev->sdev, SDEV_EVT_MEDIA_CHANGE, - GFP_ATOMIC); + int lun; + + for (lun =3D 0; lun < dev->nr_luns; lun++) + if (dev->sdev[lun]) + sdev_evt_send_simple(dev->sdev[lun], + SDEV_EVT_MEDIA_CHANGE, GFP_ATOMIC); } =20 /** @@ -5000,37 +5003,39 @@ void ata_scsi_dev_rescan(struct work_struct *work) =20 ata_for_each_link(link, ap, EDGE) { ata_for_each_dev(dev, link, ENABLED) { - struct scsi_device *sdev =3D dev->sdev; + int lun; =20 - /* - * If the port was suspended before this was scheduled, - * bail out. - */ if (ap->pflags & ATA_PFLAG_SUSPENDED) goto unlock_ap; =20 - if (!sdev) - continue; - if (scsi_device_get(sdev)) - continue; - do_resume =3D dev->flags & ATA_DFLAG_RESUMING; =20 - spin_unlock_irqrestore(ap->lock, flags); - if (do_resume) { - ret =3D scsi_resume_device(sdev); - if (ret =3D=3D -EWOULDBLOCK) { - scsi_device_put(sdev); - goto unlock_scan; + for (lun =3D 0; lun < dev->nr_luns; lun++) { + struct scsi_device *sdev =3D dev->sdev[lun]; + + if (!sdev) + continue; + if (scsi_device_get(sdev)) + continue; + + spin_unlock_irqrestore(ap->lock, flags); + if (do_resume) { + ret =3D scsi_resume_device(sdev); + if (ret =3D=3D -EWOULDBLOCK) { + scsi_device_put(sdev); + goto unlock_scan; + } } - dev->flags &=3D ~ATA_DFLAG_RESUMING; + ret =3D scsi_rescan_device(sdev); + scsi_device_put(sdev); + spin_lock_irqsave(ap->lock, flags); + + if (ret) + goto unlock_ap; } - ret =3D scsi_rescan_device(sdev); - scsi_device_put(sdev); - spin_lock_irqsave(ap->lock, flags); =20 - if (ret) - goto unlock_ap; + if (do_resume) + dev->flags &=3D ~ATA_DFLAG_RESUMING; } } =20 diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c index 414e7c63bd85..dca774d8ec05 100644 --- a/drivers/ata/libata-zpodd.c +++ b/drivers/ata/libata-zpodd.c @@ -185,7 +185,7 @@ void zpodd_enable_run_wake(struct ata_device *dev) { struct zpodd *zpodd =3D dev->zpodd; =20 - sdev_disable_disk_events(dev->sdev); + sdev_disable_disk_events(ata_dev_scsi_device(dev, 0)); =20 zpodd->powered_off =3D true; acpi_pm_set_device_wakeup(&dev->tdev, true); @@ -233,14 +233,14 @@ void zpodd_post_poweron(struct ata_device *dev) zpodd->zp_sampled =3D false; zpodd->zp_ready =3D false; =20 - sdev_enable_disk_events(dev->sdev); + sdev_enable_disk_events(ata_dev_scsi_device(dev, 0)); } =20 static void zpodd_wake_dev(acpi_handle handle, u32 event, void *context) { struct ata_device *ata_dev =3D context; struct zpodd *zpodd =3D ata_dev->zpodd; - struct device *dev =3D &ata_dev->sdev->sdev_gendev; + struct device *dev =3D &ata_dev_scsi_device(ata_dev, 0)->sdev_gendev; =20 if (event =3D=3D ACPI_NOTIFY_DEVICE_WAKE && pm_runtime_suspended(dev)) { zpodd->from_notify =3D true; diff --git a/include/linux/libata.h b/include/linux/libata.h index 27b11577826e..70d5e72e35ef 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -722,7 +722,8 @@ struct ata_device { unsigned int devno; /* 0 or 1 */ u64 quirks; /* List of broken features */ unsigned long flags; /* ATA_DFLAG_xxx */ - struct scsi_device *sdev; /* attached SCSI device */ + struct scsi_device *sdev[ATAPI_MAX_LUN]; /* per-LUN SCSI devices */ + unsigned int nr_luns; /* valid entries in sdev[] */ void *private_data; #ifdef CONFIG_ATA_ACPI union acpi_object *gtf_cache; @@ -1715,6 +1716,14 @@ static inline unsigned int ata_dev_absent(const stru= ct ata_device *dev) return ata_class_absent(dev->class); } =20 +static inline struct scsi_device * +ata_dev_scsi_device(struct ata_device *dev, unsigned int lun) +{ + if (WARN_ON_ONCE(lun >=3D dev->nr_luns)) + return NULL; + return dev->sdev[lun]; +} + /* * link helpers */ --=20 2.43.0 From nobody Sat Jun 13 15:26:30 2026 Received: from nick.sneptech.io (nick.sneptech.io [178.62.38.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C9D2D23183C; Wed, 6 May 2026 23:45:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.62.38.78 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778111158; cv=none; b=sd50EhB3oEK8wj1HlWscROYGvkOu87UUTci9d4XARYBJ7QDo3xZC4do5JHoR9j1eNvJ+Wxfh1Nj0aDiOKaeZzPrLrvd44PvpcQnSgL0+c1XkSvYWfbkAeCaOu2djvknR+f0yLYzKl5PqlbD6BouM/5PwXIGwta3wLEWSl/bJhKg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778111158; c=relaxed/simple; bh=iSH+EsUYTi5kjwu7PQRwKavxPbeUI9BWXZgW1s3W2BI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FaNLPezLOzCDzjh9P/SlAZJLviSvZY/F7+M6tnD+GAazp+ZC7IMS4COhcttqYRQ1/+8JUeuDv4/h8QO05DS6TddeptFmxmvTGjmDm2v1bv/TpghlLW+dWJpY8Ck8MKeOJB3Pw1SgYMSrZgtDQ4osONKvIUKNVpJyEnWaO7H45lM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=philpem.me.uk; spf=pass smtp.mailfrom=philpem.me.uk; dkim=pass (1024-bit key) header.d=philpem.me.uk header.i=@philpem.me.uk header.b=F62v5wKV; arc=none smtp.client-ip=178.62.38.78 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=philpem.me.uk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=philpem.me.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=philpem.me.uk header.i=@philpem.me.uk header.b="F62v5wKV" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1778111155; bh=iSH+EsUYTi5kjwu7PQRwKavxPbeUI9BWXZgW1s3W2BI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=F62v5wKVl1qC2w8q7i15aHpdA/vZcwB+fYwH1k3puRfawkeM+hg3/nljzTyCct0lE t7D5/c3oGWADvRcG9oXllwdjK+aUczijIySgdGIBKeuojCQ4G0TK7fV/f+/AmYpgrV jYhbdXoLlsBHDi3v3b8CCUNcVBgGk88N8WskcS28= Received: from wolf.philpem.me.uk (81-187-163-148.ip4.reverse-dns.uk [81.187.163.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) (Authenticated sender: mailrelay_wolf@philpem.me.uk) by nick.sneptech.io (Postfix) with ESMTPSA id 6D2B5BE554; Wed, 6 May 2026 23:45:55 +0000 (UTC) Received: from cheetah.homenet.philpem.me.uk (cheetah.homenet.philpem.me.uk [10.0.0.32]) by wolf.philpem.me.uk (Postfix) with ESMTPSA id 2C2195FC4D; Thu, 7 May 2026 00:45:55 +0100 (BST) From: Phil Pemberton To: linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Damien Le Moal , Niklas Cassel , "James E . J . Bottomley" , "Martin K . Petersen" , Hannes Reinecke , Phil Pemberton Subject: [PATCH v4 3/7] ata: libata-scsi: route non-zero LUN commands for multi-LUN ATAPI Date: Thu, 7 May 2026 00:45:44 +0100 Message-ID: <20260506234548.1974603-4-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260506234548.1974603-1-philpem@philpem.me.uk> References: <20260506234548.1974603-1-philpem@philpem.me.uk> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Two changes are required to route commands to ATAPI LUNs other than 0: 1. __ata_scsi_find_dev(): The existing code rejects any scsi_device with a non-zero LUN, returning NULL and dropping the command on the floor. Hoist a non-zero LUN early-exit ahead of the original channel/id checks: when scsidev->lun is non-zero, allow it through only if the underlying ata_device is ATAPI class. The original LUN-0 path is left structurally unchanged. 2. atapi_xlat(): Older ATAPI devices (SCSI-2 era) expect the LUN in CDB byte 1 bits 7:5 rather than relying on transport-level LUN addressing. Encode scmd->device->lun into those bits, preserving the existing command-specific bits in 4:0. This is required by both the Panasonic PD/CD combos and Nakamichi CD changers. The SCSI layer caps the LUN at shost->max_lun, so a value beyond the device's nr_luns should never reach this point; guard with WARN_ON_ONCE() and return AC_ERR_INVALID if it does, since the 3-bit CDB field cannot represent it. Signed-off-by: Phil Pemberton --- drivers/ata/libata-scsi.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 59eb97433087..7eb735fed4f0 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2956,6 +2956,15 @@ static unsigned int atapi_xlat(struct ata_queued_cmd= *qc) memset(qc->cdb, 0, dev->cdb_len); memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len); =20 + /* + * SCSI-2 CDB LUN encoding: bits 7:5 of byte 1 (3-bit field). + * The SCSI layer caps the LUN at shost->max_lun (<=3D ATAPI_MAX_LUN), + * so this should never trip; warn and reject if it does. + */ + if (WARN_ON_ONCE(scmd->device->lun >=3D dev->nr_luns)) + return AC_ERR_INVALID; + qc->cdb[1] =3D (qc->cdb[1] & 0x1f) | ((u8)scmd->device->lun << 5); + qc->complete_fn =3D atapi_qc_complete; =20 qc->tf.flags |=3D ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; @@ -3066,6 +3075,29 @@ static struct ata_device *__ata_scsi_find_dev(struct= ata_port *ap, { int devno; =20 + /* + * Non-zero LUN is only legal for ATAPI devices, since they can + * legitimately expose more than one LUN (PD/CD combos, CD changers). + * Handle that case up front so the LUN-0 path below stays unchanged. + */ + if (unlikely(scsidev->lun)) { + struct ata_device *dev; + + if (!sata_pmp_attached(ap)) { + if (unlikely(scsidev->channel)) + return NULL; + devno =3D scsidev->id; + } else { + if (unlikely(scsidev->id)) + return NULL; + devno =3D scsidev->channel; + } + dev =3D ata_find_dev(ap, devno); + if (!dev || dev->class !=3D ATA_DEV_ATAPI) + return NULL; + return dev; + } + /* skip commands not addressed to targets we simulate */ if (!sata_pmp_attached(ap)) { if (unlikely(scsidev->channel || scsidev->lun)) --=20 2.43.0 From nobody Sat Jun 13 15:26:30 2026 Received: from nick.sneptech.io (nick.sneptech.io [178.62.38.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E965B30C608; Wed, 6 May 2026 23:45:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.62.38.78 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778111158; cv=none; b=UYKp2Tpzc79N3EqfOWuflOGvpgoLPRKO/wQE6DFA1wfPPTQgKYR1aaNZXBvOy/DjaTXsY1BJ61nsEMIn7mHSwi3ze/V60bKHbXRHFeBGk2uy45u/5gMGUxBKYphoS3XUhfQYJsVuMtAuYW0VuIvJQmr5i5NYDQ4v816ta61q7Ms= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778111158; c=relaxed/simple; bh=4FH1jA71JSDRfOvyJ5eMM5Q9da7Qmo6FiQ07tWl/Uxc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Iy6UPMqwhCJ18I999+2lhJkJSEsJGJWDsTqsetxrxda3tKGvfZ8/ii/AKRlfBd7oO2JUT5owJv4jmuQd3Z52DEdw9wl/V7SsG8iUWJW/sBQUINcGhm/sg9ugu0eqpyhD90O5nbGczUkE2lJM6LEa4vzi4S+kFZDNOfsLf7cfDLY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=philpem.me.uk; spf=pass smtp.mailfrom=philpem.me.uk; dkim=pass (1024-bit key) header.d=philpem.me.uk header.i=@philpem.me.uk header.b=G/bRXbbn; arc=none smtp.client-ip=178.62.38.78 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=philpem.me.uk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=philpem.me.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=philpem.me.uk header.i=@philpem.me.uk header.b="G/bRXbbn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1778111155; bh=4FH1jA71JSDRfOvyJ5eMM5Q9da7Qmo6FiQ07tWl/Uxc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=G/bRXbbnyPTgws+nHXeqBjifNL1HByiobVNzC7kVWb3S7v22DubM7Vtr97rmV6K+q a8NfA2MKiycYfAsW/B7lG+zxd43Bc/pId07jdlnVLakW9skX15OCztFXtmrjPL1zUv 7T7rBQvUSUPgKv5OEmeil0oW2cpLG7y09Ssy0+/I= Received: from wolf.philpem.me.uk (81-187-163-148.ip4.reverse-dns.uk [81.187.163.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) (Authenticated sender: mailrelay_wolf@philpem.me.uk) by nick.sneptech.io (Postfix) with ESMTPSA id 7076BBE5AB; Wed, 6 May 2026 23:45:55 +0000 (UTC) Received: from cheetah.homenet.philpem.me.uk (cheetah.homenet.philpem.me.uk [10.0.0.32]) by wolf.philpem.me.uk (Postfix) with ESMTPSA id 3EE0E5FC52; Thu, 7 May 2026 00:45:55 +0100 (BST) From: Phil Pemberton To: linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Damien Le Moal , Niklas Cassel , "James E . J . Bottomley" , "Martin K . Petersen" , Hannes Reinecke , Phil Pemberton Subject: [PATCH v4 4/7] scsi: add BLIST_NO_LUN_1F blacklist flag Date: Thu, 7 May 2026 00:45:45 +0100 Message-ID: <20260506234548.1974603-5-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260506234548.1974603-1-philpem@philpem.me.uk> References: <20260506234548.1974603-1-philpem@philpem.me.uk> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Some multi-LUN devices respond to INQUIRY on unpopulated LUNs with PQ=3D0 / PDT=3D0x1f instead of the standard PQ=3D3. The SCSI scan layer normally adds such devices (PQ=3D0 means "connected"), producing spurious "No Device" entries. The scsi_target field pdt_1f_for_no_lun already exists to suppress this, but was previously only set by the USB UFI driver. Add BLIST_NO_LUN_1F so the flag can be set per-device from scsi_devinfo, and wire it up in scsi_add_lun() to set starget->pdt_1f_for_no_lun from the blacklist flags. This runs during LUN 0 processing, before the sequential LUN scan probes higher LUNs. Reviewed-by: Damien Le Moal Reviewed-by: Hannes Reinecke Signed-off-by: Phil Pemberton --- drivers/scsi/scsi_scan.c | 2 ++ include/scsi/scsi_devinfo.h | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 7b11bc7de0e3..a8fbe66379b9 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1069,6 +1069,8 @@ static int scsi_add_lun(struct scsi_device *sdev, uns= igned char *inq_result, transport_configure_device(&sdev->sdev_gendev); =20 sdev->sdev_bflags =3D *bflags; + if (sdev->sdev_bflags & BLIST_NO_LUN_1F) + sdev->sdev_target->pdt_1f_for_no_lun =3D 1; =20 if (scsi_device_is_pseudo_dev(sdev)) return SCSI_SCAN_LUN_PRESENT; 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 | \ --=20 2.43.0 From nobody Sat Jun 13 15:26:30 2026 Received: from nick.sneptech.io (nick.sneptech.io [178.62.38.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4F4C13D565D; Wed, 6 May 2026 23:45:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.62.38.78 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778111160; cv=none; b=OlLhGoHJlXOxndmZJ6YGxhNDgMO8Fv6TV17Fre7CshRvmeBv8WH7EOPPVnI4wEFqPi7Hc9sXfqzSv5lIvOwEZGfhHWmbmPG/6nNq397yEm8SDNAW5REoGqn5If6xBk1YbTT32gFEVxRTHj2VI54SDnuf440hdnaisl9ZnMZSVJo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778111160; c=relaxed/simple; bh=RyV4iP2HcFmR1DFPt3oGav97FriSDQg1K7LdVAgsbdw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=C8hBMi6lmc9mk2BkqA5o47Bx9WPquUgN6kSrh7j5JEDDf0bMM9sC25+bJDWd/57EFYZY4msevulO1TesCONoFKEMyLUl59uRoObIOaa7f328JPGQeSRfJF82K6Acfp0xvA6OnqfzBLe+e1XLmVkz8xB/sLMzxXBIYqER2bYI1zE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=philpem.me.uk; spf=pass smtp.mailfrom=philpem.me.uk; dkim=pass (1024-bit key) header.d=philpem.me.uk header.i=@philpem.me.uk header.b=f/pg6lrD; arc=none smtp.client-ip=178.62.38.78 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=philpem.me.uk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=philpem.me.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=philpem.me.uk header.i=@philpem.me.uk header.b="f/pg6lrD" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1778111155; bh=RyV4iP2HcFmR1DFPt3oGav97FriSDQg1K7LdVAgsbdw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f/pg6lrDfdikFMtr5fzWR6935Z+X904GgWklMhc3swbfcMfz7vnTg1N9eiKB49V9l 2uCM38XQ9M8uY6feKtcsiMFJOLx4Lj8/vTshP7vdDLn20LC/AyHxKRBkhhzmmxF1r4 doCJ/eCiwnevcX+CXRnSpAe7/0ySX2ugeTUopm3g= Received: from wolf.philpem.me.uk (81-187-163-148.ip4.reverse-dns.uk [81.187.163.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) (Authenticated sender: mailrelay_wolf@philpem.me.uk) by nick.sneptech.io (Postfix) with ESMTPSA id 87198BE5B1; Wed, 6 May 2026 23:45:55 +0000 (UTC) Received: from cheetah.homenet.philpem.me.uk (cheetah.homenet.philpem.me.uk [10.0.0.32]) by wolf.philpem.me.uk (Postfix) with ESMTPSA id 472385FC54; Thu, 7 May 2026 00:45:55 +0100 (BST) From: Phil Pemberton To: linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Damien Le Moal , Niklas Cassel , "James E . J . Bottomley" , "Martin K . Petersen" , Hannes Reinecke , Phil Pemberton Subject: [PATCH v4 5/7] ata: libata-scsi: probe additional LUNs for multi-LUN ATAPI devices Date: Thu, 7 May 2026 00:45:46 +0100 Message-ID: <20260506234548.1974603-6-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260506234548.1974603-1-philpem@philpem.me.uk> References: <20260506234548.1974603-1-philpem@philpem.me.uk> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" After LUN 0 is added for an ATAPI device, check its BLIST_FORCELUN flag. If set, bump dev->nr_luns to the host's max_lun so the LUN routing in atapi_xlat() accepts the probe INQUIRYs, then call scsi_scan_target() with SCAN_WILD_CARD to trigger the SCSI layer's built-in sequential LUN scan for that target only. This probes LUNs 1..shost->max_lun, driven by the libata atapi_max_lun module parameter. Devices without BLIST_FORCELUN (the vast majority of ATAPI devices) are left with only LUN 0 -- no sequential scan is triggered, so single-LUN devices like the iHAS124 DVD writer are completely unaffected. Non-responding LUNs (PQ=3D0/PDT=3D0x1f) are silently skipped by scsi_probe_and_add_lun() when BLIST_NO_LUN_1F is set on the device via scsi_devinfo. Signed-off-by: Phil Pemberton --- drivers/ata/libata-scsi.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 7eb735fed4f0..b5b79ae94b59 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -4738,12 +4739,30 @@ void ata_scsi_scan_host(struct ata_port *ap, int sy= nc) sdev =3D __scsi_add_device(ap->scsi_host, channel, id, 0, NULL); if (!IS_ERR(sdev)) { - dev->sdev[0] =3D sdev; - ata_scsi_assign_ofnode(dev, ap); + /* + * For multi-LUN ATAPI (BLIST_FORCELUN), bump + * dev->nr_luns to the host max so the LUN + * routing in atapi_xlat() accepts the probe + * INQUIRYs to LUN > 0, then trigger the + * sequential scan. pdt_1f_for_no_lun, set + * during LUN 0 configure, ensures + * non-responding LUNs are silently skipped; + * dev->sdev[] is populated by + * ata_scsi_dev_config() during the scan. + */ + if (dev->class =3D=3D ATA_DEV_ATAPI && + sdev->sdev_bflags & BLIST_FORCELUN) { + dev->nr_luns =3D ap->scsi_host->max_lun; + scsi_scan_target( + &ap->scsi_host->shost_gendev, + channel, id, SCAN_WILD_CARD, + SCSI_SCAN_RESCAN); + } scsi_device_put(sdev); - } else { - dev->sdev[0] =3D NULL; } + + if (dev->sdev[0]) + ata_scsi_assign_ofnode(dev, ap); } } =20 --=20 2.43.0 From nobody Sat Jun 13 15:26:30 2026 Received: from nick.sneptech.io (nick.sneptech.io [178.62.38.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4FBE33D565E; Wed, 6 May 2026 23:45:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.62.38.78 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778111162; cv=none; b=uDwjMFUyfTFoVuAda/q2Mx/n1NsFonOAcjVvQWb1LuV74okd94+LwvlUblJT18xCsArnuWyHHazzgs8DU7N3DS+3PCm6b4rm03ud8ud3OxFOs2uxD1eSWng3kedkNYYRJkOXW9zn4tWCUVd+Mk7rsUOE6eh9M0Oo/F19hsT/8vQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778111162; c=relaxed/simple; bh=NgI+BloTluXJ7eZWq4tfe6pWs03z++jaiAMs+De/a1I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lGUrT4AJRFHslAPnFB6prIVlzTBIFK2uNxnCx1gPgQ1TBattvkxo8A5+YyVHioemMnLNL/3B+HS3ZzmVZ35Ydk/kR4sjMKUlhm1R9nLOnN7tbnswzMlUb9HEA2U7ZCQ+Tq3QYfA7lQq6WKJ08mE+tOy5hiC9XeUbPJlDr6Shfr4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=philpem.me.uk; spf=pass smtp.mailfrom=philpem.me.uk; dkim=pass (1024-bit key) header.d=philpem.me.uk header.i=@philpem.me.uk header.b=gHOt6MzO; arc=none smtp.client-ip=178.62.38.78 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=philpem.me.uk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=philpem.me.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=philpem.me.uk header.i=@philpem.me.uk header.b="gHOt6MzO" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1778111155; bh=NgI+BloTluXJ7eZWq4tfe6pWs03z++jaiAMs+De/a1I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gHOt6MzOnbZcGUUVJDWsQ9SLZQ5mhw3VjCV6DnCqzh0YN/kzu9gWNoWaSHxWujIS4 qNYd0gsvl7fJRtV07RHXGXfOWPR5jC4tRXEsSOGGckaB3ppA9E4uxdnC1CnZMJKgfW UxXTAnOxUkxKJ+HdIVZYeZv3WjkkW8aMNyqS4jJo= Received: from wolf.philpem.me.uk (81-187-163-148.ip4.reverse-dns.uk [81.187.163.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) (Authenticated sender: mailrelay_wolf@philpem.me.uk) by nick.sneptech.io (Postfix) with ESMTPSA id 8EF82BE5BA; Wed, 6 May 2026 23:45:55 +0000 (UTC) Received: from cheetah.homenet.philpem.me.uk (cheetah.homenet.philpem.me.uk [10.0.0.32]) by wolf.philpem.me.uk (Postfix) with ESMTPSA id 4CC415FC56; Thu, 7 May 2026 00:45:55 +0100 (BST) From: Phil Pemberton To: linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Damien Le Moal , Niklas Cassel , "James E . J . Bottomley" , "Martin K . Petersen" , Hannes Reinecke , Phil Pemberton Subject: [PATCH v4 6/7] scsi: scsi_devinfo: add COMPAQ PD-1 multi-LUN ATAPI device quirk Date: Thu, 7 May 2026 00:45:47 +0100 Message-ID: <20260506234548.1974603-7-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260506234548.1974603-1-philpem@philpem.me.uk> References: <20260506234548.1974603-1-philpem@philpem.me.uk> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The COMPAQ PD-1 (OEM Panasonic/Matsushita LF-1195C) is a PD/CD combo drive that exposes two ATAPI LUNs: LUN 0 is a CD-ROM (TYPE_ROM), LUN 1 is a 650 MB PD (TYPE_DISK). Add it to the SCSI device list with: - BLIST_FORCELUN: tells the SCSI layer to scan past LUN 0 - BLIST_SINGLELUN: serialises commands across the two LUNs, since the drive has a single transport and cannot handle concurrent operations on both - BLIST_NO_LUN_1F: the drive returns PQ=3D0/PDT=3D0x1f for unpopulated LUNs instead of PQ=3D3; this flag tells scsi_probe_and_add_lun() to silently skip them The INQUIRY strings as reported by the device are: Vendor: "COMPAQ " (T10 format, space-padded) Product: "PD-1" Reviewed-by: Damien Le Moal Reviewed-by: Hannes Reinecke Signed-off-by: Phil Pemberton --- drivers/scsi/scsi_devinfo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 68a992494b12..bfc2cbd43897 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -150,6 +150,8 @@ static struct { {"COMPAQ", "MSA1000", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD}, {"COMPAQ", "MSA1000 VOLUME", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD}, {"COMPAQ", "HSV110", NULL, BLIST_REPORTLUN2 | BLIST_NOSTARTONADD}, + {"COMPAQ", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN | + BLIST_NO_LUN_1F}, {"DDN", "SAN DataDirector", "*", BLIST_SPARSELUN}, {"DEC", "HSG80", NULL, BLIST_REPORTLUN2 | BLIST_NOSTARTONADD}, {"DELL", "PV660F", NULL, BLIST_SPARSELUN}, --=20 2.43.0 From nobody Sat Jun 13 15:26:30 2026 Received: from nick.sneptech.io (nick.sneptech.io [178.62.38.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5C00A3D6470; Wed, 6 May 2026 23:45:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.62.38.78 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778111160; cv=none; b=H3nYobuP3Q/J17OWUC66WMmb0sTSfUBm9h+Jc1/il7BDv5fpsM6T7NyClkGbl64ZVsuWImyhnkDa3TAPGxXcg1NfPdFWvKPFJvhj55c6DZgRqrOo8HbSqv8J/QzWeEpYmVfGcfIsN6CUqZO+WP8EQ6qK6bORA7fOvglnG+E/HcQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778111160; c=relaxed/simple; bh=1irAv+3MHfTXWESaNzg4xLYuIifqdSJCqBORJrfLkmc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KSxlL+Fjgkm4GkXOclXM/ctE5cgOuX8Vuy4Lgf2Rc5Cn4OMyg6ZHOTU/oDonL5uvstNHqpbhBZw49nRQ1ifb+Y64FmZnfhP9vi/DR7e20It+Xl9NIBxXXflEQLRNSiGFc/JiqEAmbvtKrHyT9J6IYwfrR0bWFr2j+VcN/K01qyU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=philpem.me.uk; spf=pass smtp.mailfrom=philpem.me.uk; dkim=pass (1024-bit key) header.d=philpem.me.uk header.i=@philpem.me.uk header.b=DuQ9oFsh; arc=none smtp.client-ip=178.62.38.78 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=philpem.me.uk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=philpem.me.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=philpem.me.uk header.i=@philpem.me.uk header.b="DuQ9oFsh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1778111155; bh=1irAv+3MHfTXWESaNzg4xLYuIifqdSJCqBORJrfLkmc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DuQ9oFshTbqbKes/2b6cca/7TqqwF6UfoS0hDth/PD0BRVV/GZp0kzpyCUwj9/Ev2 7xpNXR6aOwOgf1VI7rHJX39aecz5S5mKo+fYMcJ8hHGXCN1qTTeJD47HM+P7/psGXz C9zs5bp1okiX42TW65L8Zu4dasrkIFPKE4iBP6pk= Received: from wolf.philpem.me.uk (81-187-163-148.ip4.reverse-dns.uk [81.187.163.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) (Authenticated sender: mailrelay_wolf@philpem.me.uk) by nick.sneptech.io (Postfix) with ESMTPSA id 97B0FBE624; Wed, 6 May 2026 23:45:55 +0000 (UTC) Received: from cheetah.homenet.philpem.me.uk (cheetah.homenet.philpem.me.uk [10.0.0.32]) by wolf.philpem.me.uk (Postfix) with ESMTPSA id 604B15F8AD; Thu, 7 May 2026 00:45:55 +0100 (BST) From: Phil Pemberton To: linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Damien Le Moal , Niklas Cassel , "James E . J . Bottomley" , "Martin K . Petersen" , Hannes Reinecke , Phil Pemberton Subject: [PATCH v4 7/7] scsi: scsi_devinfo: extend BLIST_NO_LUN_1F to MATSHITA and NEC PD-1 variants Date: Thu, 7 May 2026 00:45:48 +0100 Message-ID: <20260506234548.1974603-8-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260506234548.1974603-1-philpem@philpem.me.uk> References: <20260506234548.1974603-1-philpem@philpem.me.uk> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The Panasonic LF-1095/LF-1195 PD/CD combo drive was sold under three OEM identities: COMPAQ "PD-1", MATSHITA "PD-1", and NEC "PD-1 ODX654P". All three are the same drive mechanism with the same firmware family, so they should share the BLIST_NO_LUN_1F quirk that was applied to the COMPAQ variant: PDT 0x1f / PQ 0 INQUIRY responses on non-existent LUNs are treated as "LUN not present" rather than as a phantom sdev. This patch is offered for completeness. It has not been tested on the MATSHITA or NEC variants -- the author only has access to the COMPAQ unit -- but the drives are functionally identical and the flag is a no-op on devices that do not exhibit the PDT 0x1f response. Drop or hold this patch if confirmation on real hardware is preferred before extending the quirk. Reviewed-by: Damien Le Moal Signed-off-by: Phil Pemberton --- drivers/scsi/scsi_devinfo.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index bfc2cbd43897..ab1ffa9433b7 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -201,7 +201,8 @@ static struct { {"LASOUND", "CDX7405", "3.10", BLIST_MAX5LUN | BLIST_SINGLELUN}, {"Marvell", "Console", NULL, BLIST_SKIP_VPD_PAGES}, {"Marvell", "91xx Config", "1.01", BLIST_SKIP_VPD_PAGES}, - {"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, + {"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN | + BLIST_NO_LUN_1F}, {"MATSHITA", "DMC-LC5", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36}, {"MATSHITA", "DMC-LC40", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36}, {"Medion", "Flash XL MMC/SD", "2.6D", BLIST_FORCELUN}, @@ -212,7 +213,8 @@ static struct { {"nCipher", "Fastness Crypto", NULL, BLIST_FORCELUN}, {"NAKAMICH", "MJ-4.8S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"NAKAMICH", "MJ-5.16S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, - {"NEC", "PD-1 ODX654P", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, + {"NEC", "PD-1 ODX654P", NULL, BLIST_FORCELUN | BLIST_SINGLELUN | + BLIST_NO_LUN_1F}, {"NEC", "iStorage", NULL, BLIST_REPORTLUN2}, {"NRC", "MBR-7", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"NRC", "MBR-7.4", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, --=20 2.43.0