aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/sata_inic162x.c47
1 files changed, 45 insertions, 2 deletions
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index 1b10455e1ae0..97267ab001ed 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -410,6 +410,41 @@ static unsigned int inic_qc_issue(struct ata_queued_cmd *qc)
410 return ata_sff_qc_issue(qc); 410 return ata_sff_qc_issue(qc);
411} 411}
412 412
413static void inic_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
414{
415 void __iomem *port_base = inic_port_base(ap);
416
417 tf->feature = readb(port_base + PORT_TF_FEATURE);
418 tf->nsect = readb(port_base + PORT_TF_NSECT);
419 tf->lbal = readb(port_base + PORT_TF_LBAL);
420 tf->lbam = readb(port_base + PORT_TF_LBAM);
421 tf->lbah = readb(port_base + PORT_TF_LBAH);
422 tf->device = readb(port_base + PORT_TF_DEVICE);
423 tf->command = readb(port_base + PORT_TF_COMMAND);
424}
425
426static bool inic_qc_fill_rtf(struct ata_queued_cmd *qc)
427{
428 struct ata_taskfile *rtf = &qc->result_tf;
429 struct ata_taskfile tf;
430
431 /* FIXME: Except for status and error, result TF access
432 * doesn't work. I tried reading from BAR0/2, CPB and BAR5.
433 * None works regardless of which command interface is used.
434 * For now return true iff status indicates device error.
435 * This means that we're reporting bogus sector for RW
436 * failures. Eeekk....
437 */
438 inic_tf_read(qc->ap, &tf);
439
440 if (!(tf.command & ATA_ERR))
441 return false;
442
443 rtf->command = tf.command;
444 rtf->feature = tf.feature;
445 return true;
446}
447
413static void inic_freeze(struct ata_port *ap) 448static void inic_freeze(struct ata_port *ap)
414{ 449{
415 void __iomem *port_base = inic_port_base(ap); 450 void __iomem *port_base = inic_port_base(ap);
@@ -430,6 +465,13 @@ static void inic_thaw(struct ata_port *ap)
430 __inic_set_pirq_mask(ap, PIRQ_MASK_OTHER); 465 __inic_set_pirq_mask(ap, PIRQ_MASK_OTHER);
431} 466}
432 467
468static int inic_check_ready(struct ata_link *link)
469{
470 void __iomem *port_base = inic_port_base(link->ap);
471
472 return ata_check_ready(readb(port_base + PORT_TF_COMMAND));
473}
474
433/* 475/*
434 * SRST and SControl hardreset don't give valid signature on this 476 * SRST and SControl hardreset don't give valid signature on this
435 * controller. Only controller specific hardreset mechanism works. 477 * controller. Only controller specific hardreset mechanism works.
@@ -465,7 +507,7 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class,
465 struct ata_taskfile tf; 507 struct ata_taskfile tf;
466 508
467 /* wait for link to become ready */ 509 /* wait for link to become ready */
468 rc = ata_sff_wait_after_reset(link, 1, deadline); 510 rc = ata_wait_after_reset(link, deadline, inic_check_ready);
469 /* link occupied, -ENODEV too is an error */ 511 /* link occupied, -ENODEV too is an error */
470 if (rc) { 512 if (rc) {
471 ata_link_printk(link, KERN_WARNING, "device not ready " 513 ata_link_printk(link, KERN_WARNING, "device not ready "
@@ -473,7 +515,7 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class,
473 return rc; 515 return rc;
474 } 516 }
475 517
476 ata_sff_tf_read(ap, &tf); 518 inic_tf_read(ap, &tf);
477 *class = ata_dev_classify(&tf); 519 *class = ata_dev_classify(&tf);
478 } 520 }
479 521
@@ -569,6 +611,7 @@ static struct ata_port_operations inic_port_ops = {
569 .bmdma_stop = inic_bmdma_stop, 611 .bmdma_stop = inic_bmdma_stop,
570 .bmdma_status = inic_bmdma_status, 612 .bmdma_status = inic_bmdma_status,
571 .qc_issue = inic_qc_issue, 613 .qc_issue = inic_qc_issue,
614 .qc_fill_rtf = inic_qc_fill_rtf,
572 615
573 .freeze = inic_freeze, 616 .freeze = inic_freeze,
574 .thaw = inic_thaw, 617 .thaw = inic_thaw,