From nobody Thu Jun 18 08:18:08 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 8E063393DF9; Mon, 20 Apr 2026 12:45:25 +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=1776689127; cv=none; b=cz5/JIEE4nH5KjcnOnOBkEE4OhGny8HJjiuKR3NJjOF3oarpnGqp/hUqVnzrWKLjFh2p6EHREAzqAoqCpe4/pLxFdQEw7JkSeXLoZRVraZ1nxwGx0Cv/grJBconxF8ZUCU04Bl1SEJm9bCZJ1EROpKzLR1a/8hX9uWlI32zP/0Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776689127; c=relaxed/simple; bh=IsQYB9LYP2StV7D93d0U0QPltWvtmbEQheG5KxO1iFk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=A6BqElmxZQVEfpgqYT22xZBRyNX6PKIjXFsoEa4aX7Hn28Nt2IObPru7sCt4FIV+cKSkDDbQ5ho7zuka6H6PGa5XOWZsimvguWLtU1iSVE4ZUgppLkxAvpc+yj0AGVqoGByluqQReAbG1j9LdCZxbe38DlAZkXJ2P0NA/9fVJXg= 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=FZUbyZKg; 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="FZUbyZKg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1776687809; bh=IsQYB9LYP2StV7D93d0U0QPltWvtmbEQheG5KxO1iFk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FZUbyZKgJLFAzEaox7bK5/6kz2r6+nyNEbV0smo3ZzaReae7EP8JE46KyE8KJYoCw 8BSTnDj8hMal1SJ/Y/bbkhueQ/Z0MquGVF12+Qb6hOUsVaCNh9fC/NEuIDnUlIH6wM 4C7usrl57otnvKj8X4YWrUS+I6qEsIpGGIP9kd4c= 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 29798BEFDF; Mon, 20 Apr 2026 12:23: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 92E385FC55; Mon, 20 Apr 2026 13:23:28 +0100 (BST) From: Phil Pemberton To: Damien Le Moal , Niklas Cassel Cc: "James E . J . Bottomley" , "Martin K . Petersen" , Hannes Reinecke , linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Phil Pemberton Subject: [PATCH v2 1/5] ata: libata-scsi: add atapi_max_lun module parameter Date: Mon, 20 Apr 2026 13:23:17 +0100 Message-ID: <20260420122321.4161027-2-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260420122321.4161027-1-philpem@philpem.me.uk> References: <20260420122321.4161027-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. Signed-off-by: Phil Pemberton Reviewed-by: Hannes Reinecke Reviewed-by: Martin K. Petersen --- 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 Thu Jun 18 08:18:08 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 A449A40DFCA; Mon, 20 Apr 2026 12:40:25 +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=1776688827; cv=none; b=RlLXpqh3bQFqTs4JiQkaYgy96WGNvswWtq9XsxZb9hjko/zgcfrN3JAlPsJ7v8lL0KC2w0pmyBzk+4v8J6sJ0PH90HeBZfPO47d0e4llDLA+Dc0VgdXb6HP091883VmOQoqZtIE1e6Y+AQe7/rOi7D0K/RbMFJcHoftITkRzDOM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776688827; c=relaxed/simple; bh=vRT5e1DqiM/5f3FADuR9Az/ABfSzGFffqKBSWG1K5sw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Ulykxo7mDrTFolOwyz9MDnonMACakGHt56jusxyvqnHniTQxp6ALWeRSwqIiQjvtxRTw6LqEPH8fcX5XRurH/ZAdCowZas0Lh2Q6Pko8r5oz+kf4qSnj73xoLOSHLm2vB2Zxz9XZoIDTwIv0uYA61Y2pEBswBW5t/EPSYIwnoHM= 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=MZRusxAI; 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="MZRusxAI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1776687809; bh=vRT5e1DqiM/5f3FADuR9Az/ABfSzGFffqKBSWG1K5sw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MZRusxAIzEGW9c0Ya5ITMQBIHctsWSfo+ER8RJalOxrAt/fJTJFgUTxmuMMe9Jygy sA+QptXF5MXPoATDtjIk3u2+d5DS2zBj8eVrWIjy2UXhN5U5C4LzfIszOtPkR6lsfc XMdbX4M5HiaRUf6Y3BK3zatZHxjzqvP08JsUTAPc= 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 319CEBEFE1; Mon, 20 Apr 2026 12:23: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 9BFC65FC57; Mon, 20 Apr 2026 13:23:28 +0100 (BST) From: Phil Pemberton To: Damien Le Moal , Niklas Cassel Cc: "James E . J . Bottomley" , "Martin K . Petersen" , Hannes Reinecke , linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Phil Pemberton Subject: [PATCH v2 2/5] ata: libata-scsi: convert dev->sdev to per-LUN array Date: Mon, 20 Apr 2026 13:23:18 +0100 Message-ID: <20260420122321.4161027-3-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260420122321.4161027-1-philpem@philpem.me.uk> References: <20260420122321.4161027-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. Signed-off-by: Phil Pemberton Reviewed-by: Hannes Reinecke Reviewed-by: Martin K. Petersen --- 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 Thu Jun 18 08:18:08 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 8DFB92D7DDD; Mon, 20 Apr 2026 12:45:25 +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=1776689126; cv=none; b=kKwTi/riA3syWjfhX7Ac/qyuggdAcsXdBl3CO+6WlkqOCnC7xs3Wlrsxt2Jcb3TpRZBdGz0bgwC/OTw5t7S8AJETfZIQhEq/9ZpFtoMN74bI+YIBN685yVXzr9sCKKh/Ykx7YpNBDbfJdTe+oRIa3emVQn6arv9B7o9WMX3BuxA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776689126; c=relaxed/simple; bh=mOszOGgiRniI+v2UWq22eRi5tmlU02g5ePSKlT10boU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cYtLgKX9dgwNkCg7OkfWOqJbVQoKmPP1KAcmtAKGa6XUx1XiJCe7AW1GxijqWZXBTLZVOM7R8oEglwrQLIwrTk3GXzhp1IZmpb8siQ6kww2427WE0VgtOD6A7wOjK9PAcHQphSH//R2shSycD2PSvj6S+7RkFg/pc1GZE6AcmX8= 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=Dz/93QVn; 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="Dz/93QVn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1776687809; bh=mOszOGgiRniI+v2UWq22eRi5tmlU02g5ePSKlT10boU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Dz/93QVnxhsZ5AVlWbrYuCF6+9GAlDgaeyk0NVRHgYcEce8yM4EBkV1619R9ybLbN u7zMIy3UtqNnCaR5mBZ442Sy6dgdh/mXZ81ZH25A8F69BHtXcW9NiF8ln1MUx0I6K0 2PsLvnG+CgVefxXvCwhtE1hWsPc10RS0BP/QxsJE= 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 36724BEFE2; Mon, 20 Apr 2026 12:23: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 AF6965FC59; Mon, 20 Apr 2026 13:23:28 +0100 (BST) From: Phil Pemberton To: Damien Le Moal , Niklas Cassel Cc: "James E . J . Bottomley" , "Martin K . Petersen" , Hannes Reinecke , linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Phil Pemberton Subject: [PATCH v2 3/5] ata: libata-scsi: route non-zero LUN commands for multi-LUN ATAPI Date: Mon, 20 Apr 2026 13:23:19 +0100 Message-ID: <20260420122321.4161027-4-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260420122321.4161027-1-philpem@philpem.me.uk> References: <20260420122321.4161027-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. Signed-off-by: Phil Pemberton Reviewed-by: Martin K. Petersen --- 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..4e88ae7d94c3 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 */ + if (scmd->device->lun < 8) + 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 Thu Jun 18 08:18:08 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 8E0E9399019; Mon, 20 Apr 2026 12:45:25 +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=1776689128; cv=none; b=hpMbfncGS1QSvLPsNIvmITZOpaWpU09uU4niRAJnoyvJNzDSudMox41e77N+MVVgGguNqRuCamOClFj58T1XsQM7/pwtj181xf72SY6kkIEvYqdcdEYM9erQN3ycy4dY0xFrJIcGiit6meIqPhZEJpsqn9Zs/7Hc+aAUELUIyyg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776689128; c=relaxed/simple; bh=vGCMlAn3ZRxZJy5AYq/flJzKXszt4Qsi2hLGeF8baJI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=r8T3S5DzPG80e80/2iurSLWG6aPQFdN+q2GMeOz/AKY/v/e9idgAxLAuN0YVTspCHGffIe/Hdo6OxxqHvtP1hdwB6AwUgkEFE8cbYlHLDkHZnimXiItVKPBtf8ePKrVHnZySpZvRRWLvPRjwfWFOaDglE525Bla0HFk6UBl9zN8= 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=NnwMstFn; 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="NnwMstFn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1776687809; bh=vGCMlAn3ZRxZJy5AYq/flJzKXszt4Qsi2hLGeF8baJI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NnwMstFnPSaFTU9eZ02elsf1KakiUBpX9K4dsmrpcq/SiZOR3aYyucaWZaz0PIBWS w0Z6UUJyWKvfErW4V8Eh0WQCed0AB8cfcYXMVhTfbyWLXhEi2MipW12P9T7ezWPr9h xNEMsI1u9RiJqFYDU0vt0Hr6ieNzT8L0LfORqRUk= 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 45D87BEFE9; Mon, 20 Apr 2026 12:23: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 BC87A5FC5A; Mon, 20 Apr 2026 13:23:28 +0100 (BST) From: Phil Pemberton To: Damien Le Moal , Niklas Cassel Cc: "James E . J . Bottomley" , "Martin K . Petersen" , Hannes Reinecke , linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Phil Pemberton Subject: [PATCH v2 4/5] ata: libata-scsi: probe additional LUNs for multi-LUN ATAPI devices Date: Mon, 20 Apr 2026 13:23:20 +0100 Message-ID: <20260420122321.4161027-5-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260420122321.4161027-1-philpem@philpem.me.uk> References: <20260420122321.4161027-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 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/5. Devices without BLIST_FORCELUN (the vast majority of ATAPI devices) are left with only LUN 0 =E2=80=94 no sequential scan is triggered, so single-LUN devices like the iHAS124 DVD writer are completely unaffected. To suppress spurious "No Device" log entries from non-responding LUNs (e.g. LUN 2+ on a two-LUN PD/CD drive), set pdt_1f_for_no_lun on the scsi_target during LUN 0 configuration. The Panasonic PD-1 returns PQ=3D0/PDT=3D0x1f for unpopulated LUNs rather than the standard PQ=3D3; with this flag, scsi_probe_and_add_lun() silently skips them. If BLIST_FORCELUN is set but atapi_max_lun is still at its default of 1, an informational message points the user at the module parameter so the knob is discoverable from dmesg. Signed-off-by: Phil Pemberton Reviewed-by: Martin K. Petersen --- drivers/ata/libata-scsi.c | 53 ++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 4e88ae7d94c3..9d18ef2835a5 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -1132,6 +1133,22 @@ int ata_scsi_dev_config(struct scsi_device *sdev, st= ruct queue_limits *lim, sdev->security_supported =3D 1; =20 dev->sdev[sdev->lun] =3D sdev; + + /* + * Tell the SCSI scan layer that PDT 0x1f with PQ 0 means "no LUN + * present" for this target. The Panasonic PD-1 (and likely other + * multi-LUN ATAPI devices) returns PQ=3D0/PDT=3D0x1f for unpopulated + * LUNs instead of the standard PQ=3D3. Setting this flag lets the + * sequential LUN scan skip those LUNs cleanly. + */ + if (dev->class =3D=3D ATA_DEV_ATAPI && sdev->lun =3D=3D 0) { + sdev->sdev_target->pdt_1f_for_no_lun =3D 1; + + if ((sdev->sdev_bflags & BLIST_FORCELUN) && atapi_max_lun < 2) + ata_dev_info(dev, + "device has additional LUNs; set libata.atapi_max_lun=3D2 or higher to= access them\n"); + } + return 0; } =20 @@ -4700,7 +4717,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 +4727,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 Thu Jun 18 08:18:08 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 BA5FD39F164; Mon, 20 Apr 2026 12:23: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=1776687822; cv=none; b=R6gD972ArSCko02WY6Yt9rHzTTtzCvBHbB6M4dMr+2w9GHGLfulaJx3wYGBSulM4mz7sgMMYak40qJydVKSaaO4WWhh7evMY79wHXvbFPV6ZKAAAeFwfsPshgipFCOpKiq3tPQYDxN44WjA5V924OdEE2HA8xrO0y/Vu+ENrYXc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776687822; c=relaxed/simple; bh=zRabrlMAt8mmwgKPv2viGfu9sJPKsnu7kmQGmU+O7u4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EDZMndVsjTKEkxxIbCN0DwpKOfhGYWDUoRyl16Uo6tJSqpMgX5U1F40buaU/yWG8xve1WkcbcGgGUZKFWuWLUJaCHcNIPl4i/GSfQrJU/WEmCyW2eK81a20Z03X6mjt44w1GWavAhD8G+6J2G75vPH+5pd6I2KzXlHqdgKhFpNI= 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=hSPonNTc; 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="hSPonNTc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=philpem.me.uk; s=mail; t=1776687809; bh=zRabrlMAt8mmwgKPv2viGfu9sJPKsnu7kmQGmU+O7u4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hSPonNTccTzUaQqPzRj8xdtZYj1Uk3qLzAJdWsR952oSPgB22H2cKVeolSTXFySWJ VfNATVZt7hBnCtZ4QpofE2sMZWklPQLZExUotcs2Ba4KaYhkrmvAsPoum/VyD8X3oU CwQRoK9ocxC9MkP7zACOUI5ItBIkJjgy1Q5RxYBM= 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 6A10BBEFEB; Mon, 20 Apr 2026 12:23: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 CE25C5FC5B; Mon, 20 Apr 2026 13:23:28 +0100 (BST) From: Phil Pemberton To: Damien Le Moal , Niklas Cassel Cc: "James E . J . Bottomley" , "Martin K . Petersen" , Hannes Reinecke , linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Phil Pemberton Subject: [PATCH v2 5/5] scsi: scsi_devinfo: add COMPAQ PD-1 multi-LUN ATAPI device quirk Date: Mon, 20 Apr 2026 13:23:21 +0100 Message-ID: <20260420122321.4161027-6-philpem@philpem.me.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260420122321.4161027-1-philpem@philpem.me.uk> References: <20260420122321.4161027-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 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: Martin K. Petersen --- drivers/scsi/scsi_devinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 68a992494b12..06b211b93567 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -150,6 +150,7 @@ 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}, {"DDN", "SAN DataDirector", "*", BLIST_SPARSELUN}, {"DEC", "HSG80", NULL, BLIST_REPORTLUN2 | BLIST_NOSTARTONADD}, {"DELL", "PV660F", NULL, BLIST_SPARSELUN}, --=20 2.43.0