From nobody Fri Jun 19 07:51:43 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 3E1BB37C112; Sun, 26 Apr 2026 19:09:36 +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=1777230577; cv=none; b=Ee12UQnvG0HKEhvuUYQynMfu/9TVnh0cEH6slF01oXUbdMM8gR/j3IzuaNXX6pvkilk0yMiJrZe0K4EYx2OgVM3zOMGx8Wgl/AYugQbLw5Ezk2GXZuRWYiUuWGGmZsZSEWycJyaxzmmcQ3N6qXpRYF8QaPUC+brfujaWSs7tMRg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777230577; c=relaxed/simple; bh=Ui1185AFfkku0MdzhMjt01W74TSAjdA+/L8qfGI0kN8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=no8bkvgq1wgprVxmtH43Xhu+YtHPMHs1u0lZHSXVYHj7gGH9GPqMKyBnnHbx0Rq6PyQlqndpYTIXKExKs7SbhP4u8+ZWiQ6nQIrcZiT36XBKDpqQcx0kYLP2VDdAN4kdaqP9rMrCnuY9nT9vymK88PLa3gu7+CMsWLS2Z/0YgCE= 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=Pkei29j5; 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="Pkei29j5" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1777230569; bh=Ui1185AFfkku0MdzhMjt01W74TSAjdA+/L8qfGI0kN8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Pkei29j5i5ZucIfwkkAACnm9l1S1pPwvoyUKla9oyvWTeFXZOgjqL/UvNjqynjGyE nYke2/RxVlWmc6G7LM9IZ5YkVH5pfWh2r/7nL2DXeNE5tLqB5A8k7YPLFWX6wAN/bK VoXJJHOZGhYJQ0ZtPE499mEEmkHK+Y37YgVbtk0E= 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) server-digest SHA256) (No client certificate requested) (Authenticated sender: mailrelay_wolf@philpem.me.uk) by nick.sneptech.io (Postfix) with ESMTPSA id 509B8BD366; Sun, 26 Apr 2026 19:09:29 +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 0213D5FBA6; Sun, 26 Apr 2026 20:09:29 +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 v3 1/7] ata: libata-scsi: add atapi_max_lun module parameter Date: Sun, 26 Apr 2026 20:09:14 +0100 Message-ID: <20260426190920.2051289-2-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260426190920.2051289-1-philpem@philpem.me.uk> References: <20260426190920.2051289-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 Reviewed-by: Damien Le Moal --- 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 Fri Jun 19 07:51:43 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 3E26637C118; Sun, 26 Apr 2026 19:09:36 +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=1777230578; cv=none; b=vD7UMwtt7WWUW4VOChIe9LKEIvVaJ7vCsk4SlPg9gbiceTA5JkPd0Bb9LoGV/Pe106qmk/GtmMuyRRjKJVedKloOIybl7IhDa435Sobo102ELm7Qmz7y32zKNbz4OBy96eNtjm5SySs3tKUHPyQiYwvdaHw7umIrTlRgD6Z8Kes= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777230578; c=relaxed/simple; bh=6+URO5az9MZa5bl3gnoa9j7B0TAr9LmTwLLIV+d7biI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=sqpzWsjwuQAigNJtPo1EP5pdoX7Uvmr43AXty9IWhQpqCjs3NasYhELjkKJFTVdrnqMuXDsjgWw+XyJeOfKzEJ2rO/RH+ohH3W55aAooirgwDPYQ/w2A5ICJpajkECK9FCdSBUJ77eo26RIBl4Dmu+voXzi7w6HTWiJMYo+GtSE= 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=IENA5jnv; 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="IENA5jnv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1777230569; bh=6+URO5az9MZa5bl3gnoa9j7B0TAr9LmTwLLIV+d7biI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IENA5jnvimCLy+icZLwzKCqbbWPFPetltLawQqpXswYolxXskE/4OoIEgTPrKPyKL 8LgynZh0mc9PlB5jUSQL7OcsNsvCjlbCjf66G8FeiuEnZadb/Yvzo1QP2ybybWnEJ3 g9QkwSQy8UypicOdIqu/jfA9NrV8EL8T3fr6PUck= 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) server-digest SHA256) (No client certificate requested) (Authenticated sender: mailrelay_wolf@philpem.me.uk) by nick.sneptech.io (Postfix) with ESMTPSA id 5AD46BE5D5; Sun, 26 Apr 2026 19:09:29 +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 0C5D05FC4D; Sun, 26 Apr 2026 20:09:29 +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 v3 2/7] ata: libata-scsi: convert dev->sdev to per-LUN array Date: Sun, 26 Apr 2026 20:09:15 +0100 Message-ID: <20260426190920.2051289-3-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260426190920.2051289-1-philpem@philpem.me.uk> References: <20260426190920.2051289-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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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). 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 all LUN slots (high=E2=86=92low) - ata_scsi_offline_dev: iterate all LUN 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 dev->sdev[0] (LUN 0 remains canonical for ATA-level operations) - ata_scsi_scan_host: uses dev->sdev[0] for the existing LUN-0 add/retry path For single-LUN devices (the vast majority), only dev->sdev[0] is ever populated and the additional slots remain NULL. Reviewed-by: Hannes Reinecke Signed-off-by: Phil Pemberton --- drivers/ata/libata-acpi.c | 4 +- drivers/ata/libata-core.c | 10 ++- drivers/ata/libata-scsi.c | 146 ++++++++++++++++++------------------- drivers/ata/libata-zpodd.c | 6 +- include/linux/libata.h | 2 +- 5 files changed, 86 insertions(+), 82 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 4433f626246b..d07237f66d98 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -153,8 +153,8 @@ static void ata_acpi_uevent(struct ata_port *ap, struct= ata_device *dev, char *envp[] =3D { event_string, NULL }; =20 if (dev) { - if (dev->sdev) - kobj =3D &dev->sdev->sdev_gendev.kobj; + if (dev->sdev[0]) + kobj =3D &dev->sdev[0]->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..f24d38f6ee73 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6270,11 +6270,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 ATAPI_MAX_LUN - 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..317883bac25f 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,10 @@ 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 qc->dev->sdev[0] 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 && qc->dev->sdev[0]) + qc->dev->sdev[0]->locked =3D 0; =20 qc->scsicmd->result =3D SAM_STAT_CHECK_CONDITION; ata_qc_done(qc); @@ -4651,7 +4652,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 dev->sdev[0]; struct device *d =3D ap->host->dev; struct device_node *np =3D d->of_node; struct device_node *child; @@ -4689,7 +4690,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 +4701,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 +4716,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 +4757,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 +4767,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 ATAPI_MAX_LUN - 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 +4792,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 ATAPI_MAX_LUN - 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 ATAPI_MAX_LUN - 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 +4860,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 < ATAPI_MAX_LUN; lun++) + if (dev->sdev[lun]) + sdev_evt_send_simple(dev->sdev[lun], + SDEV_EVT_MEDIA_CHANGE, GFP_ATOMIC); } =20 /** @@ -5000,37 +4998,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 < ATAPI_MAX_LUN; 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..116dd42f8232 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(dev->sdev[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(dev->sdev[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->sdev[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..e2e759d492c7 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -722,7 +722,7 @@ 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 */ void *private_data; #ifdef CONFIG_ATA_ACPI union acpi_object *gtf_cache; --=20 2.43.0 From nobody Fri Jun 19 07:51:43 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 E4CAE36212D; Sun, 26 Apr 2026 19:09:36 +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=1777230581; cv=none; b=G/UIt1Exo626Tq3WjVkmPiNns6rp8JLkTCpQCnnxaOF44OTwqkKJLjzTz5rHbKWHBa1z4KuBABpdzYfBl5DI0HH64kLRgAi/DyhONyK7f3L+NtSq2iwTyOgZCvwmJUJ9GLAzXbo2/PD2/cnmv3FczPoz9S5bfkdsL+MPOqpcwMc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777230581; c=relaxed/simple; bh=5INEidaxPS3KpBzcwlk1svLm8n+Qi1qL50o+7Kyduc4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PyuPc3SwKl1dyuwNe25LS2oQ3Lar9pCZutQzgMbbklQ7gmkekyohATHnjWy8OZVblySmDtI5np4DTa7qoOzyjj8dGtTrJSfM/myS5cRkT0L4RuIwWB1J8tL4d0nIipjxo+pU40U8vf7lhA6CEdHcqRazBdQzJom6ZUlyiiOdiuM= 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=lDUmb9c1; 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="lDUmb9c1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1777230569; bh=5INEidaxPS3KpBzcwlk1svLm8n+Qi1qL50o+7Kyduc4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lDUmb9c1VyrP+q6BiWQBnhA4Z0VMiPbUX6jQvKipIBHM7yFXToWxx2d6jm72RNv1g Mr+EHq8Mra4RXrdAt32vqshE8VLyrWRo65qSu4gd803c59f8V3Dd5gbiUUbfEnuCvX kACixhxt3L5amLObMblQ7r0RlZYyAkuRhArtcq+M= 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 7A8CCBE5D6; Sun, 26 Apr 2026 19:09:29 +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 1E72A5FC55; Sun, 26 Apr 2026 20:09:29 +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 v3 3/7] ata: libata-scsi: route non-zero LUN commands for multi-LUN ATAPI Date: Sun, 26 Apr 2026 20:09:16 +0100 Message-ID: <20260426190920.2051289-4-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260426190920.2051289-1-philpem@philpem.me.uk> References: <20260426190920.2051289-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. Relax both the PMP and non-PMP branches to allow non-zero LUNs through when the underlying ata_device is ATAPI class, since ATAPI devices can legitimately expose multiple LUNs. 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. LUNs beyond 7 cannot be encoded in the 3-bit CDB field; reject them with AC_ERR_INVALID. Signed-off-by: Phil Pemberton --- drivers/ata/libata-scsi.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 317883bac25f..48c7d323d6f9 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2951,6 +2951,11 @@ 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) */ + if (scmd->device->lun >=3D 8) + 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; @@ -3059,19 +3064,27 @@ static struct ata_device *ata_find_dev(struct ata_p= ort *ap, unsigned int devno) static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev) { + struct ata_device *dev; int devno; =20 /* skip commands not addressed to targets we simulate */ if (!sata_pmp_attached(ap)) { - if (unlikely(scsidev->channel || scsidev->lun)) + if (unlikely(scsidev->channel)) return NULL; devno =3D scsidev->id; } else { - if (unlikely(scsidev->id || scsidev->lun)) + if (unlikely(scsidev->id)) return NULL; devno =3D scsidev->channel; } =20 + if (unlikely(scsidev->lun)) { + dev =3D ata_find_dev(ap, devno); + if (!dev || dev->class !=3D ATA_DEV_ATAPI) + return NULL; + return dev; + } + return ata_find_dev(ap, devno); } =20 --=20 2.43.0 From nobody Fri Jun 19 07:51:43 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 E4D3837BE6A; Sun, 26 Apr 2026 19:09:36 +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=1777230580; cv=none; b=d9SlhErFQFWTWs0GETQj/5xPr88yhBp/sQuzN4/BrMEUqgLdV4ozGQriThWHFIP77fAC0Ye8KX66kAcTVu9XMapWMtcvBHF1IRzWHkeFX58nvtNCHZskQj75OQUrrdMbNdMmnoxVvNPN6Iyg/aeWJAxmSKpE7NPvH7xGEwgyN2M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777230580; c=relaxed/simple; bh=f+CG9Amv2WmTE/Mh+QJe3KaJuRDqAPb8S1O+7kMivFU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YbRn0/Eq4hvEowZC6YK5EWJUrFiv5Lwhajb2RSaV+EJESkeaPRoQuMCsw0zVnrx0SGDLOfNAxKdEqtuKF+Awh6ZUJdmm477N6JhvCvueh1LWbWcRF1nDz+JxFccxR62Vt2kGF8n7OLlRuPsJKZICuEtfh5xECLEuY9kMAmUvFj4= 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=a/kAFWmx; 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="a/kAFWmx" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1777230569; bh=f+CG9Amv2WmTE/Mh+QJe3KaJuRDqAPb8S1O+7kMivFU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a/kAFWmxAI3Z5zTkBrwGhzr7Q9QWP/XGAbI2tiv4ahh3E2bY0v2nx56DuN4oS8Ar1 3iF08x9g6ZbsFRWP9UU3TXHjEQqZqjzLTAegXEf3IVkW9PScMTnjcgEgO04h2S25Ol LDIg5GANxLDoDm0edCeTjqNmPVXZn65AFysw7Mlw= 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 83174BE5D7; Sun, 26 Apr 2026 19:09:29 +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 314E25FC56; Sun, 26 Apr 2026 20:09:29 +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 v3 4/7] scsi: add BLIST_NO_LUN_1F blacklist flag Date: Sun, 26 Apr 2026 20:09:17 +0100 Message-ID: <20260426190920.2051289-5-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260426190920.2051289-1-philpem@philpem.me.uk> References: <20260426190920.2051289-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. Signed-off-by: Phil Pemberton Reviewed-by: Damien Le Moal Reviewed-by: Hannes Reinecke --- drivers/scsi/scsi_scan.c | 3 +++ include/scsi/scsi_devinfo.h | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 7b11bc7de0e3..d3f0540d79a2 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1070,6 +1070,9 @@ static int scsi_add_lun(struct scsi_device *sdev, uns= igned char *inq_result, =20 sdev->sdev_bflags =3D *bflags; =20 + if (*bflags & BLIST_NO_LUN_1F) + sdev->sdev_target->pdt_1f_for_no_lun =3D 1; + if (scsi_device_is_pseudo_dev(sdev)) return SCSI_SCAN_LUN_PRESENT; =20 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 Fri Jun 19 07:51:43 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 7EC3B37C108; Sun, 26 Apr 2026 19:09:39 +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=1777230584; cv=none; b=jzXwBuUA54OrG6m3B+2eZ/xZNxtSLgXr8WBI/1p8VHq7/YvRCiR16aM2TfGnfaioJg306HV3qEIStiI7JxNdoAh9aCobQCRNzaV2qp/TmRGG4PpXwsjJK5krT0VV8SRsbu72R2bAGH7TI/JyZlUhFEQrB7H8LUrR5NCKuCMTehI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777230584; c=relaxed/simple; bh=FbOQbJbQwX4HDdjMy+Pjy5LUOfdit7DkdhbmA+zqbrU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YrPirjxbwf9YwJRuJoU1fOMRAqhmfZq11j/5TTGQUjko2b9NCMJtkhGKotYC7kFSTXCNT923DRnQpJUzm7vsws09oQ9EoXmZN4tXRGWv/yJIo7dBNdK6G5PDEvayuZ/FBzHr+bzLYiPS5MIX/U183XpSC70VvP6kASbRLW7H5uw= 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=L8ZQ32ym; 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="L8ZQ32ym" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1777230569; bh=FbOQbJbQwX4HDdjMy+Pjy5LUOfdit7DkdhbmA+zqbrU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L8ZQ32ymQlEQnhuznZm29yzzZW4HpgcblUouHGtSHEc1+TXUUA5AosQVmOYOIvrX/ qsRFVRpQYnHZ9K7Q7eHuKLQ6BLLRWJEIzZ6HuNcju5AZL8lC6sHO6K+csQ4yksSTtC EGrhS8r8FwVf7/OblpJ6friOPq4A97OL7HTpbgUA= 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 97685BEFF0; Sun, 26 Apr 2026 19:09:29 +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 3D11B5FC57; Sun, 26 Apr 2026 20:09:29 +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 v3 5/7] ata: libata-scsi: probe additional LUNs for multi-LUN ATAPI devices Date: Sun, 26 Apr 2026 20:09:18 +0100 Message-ID: <20260426190920.2051289-6-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260426190920.2051289-1-philpem@philpem.me.uk> References: <20260426190920.2051289-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, 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 atapi_max_lun module parameter from patch 1/6. 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 (see patch 4/6). Signed-off-by: Phil Pemberton --- drivers/ata/libata-scsi.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 48c7d323d6f9..fc719e3d7d60 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -4700,7 +4701,6 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync) repeat: ata_for_each_link(link, ap, EDGE) { ata_for_each_dev(dev, link, ENABLED) { - struct scsi_device *sdev; int channel =3D 0, id =3D 0; =20 if (dev->sdev[0]) @@ -4711,15 +4711,34 @@ void ata_scsi_scan_host(struct ata_port *ap, int sy= nc) else channel =3D link->pmp; =20 - 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); - scsi_device_put(sdev); - } else { - dev->sdev[0] =3D NULL; + { + struct scsi_device *sdev; + + sdev =3D __scsi_add_device(ap->scsi_host, + channel, id, 0, NULL); + if (!IS_ERR(sdev)) { + /* + * For multi-LUN ATAPI (BLIST_FORCELUN), + * trigger the sequential LUN 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 callbacks. + */ + if (dev->class =3D=3D ATA_DEV_ATAPI && + sdev->sdev_bflags & BLIST_FORCELUN) + scsi_scan_target( + &ap->scsi_host->shost_gendev, + channel, id, + SCAN_WILD_CARD, + SCSI_SCAN_RESCAN); + scsi_device_put(sdev); + } } + + if (dev->sdev[0]) + ata_scsi_assign_ofnode(dev, ap); } } =20 --=20 2.43.0 From nobody Fri Jun 19 07:51:43 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 19DC137CD23; Sun, 26 Apr 2026 19:09:38 +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=1777230582; cv=none; b=ACNNCDSQPCinWKHln/dvUBrruBzBFIKpNxanT0pEJyCNEqUQUszs1kWMMx+EQzlg/sP0A0x7bvxDgs9+YLXjFsnFeafPgY8F1V6acHP6IIHhqqdH+6imW5KshKb5EVsXVjCVKFz2wMgOX3Chrd8IWsh18TEs6GNxnbdV++rr/O4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777230582; c=relaxed/simple; bh=1oZVA9rjnfl8CikmaeVN1WdSpPfh+pFNawRzT3Czi6A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CrO1uppU3ba0peS7bkbqlfYQ6t/pdQO//8UaxFGtPnYcBzkALSFVgtXOsq1tSrSKGNPvqdY/xhfeyyYFNrURo0rqY8NHkrXymObW6RDB30T4XuDhKN2xK/XyvTiSryD1i1s3CBSdtmbyXcU584Qz0gBXDeyWlJFlShWc4C8KMA4= 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=nshFi3cU; 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="nshFi3cU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1777230569; bh=1oZVA9rjnfl8CikmaeVN1WdSpPfh+pFNawRzT3Czi6A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nshFi3cUXeWvO8fp8pjjkZtanOQmq0laYdsvX1grBN9NXs/lI0SXaP2UEMmAU+kpZ LjmoT8q456A7P9RcfZzPQdhe01O357N6Jtn6+aTZldaCefsJFctKjADA9lQIxpn30n GV3cWmir6Io87sbkjzNdYil+T4CGXV5PmiORoD/g= 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 93748BECB0; Sun, 26 Apr 2026 19:09:29 +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 4C0005FC59; Sun, 26 Apr 2026 20:09:29 +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 v3 6/7] scsi: scsi_devinfo: add COMPAQ PD-1 multi-LUN ATAPI device quirk Date: Sun, 26 Apr 2026 20:09:19 +0100 Message-ID: <20260426190920.2051289-7-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260426190920.2051289-1-philpem@philpem.me.uk> References: <20260426190920.2051289-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" Signed-off-by: Phil Pemberton Reviewed-by: Damien Le Moal Reviewed-by: Hannes Reinecke --- 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 Fri Jun 19 07:51:43 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 1997637CD22; Sun, 26 Apr 2026 19:09:39 +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=1777230581; cv=none; b=kF4oVumolbjEplO4J/KoKwPPAu8yCnW+vSBeyet9AjSNTlfVHcavcS0RJGCGz/qdstIcUtFneAGIm5llacx8gP5791KLoiAVK7hOhB8P/JSkTJUwB/j98krFncbs6JJKOuiPORNmWnGatC2YbyWHNR2Yu7EgQQM/hx+troPoTp8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777230581; c=relaxed/simple; bh=PBwfDz5omNpfcINQQatgifpJDGZJ35fjbov7gbgVjaw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hFuB+XH6U9p9RWuEjhbbU0ltH/408i+OUTg0cJNCLNQzQP7gcnrEVRrU1uGtYeCdvwHNeYry1cLRc/YchYzQs8+1YZHuTWGlkST9GpvL53GxYCNGpquoS7PlqsGrhNJGudvfW1wPpwqqlO9qLMbxB/HvOolKV4skPfRIG4Qi7Y8= 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=wXdfADVr; 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="wXdfADVr" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1777230569; bh=PBwfDz5omNpfcINQQatgifpJDGZJ35fjbov7gbgVjaw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=wXdfADVrtOsJLbNKKq/D8I8PAOqyiVjSVCaf5veQfGh8F9CiqF1vVq7qcrgCyGWrk NDIMFv5owDwfTwqQ4R9ZrFB2Q2flUKNRdYp/5T/7w/Y9pFc961d7bnsovoukNk5H41 vMu7+GbV+pwhfIpa1Uf0pWopTU/S1aTbf0oYqLEw= 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 95B97BEFED; Sun, 26 Apr 2026 19:09:29 +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 529ED5FC5A; Sun, 26 Apr 2026 20:09:29 +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 v3 7/7] scsi: scsi_devinfo: extend BLIST_NO_LUN_1F to MATSHITA and NEC PD-1 variants Date: Sun, 26 Apr 2026 20:09:20 +0100 Message-ID: <20260426190920.2051289-8-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260426190920.2051289-1-philpem@philpem.me.uk> References: <20260426190920.2051289-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. Signed-off-by: Phil Pemberton Reviewed-by: Damien Le Moal Reviewed-by: Hannes Reinecke --- 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