Skip to content

Commit

Permalink
libata_scsi: Fix ATAPI transfer lengths
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Alan Cox authored and Jeff Garzik committed Oct 12, 2007
1 parent 681c80b commit 2db78dd
Showing 1 changed file with 14 additions and 4 deletions.
18 changes: 14 additions & 4 deletions drivers/ata/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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;
}

Expand Down

0 comments on commit 2db78dd

Please sign in to comment.