ChangeSet 1.1982.33.1, 2005/02/05 23:12:30-05:00, [EMAIL PROTECTED]
Merge pobox.com:/garz/repo/linux-2.6
into pobox.com:/garz/repo/libata-dev/remove-one-fix
libata-core.c | 94 ++++++++++++++++++++++++++++++++++++++++------------------
1 files changed, 65 insertions(+), 29 deletions(-)
diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
--- a/drivers/scsi/libata-core.c 2005-03-07 11:22:13 -08:00
+++ b/drivers/scsi/libata-core.c 2005-03-07 11:22:13 -08:00
@@ -28,6 +28,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/list.h>
+#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/spinlock.h>
#include <linux/blkdev.h>
@@ -1919,7 +1920,24 @@
if (idx)
ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
}
+/**
+ * ata_check_atapi_dma - Check whether ATAPI DMA can be supported
+ * @qc: Metadata associated with taskfile to check
+ *
+ * LOCKING:
+ * RETURNS: 0 when ATAPI DMA can be used
+ * nonzero otherwise
+ */
+int ata_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ int rc = 0; /* Assume ATAPI DMA is OK by default */
+
+ if (ap->ops->check_atapi_dma)
+ rc = ap->ops->check_atapi_dma(qc);
+ return rc;
+}
/**
* ata_qc_prep - Prepare taskfile for submission
* @qc: Metadata associated with taskfile to be prepared
@@ -1950,8 +1968,6 @@
sg->page = virt_to_page(buf);
sg->offset = (unsigned long) buf & ~PAGE_MASK;
sg_dma_len(sg) = buflen;
-
- WARN_ON(buflen > PAGE_SIZE);
}
void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
@@ -2371,6 +2387,9 @@
unsigned long timeout = 0;
switch (ap->pio_task_state) {
+ case PIO_ST_IDLE:
+ return;
+
case PIO_ST:
ata_pio_block(ap);
break;
@@ -2387,18 +2406,14 @@
case PIO_ST_TMOUT:
case PIO_ST_ERR:
ata_pio_error(ap);
- break;
+ return;
}
- if ((ap->pio_task_state != PIO_ST_IDLE) &&
- (ap->pio_task_state != PIO_ST_TMOUT) &&
- (ap->pio_task_state != PIO_ST_ERR)) {
- if (timeout)
- queue_delayed_work(ata_wq, &ap->pio_task,
- timeout);
- else
- queue_work(ata_wq, &ap->pio_task);
- }
+ if (timeout)
+ queue_delayed_work(ata_wq, &ap->pio_task,
+ timeout);
+ else
+ queue_work(ata_wq, &ap->pio_task);
}
static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
@@ -2407,7 +2422,6 @@
DECLARE_COMPLETION(wait);
struct ata_queued_cmd *qc;
unsigned long flags;
- int using_pio = dev->flags & ATA_DFLAG_PIO;
int rc;
DPRINTK("ATAPI request sense\n");
@@ -2428,16 +2442,10 @@
qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
qc->tf.command = ATA_CMD_PACKET;
- if (using_pio) {
- qc->tf.protocol = ATA_PROT_ATAPI;
- qc->tf.lbam = (8 * 1024) & 0xff;
- qc->tf.lbah = (8 * 1024) >> 8;
-
- qc->nbytes = SCSI_SENSE_BUFFERSIZE;
- } else {
- qc->tf.protocol = ATA_PROT_ATAPI_DMA;
- qc->tf.feature |= ATAPI_PKT_DMA;
- }
+ qc->tf.protocol = ATA_PROT_ATAPI;
+ qc->tf.lbam = (8 * 1024) & 0xff;
+ qc->tf.lbah = (8 * 1024) >> 8;
+ qc->nbytes = SCSI_SENSE_BUFFERSIZE;
qc->waiting = &wait;
qc->complete_fn = ata_qc_complete_noop;
@@ -2693,6 +2701,30 @@
VPRINTK("EXIT\n");
}
+static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+
+ switch (qc->tf.protocol) {
+ case ATA_PROT_DMA:
+ case ATA_PROT_ATAPI_DMA:
+ return 1;
+
+ case ATA_PROT_ATAPI:
+ case ATA_PROT_PIO:
+ case ATA_PROT_PIO_MULT:
+ if (ap->flags & ATA_FLAG_PIO_DMA)
+ return 1;
+
+ /* fall through */
+
+ default:
+ return 0;
+ }
+
+ /* never reached */
+}
+
/**
* ata_qc_issue - issue taskfile to device
* @qc: command to issue to device
@@ -2713,12 +2745,16 @@
{
struct ata_port *ap = qc->ap;
- if (qc->flags & ATA_QCFLAG_SG) {
- if (ata_sg_setup(qc))
- goto err_out;
- } else if (qc->flags & ATA_QCFLAG_SINGLE) {
- if (ata_sg_setup_one(qc))
- goto err_out;
+ if (ata_should_dma_map(qc)) {
+ if (qc->flags & ATA_QCFLAG_SG) {
+ if (ata_sg_setup(qc))
+ goto err_out;
+ } else if (qc->flags & ATA_QCFLAG_SINGLE) {
+ if (ata_sg_setup_one(qc))
+ goto err_out;
+ }
+ } else {
+ qc->flags &= ~ATA_QCFLAG_DMAMAP;
}
ap->ops->qc_prep(qc);
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html