From: "Darrick J. Wong" <djwong@us.ibm.com>
To: Jeff Garzik <jeff@garzik.org>
Cc: linux-scsi <linux-scsi@vger.kernel.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: libata: Simulate REPORT LUNS for ATAPI devices when not supported
Date: Mon, 04 Dec 2006 15:02:38 -0800 [thread overview]
Message-ID: <4574A90E.5010801@us.ibm.com> (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.
Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
---
drivers/ata/libata-core.c | 36 ++++++++++++++++++++++++++++++++----
drivers/ata/libata-scsi.c | 4 ++--
include/linux/libata.h | 2 ++
3 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 915a55a..a3d6217 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -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);
}
/**
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 47ea111..da013a7 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -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;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index abd2deb..b37b21f 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -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 *);
next reply other threads:[~2006-12-04 23:02 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-04 23:02 Darrick J. Wong [this message]
2006-12-04 23:12 ` libata: Simulate REPORT LUNS for ATAPI devices when not supported Jeff Garzik
2006-12-04 23:32 ` [PATCH v2] libata: Simulate REPORT LUNS for ATAPI devices Darrick J. Wong
2006-12-07 12:20 ` Jeff Garzik
2006-12-07 15:47 ` Douglas Gilbert
2006-12-07 18:09 ` James Bottomley
2006-12-07 19:13 ` Douglas Gilbert
2006-12-11 16:24 ` Jeff Garzik
2006-12-11 16:44 ` James Bottomley
2006-12-11 16:59 ` Jeff Garzik
2006-12-12 22:24 ` Darrick J. Wong
2006-12-13 16:10 ` James Bottomley
2006-12-13 17:38 ` Darrick J. Wong
2006-12-13 17:57 ` James Bottomley
2006-12-13 18:56 ` Patrick Mansfield
2006-12-13 20:06 ` Darrick J. Wong
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=4574A90E.5010801@us.ibm.com \
--to=djwong@us.ibm.com \
--cc=jeff@garzik.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.