diff options
Diffstat (limited to 'drivers/ata/pata_scc.c')
-rw-r--r-- | drivers/ata/pata_scc.c | 91 |
1 files changed, 51 insertions, 40 deletions
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 2b9da715c704..accc275e74cc 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c | |||
@@ -497,47 +497,68 @@ static unsigned int scc_devchk (struct ata_port *ap, | |||
497 | } | 497 | } |
498 | 498 | ||
499 | /** | 499 | /** |
500 | * scc_bus_post_reset - PATA device post reset | 500 | * scc_wait_after_reset - wait for devices to become ready after reset |
501 | * | 501 | * |
502 | * Note: Original code is ata_bus_post_reset(). | 502 | * Note: Original code is ata_sff_wait_after_reset |
503 | */ | 503 | */ |
504 | 504 | ||
505 | static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask, | 505 | int scc_wait_after_reset(struct ata_link *link, unsigned int devmask, |
506 | unsigned long deadline) | 506 | unsigned long deadline) |
507 | { | 507 | { |
508 | struct ata_port *ap = link->ap; | ||
508 | struct ata_ioports *ioaddr = &ap->ioaddr; | 509 | struct ata_ioports *ioaddr = &ap->ioaddr; |
509 | unsigned int dev0 = devmask & (1 << 0); | 510 | unsigned int dev0 = devmask & (1 << 0); |
510 | unsigned int dev1 = devmask & (1 << 1); | 511 | unsigned int dev1 = devmask & (1 << 1); |
511 | int rc; | 512 | int rc, ret = 0; |
513 | |||
514 | /* Spec mandates ">= 2ms" before checking status. We wait | ||
515 | * 150ms, because that was the magic delay used for ATAPI | ||
516 | * devices in Hale Landis's ATADRVR, for the period of time | ||
517 | * between when the ATA command register is written, and then | ||
518 | * status is checked. Because waiting for "a while" before | ||
519 | * checking status is fine, post SRST, we perform this magic | ||
520 | * delay here as well. | ||
521 | * | ||
522 | * Old drivers/ide uses the 2mS rule and then waits for ready. | ||
523 | */ | ||
524 | msleep(150); | ||
512 | 525 | ||
513 | /* if device 0 was found in ata_devchk, wait for its | 526 | /* always check readiness of the master device */ |
514 | * BSY bit to clear | 527 | rc = ata_sff_wait_ready(link, deadline); |
528 | /* -ENODEV means the odd clown forgot the D7 pulldown resistor | ||
529 | * and TF status is 0xff, bail out on it too. | ||
515 | */ | 530 | */ |
516 | if (dev0) { | 531 | if (rc) |
517 | rc = ata_sff_wait_ready(ap, deadline); | 532 | return rc; |
518 | if (rc && rc != -ENODEV) | ||
519 | return rc; | ||
520 | } | ||
521 | 533 | ||
522 | /* if device 1 was found in ata_devchk, wait for | 534 | /* if device 1 was found in ata_devchk, wait for register |
523 | * register access, then wait for BSY to clear | 535 | * access briefly, then wait for BSY to clear. |
524 | */ | 536 | */ |
525 | while (dev1) { | 537 | if (dev1) { |
526 | u8 nsect, lbal; | 538 | int i; |
527 | 539 | ||
528 | ap->ops->sff_dev_select(ap, 1); | 540 | ap->ops->sff_dev_select(ap, 1); |
529 | nsect = in_be32(ioaddr->nsect_addr); | 541 | |
530 | lbal = in_be32(ioaddr->lbal_addr); | 542 | /* Wait for register access. Some ATAPI devices fail |
531 | if ((nsect == 1) && (lbal == 1)) | 543 | * to set nsect/lbal after reset, so don't waste too |
532 | break; | 544 | * much time on it. We're gonna wait for !BSY anyway. |
533 | if (time_after(jiffies, deadline)) | 545 | */ |
534 | return -EBUSY; | 546 | for (i = 0; i < 2; i++) { |
535 | msleep(50); /* give drive a breather */ | 547 | u8 nsect, lbal; |
536 | } | 548 | |
537 | if (dev1) { | 549 | nsect = in_be32(ioaddr->nsect_addr); |
538 | rc = ata_sff_wait_ready(ap, deadline); | 550 | lbal = in_be32(ioaddr->lbal_addr); |
539 | if (rc && rc != -ENODEV) | 551 | if ((nsect == 1) && (lbal == 1)) |
540 | return rc; | 552 | break; |
553 | msleep(50); /* give drive a breather */ | ||
554 | } | ||
555 | |||
556 | rc = ata_sff_wait_ready(link, deadline); | ||
557 | if (rc) { | ||
558 | if (rc != -ENODEV) | ||
559 | return rc; | ||
560 | ret = rc; | ||
561 | } | ||
541 | } | 562 | } |
542 | 563 | ||
543 | /* is all this really necessary? */ | 564 | /* is all this really necessary? */ |
@@ -547,7 +568,7 @@ static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask, | |||
547 | if (dev0) | 568 | if (dev0) |
548 | ap->ops->sff_dev_select(ap, 0); | 569 | ap->ops->sff_dev_select(ap, 0); |
549 | 570 | ||
550 | return 0; | 571 | return ret; |
551 | } | 572 | } |
552 | 573 | ||
553 | /** | 574 | /** |
@@ -570,17 +591,7 @@ static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, | |||
570 | udelay(20); | 591 | udelay(20); |
571 | out_be32(ioaddr->ctl_addr, ap->ctl); | 592 | out_be32(ioaddr->ctl_addr, ap->ctl); |
572 | 593 | ||
573 | /* wait a while before checking status */ | 594 | scc_wait_after_reset(&ap->link, devmask, deadlien); |
574 | ata_sff_wait_after_reset(ap, deadline); | ||
575 | |||
576 | /* Before we perform post reset processing we want to see if | ||
577 | * the bus shows 0xFF because the odd clown forgets the D7 | ||
578 | * pulldown resistor. | ||
579 | */ | ||
580 | if (scc_check_status(ap) == 0xFF) | ||
581 | return 0; | ||
582 | |||
583 | scc_bus_post_reset(ap, devmask, deadline); | ||
584 | 595 | ||
585 | return 0; | 596 | return 0; |
586 | } | 597 | } |