diff options
author | Mikael Pettersson <mikpe@it.uu.se> | 2007-01-13 15:32:30 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-09 17:39:34 -0500 |
commit | fba6edbd3bbd5e6c10b8247d3c3794e718bbc811 (patch) | |
tree | 4b6fed09aea236aed161c29d8536ce2300294a79 /drivers/ata/sata_promise.c | |
parent | 4113bb6b67ced963b3269a72f335dd278543b56d (diff) |
sata_promise: handle ATAPI_NODATA ourselves
This patch extends sata_promise to handle ATAPI_NODATA
commands internally. However, commands destined to
ATA_DFLAG_CDB_INTR devices are excluded from this and
continue to be returned to libata.
Concrete changes:
- pdc_atapi_dma_pkt() is renamed to pdc_atapi_pkt(), and is
extended to set up correct headers for NODATA packets
- pdc_qc_prep() calls pdc_atapi_pkt() for ATAPI_NODATA
- pdc_host_intr() handles ATAPI_NODATA
- pdc_qc_issue_prot() sends ATAPI_NODATA packets via the
chip's packet mechanism, except for CDB_INTR devices
Tested on first- and second-generation chips, SATAPI and PATAPI,
with no observable regressions.
Signed-off-by: Mikael Pettersson <mikpe@it.uu.se>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/sata_promise.c')
-rw-r--r-- | drivers/ata/sata_promise.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 9d73cb9de42a..551644a94861 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
@@ -448,7 +448,7 @@ static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, | |||
448 | writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); | 448 | writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); |
449 | } | 449 | } |
450 | 450 | ||
451 | static void pdc_atapi_dma_pkt(struct ata_queued_cmd *qc) | 451 | static void pdc_atapi_pkt(struct ata_queued_cmd *qc) |
452 | { | 452 | { |
453 | struct ata_port *ap = qc->ap; | 453 | struct ata_port *ap = qc->ap; |
454 | dma_addr_t sg_table = ap->prd_dma; | 454 | dma_addr_t sg_table = ap->prd_dma; |
@@ -462,10 +462,20 @@ static void pdc_atapi_dma_pkt(struct ata_queued_cmd *qc) | |||
462 | /* set control bits (byte 0), zero delay seq id (byte 3), | 462 | /* set control bits (byte 0), zero delay seq id (byte 3), |
463 | * and seq id (byte 2) | 463 | * and seq id (byte 2) |
464 | */ | 464 | */ |
465 | if (!(qc->tf.flags & ATA_TFLAG_WRITE)) | 465 | switch (qc->tf.protocol) { |
466 | buf32[0] = cpu_to_le32(PDC_PKT_READ); | 466 | case ATA_PROT_ATAPI_DMA: |
467 | else | 467 | if (!(qc->tf.flags & ATA_TFLAG_WRITE)) |
468 | buf32[0] = 0; | 468 | buf32[0] = cpu_to_le32(PDC_PKT_READ); |
469 | else | ||
470 | buf32[0] = 0; | ||
471 | break; | ||
472 | case ATA_PROT_ATAPI_NODATA: | ||
473 | buf32[0] = cpu_to_le32(PDC_PKT_NODATA); | ||
474 | break; | ||
475 | default: | ||
476 | BUG(); | ||
477 | break; | ||
478 | } | ||
469 | buf32[1] = cpu_to_le32(sg_table); /* S/G table addr */ | 479 | buf32[1] = cpu_to_le32(sg_table); /* S/G table addr */ |
470 | buf32[2] = 0; /* no next-packet */ | 480 | buf32[2] = 0; /* no next-packet */ |
471 | 481 | ||
@@ -549,13 +559,14 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc) | |||
549 | break; | 559 | break; |
550 | 560 | ||
551 | case ATA_PROT_ATAPI: | 561 | case ATA_PROT_ATAPI: |
552 | case ATA_PROT_ATAPI_NODATA: | ||
553 | ata_qc_prep(qc); | 562 | ata_qc_prep(qc); |
554 | break; | 563 | break; |
555 | 564 | ||
556 | case ATA_PROT_ATAPI_DMA: | 565 | case ATA_PROT_ATAPI_DMA: |
557 | ata_qc_prep(qc); | 566 | ata_qc_prep(qc); |
558 | pdc_atapi_dma_pkt(qc); | 567 | /*FALLTHROUGH*/ |
568 | case ATA_PROT_ATAPI_NODATA: | ||
569 | pdc_atapi_pkt(qc); | ||
559 | break; | 570 | break; |
560 | 571 | ||
561 | default: | 572 | default: |
@@ -672,6 +683,7 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap, | |||
672 | case ATA_PROT_DMA: | 683 | case ATA_PROT_DMA: |
673 | case ATA_PROT_NODATA: | 684 | case ATA_PROT_NODATA: |
674 | case ATA_PROT_ATAPI_DMA: | 685 | case ATA_PROT_ATAPI_DMA: |
686 | case ATA_PROT_ATAPI_NODATA: | ||
675 | qc->err_mask |= ac_err_mask(ata_wait_idle(ap)); | 687 | qc->err_mask |= ac_err_mask(ata_wait_idle(ap)); |
676 | ata_qc_complete(qc); | 688 | ata_qc_complete(qc); |
677 | handled = 1; | 689 | handled = 1; |
@@ -771,6 +783,10 @@ static inline void pdc_packet_start(struct ata_queued_cmd *qc) | |||
771 | static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc) | 783 | static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc) |
772 | { | 784 | { |
773 | switch (qc->tf.protocol) { | 785 | switch (qc->tf.protocol) { |
786 | case ATA_PROT_ATAPI_NODATA: | ||
787 | if (qc->dev->flags & ATA_DFLAG_CDB_INTR) | ||
788 | break; | ||
789 | /*FALLTHROUGH*/ | ||
774 | case ATA_PROT_ATAPI_DMA: | 790 | case ATA_PROT_ATAPI_DMA: |
775 | case ATA_PROT_DMA: | 791 | case ATA_PROT_DMA: |
776 | case ATA_PROT_NODATA: | 792 | case ATA_PROT_NODATA: |