public inbox for linux-ide@vger.kernel.org
 help / color / mirror / Atom feed
From: Damien Le Moal <dlemoal@kernel.org>
To: Phil Pemberton <philpem@philpem.me.uk>,
	cassel@kernel.org, James.Bottomley@HansenPartnership.com,
	martin.petersen@oracle.com
Cc: linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/3] ata: libata-scsi: enable multi-LUN support for ATAPI devices
Date: Sun, 12 Apr 2026 09:38:12 +0200	[thread overview]
Message-ID: <c62f11f0-6127-41c6-98c6-cb6794125e70@kernel.org> (raw)
In-Reply-To: <20260409210559.155864-3-philpem@philpem.me.uk>

On 4/9/26 23:05, Phil Pemberton wrote:
> libata has never supported multi-LUN ATAPI devices like the Panasonic
> and NEC PD/CD combo drives due to three limitations:
> 
>   - shost->max_lun is hardcoded to 1 in ata_scsi_add_hosts(), which
>     stops the SCSI layer from probing any LUN other than 0.
> 
>   - __ata_scsi_find_dev() rejects all commands where scsidev->lun != 0,
>     returning NULL which causes DID_BAD_TARGET.
> 
>   - The SCSI-2 CDB LUN field (byte 1, bits 7:5) is never set. Older
>     multi-LUN ATAPI devices rely on this field to route commands to the
>     correct LUN, as transport-layer LUN addressing (per SPC-3+) is not
>     available over the ATA PACKET interface.
> 
> To fix all three, this change:
> 
>   - Raises max_lun from 1 to 8 (matching the SCSI host default).
>     Sequential LUN scanning stops at the first non-responding LUN, so
>     single-LUN devices are unaffected.

If the only case that we can encounter with libata are these special ATAPI
devices with 2 LUNs, I would limit the maximum to 2.

>   - In __ata_scsi_find_dev(), allow non-zero LUNs for ATAPI devices by
>     routing them to the same ata_device as LUN 0.
> 
>   - In atapi_xlat(), encode the target LUN into CDB byte 1 bits 7:5
>     before passing the command packet to the device.
> 
> These changes are prerequisites for probing additional LUNs during
> host scanning, which is done in a subsequent patch.
> 
> Additionally, fix two related issues exposed by multi-LUN scanning:
> 
>   - ata_scsi_dev_config() previously assigned dev->sdev = sdev for every
>     LUN configured.  With multiple LUNs sharing one ata_device, this
>     caused dev->sdev to be overwritten by each non-LUN-0 sdev.  Restrict
>     the assignment to LUN 0 so that dev->sdev always tracks the
>     canonical scsi_device for the underlying ATA device.

Special casing this does not seem nice at all. Why not simply increasing the
sdev reference count when it is assigned to a LUN that is not LUN 0 ? And drop
that reference when the LUN is torn down ? That will remove any dependency on
the order in which LUNs are torn down too.

>   - ata_scsi_sdev_destroy() detached the entire ATA device whenever
>     dev->sdev was non-NULL.  When a spurious multi-LUN scan result was
>     removed, this incorrectly tore down the underlying device.  Detach
>     only when the canonical (LUN 0) sdev is being destroyed.

This should not happen with the reference count change suggested above.

This is a lot of changes for one patch. So I also suggest splitting this patch.

> 
> Assisted-by: Claude:claude-opus-4-6
> Signed-off-by: Phil Pemberton <philpem@philpem.me.uk>
> ---
>  drivers/ata/libata-scsi.c | 38 ++++++++++++++++++++++++++++++++++----
>  1 file changed, 34 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> index 3b65df914ebb..dc6829e60fb3 100644
> --- a/drivers/ata/libata-scsi.c
> +++ b/drivers/ata/libata-scsi.c
> @@ -25,6 +25,7 @@
>  #include <scsi/scsi_eh.h>
>  #include <scsi/scsi_device.h>
>  #include <scsi/scsi_tcq.h>
> +#include <scsi/scsi_devinfo.h>
>  #include <scsi/scsi_transport.h>
>  #include <linux/libata.h>
>  #include <linux/hdreg.h>
> @@ -1131,7 +1132,14 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct queue_limits *lim,
>  	if (dev->flags & ATA_DFLAG_TRUSTED)
>  		sdev->security_supported = 1;
>  
> -	dev->sdev = sdev;
> +	/*
> +	 * Only LUN 0 is treated as the canonical scsi_device for the ATA
> +	 * device.  Multi-LUN ATAPI devices share a single ata_device, so
> +	 * dev->sdev must continue to track LUN 0 even when additional LUNs
> +	 * are added or removed.
> +	 */
> +	if (sdev->lun == 0)
> +		dev->sdev = sdev;
>  	return 0;
>  }
>  
> @@ -1220,7 +1228,12 @@ void ata_scsi_sdev_destroy(struct scsi_device *sdev)
>  
>  	spin_lock_irqsave(ap->lock, flags);
>  	dev = __ata_scsi_find_dev(ap, sdev);
> -	if (dev && dev->sdev) {
> +	/*
> +	 * Only detach when the canonical (LUN 0) scsi_device is going away.
> +	 * Removing a non-LUN-0 sdev (e.g. a spurious multi-LUN scan result)
> +	 * must not tear down the underlying ATA device.
> +	 */
> +	if (dev && dev->sdev == sdev) {
>  		/* SCSI device already in CANCEL state, no need to offline it */
>  		dev->sdev = NULL;
>  		dev->flags |= ATA_DFLAG_DETACH;
> @@ -2950,6 +2963,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);
>  
> +	/*
> +	 * Encode LUN in CDB byte 1 bits 7:5 for multi-LUN ATAPI devices
> +	 * that use the SCSI-2 CDB LUN convention (e.g. Panasonic PD/CD
> +	 * combo drives).
> +	 */
> +	if (scmd->device->lun)
> +		qc->cdb[1] = (qc->cdb[1] & 0x1f) |
> +			      ((scmd->device->lun & 0x7) << 5);

Splitting the line after the "=" should look nicer.

> +
>  	qc->complete_fn = atapi_qc_complete;
>  
>  	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
> @@ -3062,9 +3084,17 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
>  
>  	/* 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 = scsidev->id;
> +		/* Allow non-zero LUNs for ATAPI devices (e.g. PD/CD combos) */
> +		if (unlikely(scsidev->lun)) {
> +			struct ata_device *dev = ata_find_dev(ap, devno);
> +
> +			if (!dev || dev->class != ATA_DEV_ATAPI)
> +				return NULL;
> +			return dev;
> +		}

Hmmm... What if the multi-LUN ATAPI device is attached to a port multiplier ?

>  	} else {
>  		if (unlikely(scsidev->id || scsidev->lun))
>  			return NULL;
> @@ -4620,7 +4650,7 @@ int ata_scsi_add_hosts(struct ata_host *host, const struct scsi_host_template *s
>  		shost->transportt = ata_scsi_transport_template;
>  		shost->unique_id = ap->print_id;
>  		shost->max_id = 16;
> -		shost->max_lun = 1;
> +		shost->max_lun = 8;
>  		shost->max_channel = 1;
>  		shost->max_cmd_len = 32;
>  


-- 
Damien Le Moal
Western Digital Research

  reply	other threads:[~2026-04-12  7:38 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-09 21:05 [RFC PATCH 0/3] ata: libata-scsi: add multi-LUN support for ATAPI devices Phil Pemberton
2026-04-09 21:05 ` [PATCH 1/3] scsi: scsi_devinfo: add COMPAQ PD-1 multi-LUN ATAPI device quirk Phil Pemberton
2026-04-12  7:25   ` Damien Le Moal
2026-04-09 21:05 ` [PATCH 2/3] ata: libata-scsi: enable multi-LUN support for ATAPI devices Phil Pemberton
2026-04-12  7:38   ` Damien Le Moal [this message]
2026-04-12 19:40     ` Phil Pemberton
2026-04-13  5:43       ` Damien Le Moal
2026-04-13  8:31       ` Hannes Reinecke
2026-04-09 21:05 ` [PATCH 3/3] ata: libata-scsi: probe additional LUNs for multi-LUN " Phil Pemberton
2026-04-12  7:41   ` Damien Le Moal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c62f11f0-6127-41c6-98c6-cb6794125e70@kernel.org \
    --to=dlemoal@kernel.org \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=cassel@kernel.org \
    --cc=linux-ide@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=philpem@philpem.me.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox