aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-05-01 10:55:58 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-05-06 11:40:53 -0400
commit364fac0e56b9bd379330ef9e39d3761f0b491e2c (patch)
tree7812a44cd9213a53b69f1e6de74579c270a0b0fc /drivers/ata
parentb0dd9b8ef985291a8b40118c5f33b7935e273dcb (diff)
sata_inic162x: update TF read handling
inic162x can't reliably read back TF or at least we don't know how to do it yet. The only values which seem reliable are status and error. This patch updates access to TF. * implement inic_tf_read() which reads the TF area in mmio area * implement custom inic_qc_fill_rtf() which only returns true if status indicates device error. it'll be returning bogus addresses for device errors but it'll be able to report why it failed at least. * implement custom inic_check_ready() and use ata_wait_after_reset() instead of the SFF version. * use inic_tf_read() for classification. This is not perfect but it fixes hotplug detection failure and at least makes the driver report 0's instead of random garbages while reporting valid status and error for device errors. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-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,