From mboxrd@z Thu Jan 1 00:00:00 1970
From: Pat LaVarre
Subject: SATA ATAPI work in progress
Date: 12 May 2004 14:20:34 -0600
Sender: linux-ide-owner@vger.kernel.org
Message-ID: <1084393233.3999.2.camel@patibmrh9>
Mime-Version: 1.0
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
Return-path:
Received: from email-out1.iomega.com ([147.178.1.82]:26798 "EHLO
email.iomega.com") by vger.kernel.org with ESMTP id S265217AbUELUU6
(ORCPT );
Wed, 12 May 2004 16:20:58 -0400
List-Id: linux-ide@vger.kernel.org
To: jgarzik@pobox.com
Cc: linux-ide@vger.kernel.org
Jeff G:
> From: linux-2.6.6-bk1/drivers/scsi/ata_piix.c
> ...
> Maintained by: Jeff Garzik
> Please ALWAYS copy linux-ide@vger.kernel.org on emails.
Ok, hi.
> > From: [offline]
> > 1) atapi_scsi_queuecmd() should be deleted,
> > and instead a translation function should be
> > supplied for ata_scsi_translate() for all
> > ATAPI devices, resulting in a PACKET
> > taskfile.
For 2.6.6-bk1 I wrote the following trivial patch.
Is my patch a step forward?
Given ATA_ENABLE_ATAPI ATA_DEBUG ATA_VERBOSE_DEBUG, then now the initial
op x12 Inquiry now instead chokes via:
kernel: ata2: DMA timeout, stat 0x21
kernel: ata_dma_complete: ENTER
kernel: ata_dma_complete: host 2, host_stat==0x21, drv_stat==0x58
kernel: ATA: abnormal status 0x58 on port 0xE007
Looks like I've asked to start the Data DMA In before my PIO Command
Out? Left to myself, maybe next I'll go digging in ata_tf_load_pio and
ata_exec_command_pio.
> From: linux-2.6.6-bk1/
`modprobe -r ata-piix; modprobe ata-piix` now seemingly work without
reboot, thank you.
> > From: [offline]
> > 2) Issue and process a REQUEST SENSE
> > internally, based on the PACKET ... returns.
This means "auto sense", I think.
> > based on the PACKET sense key returns.
This means auto sense when (x1F1 Error & xF0 SK) are nonzero, I think.
This design choice surprises me. I vote we auto sense when (x3F6
AlternateStatus & x01 ERR) is nonzero, so that still we see sense even
when SK ASC ASCQ is zero, in particular when ASC ASCQ is nonzero in
combination with zero SK. Also we thus duck trusting the redundant copy
of SK.
Pat LaVarre
diff -Nurp linux-2.6.6-bk1/drivers/scsi/libata-scsi.c linux-2.6.6-bk1-pel/drivers/scsi/libata-scsi.c
--- linux-2.6.6-bk1/drivers/scsi/libata-scsi.c 2004-05-12 09:57:09.000000000 -0600
+++ linux-2.6.6-bk1-pel/drivers/scsi/libata-scsi.c 2004-05-12 14:01:27.530354416 -0600
@@ -215,6 +215,35 @@ int ata_scsi_error(struct Scsi_Host *hos
DPRINTK("EXIT\n");
return 0;
+}
+
+/**
+ * atapi_xlat - Pass SCSI r/w command thru to ATAPI
+ * @qc: Storage for translated ATA taskfile
+ * @scsicmd: SCSI command to translate
+ *
+ * Trust caller already cleared *qc->tf (often via ata_tf_init),
+ * deciding tf->device & (0x10 ATA_DEV1 | 0x07 SFF 8070i LUN), etc.
+ *
+ * RETURNS:
+ * Zero on success, non-zero on error.
+ */
+
+static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
+{
+ struct ata_taskfile *tf = &qc->tf;
+ tf->flags &= ~ATA_TFLAG_LBA48;
+ tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ tf->protocol = qc->dev->xfer_protocol;
+#ifdef ATA_FORCE_PIO
+#else
+ tf->feature = ATAPI_PKT_DMA; /* often x01 */
+#endif
+ tf->lbam = 0xFE; /* PIO "byte count limit" */
+ tf->lbah = 0xFF;
+ tf->command = ATA_CMD_PACKET; /* often 0xA0 */
+ DPRINTK("ATAPI\n");
+ return 0;
}
/**
@@ -885,78 +914,6 @@ void ata_scsi_badcmd(struct scsi_cmnd *c
}
/**
- * atapi_scsi_queuecmd - Send CDB to ATAPI device
- * @ap: Port to which ATAPI device is attached.
- * @dev: Target device for CDB.
- * @cmd: SCSI command being sent to device.
- * @done: SCSI command completion function.
- *
- * Sends CDB to ATAPI device. If the Linux SCSI layer sends a
- * non-data command, then this function handles the command
- * directly, via polling. Otherwise, the bmdma engine is started.
- *
- * LOCKING:
- * spin_lock_irqsave(host_set lock)
- */
-
-static void atapi_scsi_queuecmd(struct ata_port *ap, struct ata_device *dev,
- struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
-{
- struct ata_queued_cmd *qc;
- u8 *scsicmd = cmd->cmnd;
-
- VPRINTK("ENTER, drv_stat = 0x%x\n", ata_chk_status(ap));
-
- if (cmd->sc_data_direction == SCSI_DATA_UNKNOWN) {
- DPRINTK("unknown data, scsicmd 0x%x\n", scsicmd[0]);
- ata_bad_cdb(cmd, done);
- return;
- }
-
- switch(scsicmd[0]) {
- case READ_6:
- case WRITE_6:
- case MODE_SELECT:
- case MODE_SENSE:
- DPRINTK("read6/write6/modesel/modesense trap\n");
- ata_bad_scsiop(cmd, done);
- return;
-
- default:
- /* do nothing */
- break;
- }
-
- qc = ata_scsi_qc_new(ap, dev, cmd, done);
- if (!qc) {
- printk(KERN_ERR "ata%u: command queue empty\n", ap->id);
- return;
- }
-
- qc->flags |= ATA_QCFLAG_ATAPI;
-
- qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
- if (cmd->sc_data_direction == SCSI_DATA_WRITE) {
- qc->tf.flags |= ATA_TFLAG_WRITE;
- DPRINTK("direction: write\n");
- }
-
- qc->tf.command = ATA_CMD_PACKET;
-
- if (cmd->sc_data_direction == SCSI_DATA_NONE) {
- qc->tf.protocol = ATA_PROT_ATAPI;
- qc->flags |= ATA_QCFLAG_POLL;
- qc->tf.ctl |= ATA_NIEN; /* disable interrupts */
- } else {
- qc->tf.protocol = ATA_PROT_ATAPI_DMA;
- qc->flags |= ATA_QCFLAG_SG; /* data is present; dma-map it */
- qc->tf.feature |= ATAPI_PKT_DMA;
- }
-
- atapi_start(qc);
-}
-
-/**
* ata_scsi_find_dev - lookup ata_device from scsi_cmnd
* @ap: ATA port to which the device is attached
* @cmd: SCSI command to be sent to the device
@@ -1086,13 +1043,13 @@ int ata_scsi_queuecmd(struct scsi_cmnd *
if (dev->class == ATA_DEV_ATA) {
ata_xlat_func_t xlat_func = ata_get_xlat_func(cmd->cmnd[0]);
-
if (xlat_func)
ata_scsi_translate(ap, dev, cmd, done, xlat_func);
else
ata_scsi_simulate(ap, dev, cmd, done);
- } else
- atapi_scsi_queuecmd(ap, dev, cmd, done);
+ } else {
+ ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
+ }
out_unlock:
return 0;