Skip to contentSkip to conversation

libata: Simulate REPORT LUNS for ATAPI devices when not supported

PATCH In review Darrick J. Wong 5 participants 16 messages Dec 4, 2006 – Dec 13, 2006

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

The Quantum GoVault SATAPI removable disk device returns ATA_ERR in response to a REPORT LUNS packet. If this happens to an ATAPI device that is attached to a SAS controller (this is the case with sas_ata), the device does not load because SCSI won't touch a "SCSI device" that won't report its LUNs. If we see this command fail, we should simulate a response that indicates the presence of LUN 0.

---

 drivers/ata/libata-core.c |   36 ++++++++++++++++++++++++++++++++----
 drivers/ata/libata-scsi.c |    4 ++--
 include/linux/libata.h    |    2 ++
 3 files changed, 36 insertions(+), 6 deletions(-)
drivers/ata/libata-core.c +32 -4
index 915a55a..a3d6217 100644
@@ -4455,6 +4455,35 @@ void ata_qc_complete(struct ata_queued_c
 {
 	struct ata_port *ap = qc->ap;
 
+	/*
+	 * If this is an ATAPI device that fails a REPORT LUN issued by SCSI,
+	 * assume that LUN 0 exists and fake the return buffer as appropriate.
+	 * ATA devices have REPORT LUN simulated for them.
+	 */
+	if (is_atapi_taskfile(&qc->tf) &&
+	    qc->scsicmd &&
+	    qc->cdb[0] == REPORT_LUNS &&
+	    qc->err_mask) {
+		unsigned int buflen;
+		struct scsi_cmnd *cmd = qc->scsicmd;
+		u8 *buf = NULL;
+
+		buflen = ata_scsi_rbuf_get(cmd, &buf);
+		memset(buf, 0, buflen);
+		buf[3] = 8;
+		ata_scsi_rbuf_put(cmd, buf);
+		
+		qc->err_mask = 0;
+
+		/* read result TF if requested */
+		if (qc->flags & ATA_QCFLAG_RESULT_TF)
+			ap->ops->tf_read(ap, &qc->result_tf);
+		qc->result_tf.command &= ~ATA_ERR;
+		qc->flags &= ~ATA_QCFLAG_RESULT_TF;
+
+		goto finish_qc;
+	}
+
 	/* XXX: New EH and old EH use different mechanisms to
 	 * synchronize EH with regular execution path.
 	 *
@@ -4486,8 +4515,6 @@ void ata_qc_complete(struct ata_queued_c
 		/* read result TF if requested */
 		if (qc->flags & ATA_QCFLAG_RESULT_TF)
 			ap->ops->tf_read(ap, &qc->result_tf);
-
-		__ata_qc_complete(qc);
 	} else {
 		if (qc->flags & ATA_QCFLAG_EH_SCHEDULED)
 			return;
@@ -4495,9 +4522,10 @@ void ata_qc_complete(struct ata_queued_c
 		/* read result TF if failed or requested */
 		if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF)
 			ap->ops->tf_read(ap, &qc->result_tf);
-
-		__ata_qc_complete(qc);
 	}
+
+finish_qc:
+	__ata_qc_complete(qc);
 }
 
 /**
drivers/ata/libata-scsi.c +2 -2
index 47ea111..da013a7 100644
@@ -1639,7 +1639,7 @@ defer:
  *	Length of response buffer.
  */
 
-static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
+unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
 {
 	u8 *buf;
 	unsigned int buflen;
@@ -1670,7 +1670,7 @@ static unsigned int ata_scsi_rbuf_get(st
  *	spin_lock_irqsave(host lock)
  */
 
-static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf)
+void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf)
 {
 	if (cmd->use_sg) {
 		struct scatterlist *sg;
include/linux/libata.h +2 -0
index abd2deb..b37b21f 100644
@@ -723,6 +723,8 @@ extern int ata_scsi_detect(struct scsi_h
 extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
 extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
 extern int ata_scsi_release(struct Scsi_Host *host);
+unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out);
+void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf);
 extern void ata_sas_port_destroy(struct ata_port *);
 extern struct ata_port *ata_sas_port_alloc(struct ata_host *,
 					   struct ata_port_info *, struct Scsi_Host *);
#1 lore raw
Quoted 8 lines · Darrick J. Wong

The Quantum GoVault SATAPI removable disk device returns ATA_ERR in response to a REPORT LUNS packet. If this happens to an ATAPI device that is attached to a SAS controller (this is the case with sas_ata), the device does not load because SCSI won't touch a "SCSI device" that won't report its LUNs. If we see this command fail, we should simulate a response that indicates the presence of LUN 0.

I think the answer to this issue lies in the behavior of the majority of ATAPI devices when responding to REPORT LUNS. Regardless of SAS or SATA or whatever bus the device is using.

ISTR that REPORT LUNS can make ATAPI devices croak, so it might be wise and more safe to simply simulate REPORT LUNS by default for all ATAPI devices. Then readdress the issue if someone has a burning need to support the rare multi-LUN ATAPI devices. I have one, but I'm not highly motivated to dig it out.

Jeff

#2 lore raw

PATCH v2 1/1 libata: Simulate REPORT LUNS for ATAPI devices

The Quantum GoVault SATAPI removable disk device returns ATA_ERR in response to a REPORT LUNS packet. If this happens to an ATAPI device that is attached to a SAS controller (this is the case with sas_ata), the device does not load because SCSI won't touch a "SCSI device" that won't report its LUNs. Since most ATAPI devices don't support multiple LUNs anyway, we might as well fake a response like we do for ATA devices.

---

 drivers/ata/libata-scsi.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)
drivers/ata/libata-scsi.c +7 -2
index 47ea111..5ecf260 100644
@@ -2833,8 +2833,13 @@ static inline int __ata_scsi_queuecmd(st
 			rc = ata_scsi_translate(dev, cmd, done, xlat_func);
 		else
 			ata_scsi_simulate(dev, cmd, done);
-	} else
-		rc = ata_scsi_translate(dev, cmd, done, atapi_xlat);
+	} else {
+		/* Simulate REPORT LUNS for ATAPI devices */
+		if (cmd->cmnd[0] == REPORT_LUNS)
+			ata_scsi_simulate(dev, cmd, done);
+		else
+			rc = ata_scsi_translate(dev, cmd, done, atapi_xlat);
+	}
 
 	return rc;
 }
#3 lore raw

Re: [PATCH v2] libata: Simulate REPORT LUNS for ATAPI devices

Quoted 9 lines · Darrick J. Wong

The Quantum GoVault SATAPI removable disk device returns ATA_ERR in response to a REPORT LUNS packet. If this happens to an ATAPI device that is attached to a SAS controller (this is the case with sas_ata), the device does not load because SCSI won't touch a "SCSI device" that won't report its LUNs. Since most ATAPI devices don't support multiple LUNs anyway, we might as well fake a response like we do for ATA devices.

Seems sane to me, but I would like additional comment/testing/etc. before applying...

#4 lore raw

Re: [PATCH v2] libata: Simulate REPORT LUNS for ATAPI devices

Quoted 9 lines · Jeff Garzik
Quoted 8 lines · Darrick J. Wong

The Quantum GoVault SATAPI removable disk device returns ATA_ERR in response to a REPORT LUNS packet. If this happens to an ATAPI device that is attached to a SAS controller (this is the case with sas_ata), the device does not load because SCSI won't touch a "SCSI device" that won't report its LUNs. Since most ATAPI devices don't support multiple LUNs anyway, we might as well fake a response like we do for ATA devices.

Quoted 4 lines
Quoted 1 line

Seems sane to me, but I would like additional comment/testing/etc. before applying...

A SCSI target contains zero or more logical units. As in this case, those logical units may use a different transport. In such cases a SCSI target needs to emulate responses to some SCSI commands (and modify the responses to others). Here is a list that is probably not comprehensive:
- INQUIRY (peripheral qualifier in standard response)
- INQUIRY, device identification VPD page (0x83)
- obviously for the device name+identifier and port name+identifier
- may need to concatenate those with the lu's name+identifier
- INQUIRY, SCSI ports VPD page
- INQUIRY, ATA Information VPD page (for SAT)
- REPORT LUNS [mandatory in SPC-3 hence mandatory in SAT]
- protocol specific port mode page (0x19)
- protocol specific lu mode page (0x18) [could simulate]
- PATA control mode page (0xa,0xf1) (for SAT)
- protocol specific port _log_ page (0x18)

And for SAT you could add the ATA PASS-THROUGH commands to that list. Those that are really ambitious could implement well know logical units (wluns) which are essentially a clean way to talk directly to the target rather than a logical unit.

About the multi-lun ATAPI devices comment: how would libata represent multiple S-ATAPI devices connected to a SATA port multiplier?

Doug Gilbert

#5 lore raw

Re: [PATCH v2] libata: Simulate REPORT LUNS for ATAPI devices

In reply to Darrick J. Wong
Quoted 7 lines · Darrick J. Wong

The Quantum GoVault SATAPI removable disk device returns ATA_ERR in response to a REPORT LUNS packet. If this happens to an ATAPI device that is attached to a SAS controller (this is the case with sas_ata), the device does not load because SCSI won't touch a "SCSI device" that won't report its LUNs. Since most ATAPI devices don't support multiple LUNs anyway, we might as well fake a response like we do for ATA devices.

Actually, there may be a standards conflict here. SPC says that all devices reporting compliance with this standard (as the inquiry data for this device claims) shall support REPORT LUNS. On the other hand, MMC doesn't list REPORT LUNS in its table of mandatory commands.

I'm starting to think that even if they report a SCSI compliance level of 3 or greater, we still shouldn't send REPORT LUNS to devices that return MMC type unless we have a white list override.

James

#6 lore raw

Re: [PATCH v2] libata: Simulate REPORT LUNS for ATAPI devices

Quoted 9 lines · James Bottomley
Quoted 7 lines · Darrick J. Wong

The Quantum GoVault SATAPI removable disk device returns ATA_ERR in response to a REPORT LUNS packet. If this happens to an ATAPI device that is attached to a SAS controller (this is the case with sas_ata), the device does not load because SCSI won't touch a "SCSI device" that won't report its LUNs. Since most ATAPI devices don't support multiple LUNs anyway, we might as well fake a response like we do for ATA devices.

Quoted 4 lines

Actually, there may be a standards conflict here. SPC says that all devices reporting compliance with this standard (as the inquiry data for this device claims) shall support REPORT LUNS. On the other hand, MMC doesn't list REPORT LUNS in its table of mandatory commands.

MMC-5 rev 4 section 7.1:
"Some commands that may be implemented by MM drives are not described in this standard, but are found in other SCSI standards. For a complete list of these commands refer to [SPC-3]."

Hmm, "may be implemented" yet REPORT LUNS is mandatory in SPC-3 (and SPC-3 is a normative reference for MMC-5). I guess there is wriggle room there.
In practice, MMC diverges from SPC a lot more than other SCSI device type command sets (e.g. SBC and SSC).

Quoted 3 lines

I'm starting to think that even if they report a SCSI compliance level of 3 or greater, we still shouldn't send REPORT LUNS to devices that return MMC type unless we have a white list override.

There is also SAT compliance. For the ATA command set (i.e. disks) sat-r09 lists REPORT LUNS and refers to SPC-3. For ATAPI sat-r09 is far less clear. It does recommend, for example, that the ATA Information VPD pages is implemented in the SATL for ATAPI devices.

Doug Gilbert

#7 lore raw

Re: [PATCH v2] libata: Simulate REPORT LUNS for ATAPI devices

In reply to Darrick J. Wong
Quoted 9 lines · Darrick J. Wong

The Quantum GoVault SATAPI removable disk device returns ATA_ERR in response to a REPORT LUNS packet. If this happens to an ATAPI device that is attached to a SAS controller (this is the case with sas_ata), the device does not load because SCSI won't touch a "SCSI device" that won't report its LUNs. Since most ATAPI devices don't support multiple LUNs anyway, we might as well fake a response like we do for ATA devices.

I'm leaning towards applying this, perhaps with a module option that allows experimenters to revert back to the older behavior.

Any chance you could be talked into tackling some of the SAT translation-related items Doug G mentioned? I'm almost certain there are some info pages we should be returning, but are not, at the very least.

Jeff

#8 lore raw

Re: [PATCH v2] libata: Simulate REPORT LUNS for ATAPI devices

Quoted 9 lines · Jeff Garzik
Quoted 8 lines · Darrick J. Wong

The Quantum GoVault SATAPI removable disk device returns ATA_ERR in response to a REPORT LUNS packet. If this happens to an ATAPI device that is attached to a SAS controller (this is the case with sas_ata), the device does not load because SCSI won't touch a "SCSI device" that won't report its LUNs. Since most ATAPI devices don't support multiple LUNs anyway, we might as well fake a response like we do for ATA devices.

Quoted 8 lines
Quoted 1 line

I'm leaning towards applying this, perhaps with a module option that allows experimenters to revert back to the older behavior.

Any chance you could be talked into tackling some of the SAT translation-related items Doug G mentioned? I'm almost certain there are some info pages we should be returning, but are not, at the very least.

I thought we were closing in on agreeing that the SPC/MMC inconsistencies made this the correct candidate fix.

James

drivers/scsi/scsi_devinfo.c +6 -0
index ce63044..9d5e75b 100644
@@ -7,6 +7,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
+#include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_devinfo.h>
 
@@ -439,6 +440,11 @@ int scsi_get_device_flags(struct scsi_de
 				return devinfo->flags;
 		}
 	}
+	/* MMC devices can return SCSI-3 compliance and yet still not
+	 * support REPORT LUNS, so make them act as BLIST_NOREPORTLUN
+	 * unless BLIST_REPORTLUN2 is specifically set */
+	if (sdev->type == TYPE_ROM && (bflags & BLIST_REPORTLUN2) == 0)
+		bflags |= BLIST_NOREPORTLUN;
 	return bflags;
 }
 
drivers/scsi/scsi_scan.c +0 -0
#9 lore raw

Re: [PATCH v2] libata: Simulate REPORT LUNS for ATAPI devices

Quoted 10 lines · James Bottomley
Quoted 9 lines · Jeff Garzik
Quoted 8 lines · Darrick J. Wong

The Quantum GoVault SATAPI removable disk device returns ATA_ERR in response to a REPORT LUNS packet. If this happens to an ATAPI device that is attached to a SAS controller (this is the case with sas_ata), the device does not load because SCSI won't touch a "SCSI device" that won't report its LUNs. Since most ATAPI devices don't support multiple LUNs anyway, we might as well fake a response like we do for ATA devices.

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

I'm leaning towards applying this, perhaps with a module option that allows experimenters to revert back to the older behavior.

Any chance you could be talked into tackling some of the SAT translation-related items Doug G mentioned? I'm almost certain there are some info pages we should be returning, but are not, at the very least.

I thought we were closing in on agreeing that the SPC/MMC inconsistencies made this the correct candidate fix.

that works for me...

Jeff

#10 lore raw

Re: [PATCH v2] libata: Simulate REPORT LUNS for ATAPI devices

In reply to James Bottomley
Quoted 2 lines · James Bottomley

I thought we were closing in on agreeing that the SPC/MMC inconsistencies made this the correct candidate fix.

I tried out the patch below, but with it applied, SCSI still issues REPORT LUNS to the device. It seems that sdev->type = -1 and bflags = 0 when scsi_get_device_flags is called because the type code is not set up until scsi_add_lun, which is called later. In any case, the check doesn't work for me because the SATAPI GoVault reports itself as a Direct Access device, not a CD-ROM.

Quoted 1 line
drivers/scsi/scsi_devinfo.c +0 -0

<snip>

drivers/scsi/scsi_scan.c

Quoted 1 line
drivers/scsi/scsi_scan.c +0 -0

<empty>

Was there supposed to be more to this patch?

--D

#11 lore raw

Re: [PATCH v2] libata: Simulate REPORT LUNS for ATAPI devices

Quoted 2 lines · Darrick J. Wong

I tried out the patch below, but with it applied, SCSI still issues REPORT LUNS to the device. It seems that sdev->type = -1 and bflags = 0

Yes, the inquiry scanning is being called too early ... largely so BLIST_ROM can work, I suppose.

Quoted 4 lines

when scsi_get_device_flags is called because the type code is not set up until scsi_add_lun, which is called later. In any case, the check doesn't work for me because the SATAPI GoVault reports itself as a Direct Access device, not a CD-ROM.

Er, if it's really a CD-ROM, doesn't it need a blacklist entry with BLIST_ROM then? Regardless, MMC is the only standard that seems to be inconsistent in this regard. Anything claiming to conform to SBC will need to be explicitly blacklisted if it claims SCSI-3 or higher and doesn't support REPORT LUNS.

Does the attached patch fare better?

James

drivers/scsi/scsi_scan.c +8 -1
index 14e635a..92fb26b 100644
@@ -752,8 +752,15 @@ static int scsi_add_lun(struct scsi_devi
 	case TYPE_RBC:
 		sdev->writeable = 1;
 		break;
-	case TYPE_WORM:
 	case TYPE_ROM:
+		/* MMC devices can return SCSI-3 compliance and yet
+		 * still not support REPORT LUNS, so make them act as
+		 * BLIST_NOREPORTLUN unless BLIST_REPORTLUN2 is
+		 * specifically set */
+		if ((*bflags & BLIST_REPORTLUN2) == 0)
+			*bflags |= BLIST_NOREPORTLUN;
+		/* fall through */
+	case TYPE_WORM:
 		sdev->writeable = 0;
 		break;
 	default:
#12 lore raw

Re: [PATCH v2] libata: Simulate REPORT LUNS for ATAPI devices

Quoted 5 lines · James Bottomley

Er, if it's really a CD-ROM, doesn't it need a blacklist entry with BLIST_ROM then? Regardless, MMC is the only standard that seems to be inconsistent in this regard. Anything claiming to conform to SBC will need to be explicitly blacklisted if it claims SCSI-3 or higher and doesn't support REPORT LUNS.

Sorry, I should have clarified this earlier--the Quantum GoVault is a removable disk drive, not a CD-ROM. The device is reminiscent of Zip disks, but the cartridge is a sealed unit and contains a 2.5" SATA disk inside; hence it's not a CD-ROM. So the patch below won't work for me, because sdev->type == TYPE_DISK.

I wonder if the same sort of REPORT LUNS screw-up might apply to other ATAPI devices too, such as tape drives. Since we've seen that manufacturers of CD-ROMs and removable disks don't implement it, it would not surprise me if the other ATAPI devices don't either. But, that's speculation on my part.

--D

#13 lore raw

Re: [PATCH v2] libata: Simulate REPORT LUNS for ATAPI devices

Quoted 5 lines · Darrick J. Wong

Sorry, I should have clarified this earlier--the Quantum GoVault is a removable disk drive, not a CD-ROM. The device is reminiscent of Zip disks, but the cartridge is a sealed unit and contains a 2.5" SATA disk inside; hence it's not a CD-ROM. So the patch below won't work for me, because sdev->type == TYPE_DISK.

So it's a SATAPI device of type 0 ... that's fun ... but it still needs a blacklist; it's governed by SBC which isn't ambiguous about the need to support REPORT LUNS. Now, if it supported RBC instead of SBC, that's different; RBC also makes REPORT LUNS optional. However, it is required to indicate RBC support by being type 0xe.

Quoted 5 lines

I wonder if the same sort of REPORT LUNS screw-up might apply to other ATAPI devices too, such as tape drives. Since we've seen that manufacturers of CD-ROMs and removable disks don't implement it, it would not surprise me if the other ATAPI devices don't either. But, that's speculation on my part.

James

#14 lore raw

Re: [PATCH v2] libata: Simulate REPORT LUNS for ATAPI devices

In reply to Darrick J. Wong
Quoted 7 lines · Darrick J. Wong

The Quantum GoVault SATAPI removable disk device returns ATA_ERR in response to a REPORT LUNS packet. If this happens to an ATAPI device that is attached to a SAS controller (this is the case with sas_ata), the device does not load because SCSI won't touch a "SCSI device" that won't report its LUNs. Since most ATAPI devices don't support multiple LUNs anyway, we might as well fake a response like we do for ATA devices.

If the REPORT LUNS fails, we should fall back to a sequential scan.

Is (or why isn't) the error propagated back to scsi?

Quoted 16 lines

---

 drivers/ata/libata-scsi.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)
drivers/ata/libata-scsi.c +0 -2
index 47ea111..5ecf260 100644
@@ -2833,8 +2833,13 @@ static inline int __ata_scsi_queuecmd(st
 			rc = ata_scsi_translate(dev, cmd, done, xlat_func);
 		else
 			ata_scsi_simulate(dev, cmd, done);
-	} else
-		rc = ata_scsi_translate(dev, cmd, done, atapi_xlat);

drivers/ata/libata-scsi.c static inline int __ata_scsi_queuecmd(st · line 2845

Quoted 10 lines
drivers/ata/libata-scsi.c +7 -0
+	} else {
+		/* Simulate REPORT LUNS for ATAPI devices */
+		if (cmd->cmnd[0] == REPORT_LUNS)
+			ata_scsi_simulate(dev, cmd, done);
+		else
+			rc = ata_scsi_translate(dev, cmd, done, atapi_xlat);
+	}
 
 	return rc;
 }

-- Patrick Mansfield

#15 lore raw

Re: [PATCH v2] libata: Simulate REPORT LUNS for ATAPI devices

Quoted 9 lines · Patrick Mansfield
Quoted 7 lines · Darrick J. Wong

The Quantum GoVault SATAPI removable disk device returns ATA_ERR in response to a REPORT LUNS packet. If this happens to an ATAPI device that is attached to a SAS controller (this is the case with sas_ata), the device does not load because SCSI won't touch a "SCSI device" that won't report its LUNs. Since most ATAPI devices don't support multiple LUNs anyway, we might as well fake a response like we do for ATA devices.

Quoted 3 lines

If the REPORT LUNS fails, we should fall back to a sequential scan.

Is (or why isn't) the error propagated back to scsi?

I believe the error is reported back to SCSI, which attempts to follow up with TEST UNIT READY. Unfortunately, for some reason the device then gets dropped. libata normally calls __scsi_add_device with lun=0, but SAS calls scsi_scan_target with lun=SCAN_WILD_CARD, which is why SCSI sends REPORT LUNs in the first place.

As an alternative I suppose we could detect ATA devices in sas_rphy_add and change that SCAN_WILD_CARD to "0".

--D