]> err.no Git - linux-2.6/commitdiff
libata_scsi: Fix ATAPI transfer lengths
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Tue, 2 Oct 2007 20:53:04 +0000 (13:53 -0700)
committerJeff Garzik <jeff@garzik.org>
Fri, 12 Oct 2007 18:55:45 +0000 (14:55 -0400)
Some controller variants snoop the ATAPI length value for Packet
transfers to do state machine and FIFO management. Thus we want to
set it properly, even for cases where it is otherwise meaningless.

Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/ata/libata-scsi.c

index df2e05738f3b3806238e10d5cc78bdb222270217..ea53e6a570b428e88cef5018c1318923c2d75667 100644 (file)
@@ -2305,8 +2305,8 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
                qc->tf.feature |= ATAPI_PKT_DMA;
        } else {
                qc->tf.protocol = ATA_PROT_ATAPI;
-               qc->tf.lbam = (8 * 1024) & 0xff;
-               qc->tf.lbah = (8 * 1024) >> 8;
+               qc->tf.lbam = SCSI_SENSE_BUFFERSIZE;
+               qc->tf.lbah = 0;
        }
        qc->nbytes = SCSI_SENSE_BUFFERSIZE;
 
@@ -2415,6 +2415,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
        struct ata_device *dev = qc->dev;
        int using_pio = (dev->flags & ATA_DFLAG_PIO);
        int nodata = (scmd->sc_data_direction == DMA_NONE);
+       unsigned int nbytes;
 
        memset(qc->cdb, 0, dev->cdb_len);
        memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len);
@@ -2434,14 +2435,20 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
        if (!using_pio && ata_check_atapi_dma(qc))
                using_pio = 1;
 
+       /* Some controller variants snoop this value for Packet transfers
+          to do state machine and FIFO management. Thus we want to set it
+          properly, and for DMA where it is effectively meaningless */
+       nbytes = min(qc->nbytes, (unsigned int)63 * 1024);
+
+       qc->tf.lbam = (nbytes & 0xFF);
+       qc->tf.lbah = (nbytes >> 8);
+
        if (using_pio || nodata) {
                /* no data, or PIO data xfer */
                if (nodata)
                        qc->tf.protocol = ATA_PROT_ATAPI_NODATA;
                else
                        qc->tf.protocol = ATA_PROT_ATAPI;
-               qc->tf.lbam = (8 * 1024) & 0xff;
-               qc->tf.lbah = (8 * 1024) >> 8;
        } else {
                /* DMA data xfer */
                qc->tf.protocol = ATA_PROT_ATAPI_DMA;
@@ -2452,6 +2459,9 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
                        qc->tf.feature |= ATAPI_DMADIR;
        }
 
+
+       /* FIXME: We need to translate 0x05 READ_BLOCK_LIMITS to a MODE_SENSE
+          as ATAPI tape drives don't get this right otherwise */
        return 0;
 }