aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-04-30 03:35:14 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-05-06 11:40:55 -0400
commitb3f677e501a494aa1582d4ff35fb3ac6f0a59b08 (patch)
tree07742b58e6ad35add7cefc5027a87a25e72bb8d1 /drivers
parent049e8e04986bde66df9648d88d0960ab4cbd6992 (diff)
sata_inic162x: use IDMA for ATAPI commands
Use IDMA for ATAPI commands. Write and some misc commands time out when executed using ATAPI_PROT_DMA but ATAPI_PROT_PIO works fine. As PIO is driven by DMA too, it doesn't make any noticeable difference for native SATA devices. inic_check_atapi_dma() is implemented to force PIO for those ATAPI commands. After this change, sata_inic162x issues all commands using IDMA. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/sata_inic162x.c81
1 files changed, 47 insertions, 34 deletions
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index 579154c27902..cdae435620f6 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -192,7 +192,8 @@ struct inic_prd {
192 192
193struct inic_pkt { 193struct inic_pkt {
194 struct inic_cpb cpb; 194 struct inic_cpb cpb;
195 struct inic_prd prd[LIBATA_MAX_PRD]; 195 struct inic_prd prd[LIBATA_MAX_PRD + 1]; /* + 1 for cdb */
196 u8 cdb[ATAPI_CDB_LEN];
196} __packed; 197} __packed;
197 198
198struct inic_host_priv { 199struct inic_host_priv {
@@ -361,23 +362,18 @@ static void inic_host_intr(struct ata_port *ap)
361 goto spurious; 362 goto spurious;
362 } 363 }
363 364
364 if (!ata_is_atapi(qc->tf.protocol)) { 365 if (likely(idma_stat & IDMA_STAT_DONE)) {
365 if (likely(idma_stat & IDMA_STAT_DONE)) { 366 inic_stop_idma(ap);
366 inic_stop_idma(ap);
367 367
368 /* Depending on circumstances, device error 368 /* Depending on circumstances, device error
369 * isn't reported by IDMA, check it explicitly. 369 * isn't reported by IDMA, check it explicitly.
370 */ 370 */
371 if (unlikely(readb(port_base + PORT_TF_COMMAND) & 371 if (unlikely(readb(port_base + PORT_TF_COMMAND) &
372 (ATA_DF | ATA_ERR))) 372 (ATA_DF | ATA_ERR)))
373 qc->err_mask |= AC_ERR_DEV; 373 qc->err_mask |= AC_ERR_DEV;
374 374
375 ata_qc_complete(qc); 375 ata_qc_complete(qc);
376 return; 376 return;
377 }
378 } else {
379 if (likely(ata_sff_host_intr(ap, qc)))
380 return;
381 } 377 }
382 378
383 spurious: 379 spurious:
@@ -421,6 +417,19 @@ static irqreturn_t inic_interrupt(int irq, void *dev_instance)
421 return IRQ_RETVAL(handled); 417 return IRQ_RETVAL(handled);
422} 418}
423 419
420static int inic_check_atapi_dma(struct ata_queued_cmd *qc)
421{
422 /* For some reason ATAPI_PROT_DMA doesn't work for some
423 * commands including writes and other misc ops. Use PIO
424 * protocol instead, which BTW is driven by the DMA engine
425 * anyway, so it shouldn't make much difference for native
426 * SATA devices.
427 */
428 if (atapi_cmd_type(qc->cdb[0]) == READ)
429 return 0;
430 return 1;
431}
432
424static void inic_fill_sg(struct inic_prd *prd, struct ata_queued_cmd *qc) 433static void inic_fill_sg(struct inic_prd *prd, struct ata_queued_cmd *qc)
425{ 434{
426 struct scatterlist *sg; 435 struct scatterlist *sg;
@@ -452,20 +461,21 @@ static void inic_qc_prep(struct ata_queued_cmd *qc)
452 struct inic_prd *prd = pkt->prd; 461 struct inic_prd *prd = pkt->prd;
453 bool is_atapi = ata_is_atapi(qc->tf.protocol); 462 bool is_atapi = ata_is_atapi(qc->tf.protocol);
454 bool is_data = ata_is_data(qc->tf.protocol); 463 bool is_data = ata_is_data(qc->tf.protocol);
464 unsigned int cdb_len = 0;
455 465
456 VPRINTK("ENTER\n"); 466 VPRINTK("ENTER\n");
457 467
458 if (is_atapi) 468 if (is_atapi)
459 return; 469 cdb_len = qc->dev->cdb_len;
460 470
461 /* prepare packet, based on initio driver */ 471 /* prepare packet, based on initio driver */
462 memset(pkt, 0, sizeof(struct inic_pkt)); 472 memset(pkt, 0, sizeof(struct inic_pkt));
463 473
464 cpb->ctl_flags = CPB_CTL_VALID | CPB_CTL_IEN; 474 cpb->ctl_flags = CPB_CTL_VALID | CPB_CTL_IEN;
465 if (is_data) 475 if (is_atapi || is_data)
466 cpb->ctl_flags |= CPB_CTL_DATA; 476 cpb->ctl_flags |= CPB_CTL_DATA;
467 477
468 cpb->len = cpu_to_le32(qc->nbytes); 478 cpb->len = cpu_to_le32(qc->nbytes + cdb_len);
469 cpb->prd = cpu_to_le32(pp->pkt_dma + offsetof(struct inic_pkt, prd)); 479 cpb->prd = cpu_to_le32(pp->pkt_dma + offsetof(struct inic_pkt, prd));
470 480
471 cpb->device = qc->tf.device; 481 cpb->device = qc->tf.device;
@@ -486,6 +496,18 @@ static void inic_qc_prep(struct ata_queued_cmd *qc)
486 cpb->command = qc->tf.command; 496 cpb->command = qc->tf.command;
487 /* don't load ctl - dunno why. it's like that in the initio driver */ 497 /* don't load ctl - dunno why. it's like that in the initio driver */
488 498
499 /* setup PRD for CDB */
500 if (is_atapi) {
501 memcpy(pkt->cdb, qc->cdb, ATAPI_CDB_LEN);
502 prd->mad = cpu_to_le32(pp->pkt_dma +
503 offsetof(struct inic_pkt, cdb));
504 prd->len = cpu_to_le16(cdb_len);
505 prd->flags = PRD_CDB | PRD_WRITE;
506 if (!is_data)
507 prd->flags |= PRD_END;
508 prd++;
509 }
510
489 /* setup sg table */ 511 /* setup sg table */
490 if (is_data) 512 if (is_data)
491 inic_fill_sg(prd, qc); 513 inic_fill_sg(prd, qc);
@@ -498,16 +520,12 @@ static unsigned int inic_qc_issue(struct ata_queued_cmd *qc)
498 struct ata_port *ap = qc->ap; 520 struct ata_port *ap = qc->ap;
499 void __iomem *port_base = inic_port_base(ap); 521 void __iomem *port_base = inic_port_base(ap);
500 522
501 if (!ata_is_atapi(qc->tf.protocol)) { 523 /* fire up the ADMA engine */
502 /* fire up the ADMA engine */ 524 writew(HCTL_FTHD0, port_base + HOST_CTL);
503 writew(HCTL_FTHD0, port_base + HOST_CTL); 525 writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL);
504 writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL); 526 writeb(0, port_base + PORT_CPB_PTQFIFO);
505 writeb(0, port_base + PORT_CPB_PTQFIFO);
506
507 return 0;
508 }
509 527
510 return ata_sff_qc_issue(qc); 528 return 0;
511} 529}
512 530
513static void inic_tf_read(struct ata_port *ap, struct ata_taskfile *tf) 531static void inic_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
@@ -698,6 +716,7 @@ static int inic_port_start(struct ata_port *ap)
698static struct ata_port_operations inic_port_ops = { 716static struct ata_port_operations inic_port_ops = {
699 .inherits = &ata_sff_port_ops, 717 .inherits = &ata_sff_port_ops,
700 718
719 .check_atapi_dma = inic_check_atapi_dma,
701 .qc_prep = inic_qc_prep, 720 .qc_prep = inic_qc_prep,
702 .qc_issue = inic_qc_issue, 721 .qc_issue = inic_qc_issue,
703 .qc_fill_rtf = inic_qc_fill_rtf, 722 .qc_fill_rtf = inic_qc_fill_rtf,
@@ -717,12 +736,6 @@ static struct ata_port_operations inic_port_ops = {
717}; 736};
718 737
719static struct ata_port_info inic_port_info = { 738static struct ata_port_info inic_port_info = {
720 /* For some reason, ATAPI_PROT_PIO is broken on this
721 * controller, and no, PIO_POLLING does't fix it. It somehow
722 * manages to report the wrong ireason and ignoring ireason
723 * results in machine lock up. Tell libata to always prefer
724 * DMA.
725 */
726 .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA, 739 .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
727 .pio_mask = 0x1f, /* pio0-4 */ 740 .pio_mask = 0x1f, /* pio0-4 */
728 .mwdma_mask = 0x07, /* mwdma0-2 */ 741 .mwdma_mask = 0x07, /* mwdma0-2 */