Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2db78dd3 authored by Alan Cox's avatar Alan Cox Committed by Jeff Garzik
Browse files

libata_scsi: Fix ATAPI transfer lengths



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: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 681c80b5
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -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;
}