diff options
| -rw-r--r-- | drivers/ata/sata_inic162x.c | 47 |
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 | ||
| 413 | static 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 | |||
| 426 | static 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 | |||
| 413 | static void inic_freeze(struct ata_port *ap) | 448 | static 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 | ||
| 468 | static 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, |
