diff options
| -rw-r--r-- | drivers/ata/pata_scc.c | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index aa138d211b09..61502bc7bf1d 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c | |||
| @@ -489,23 +489,26 @@ static unsigned int scc_devchk (struct ata_port *ap, | |||
| 489 | * Note: Original code is ata_bus_post_reset(). | 489 | * Note: Original code is ata_bus_post_reset(). |
| 490 | */ | 490 | */ |
| 491 | 491 | ||
| 492 | static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask) | 492 | static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask, |
| 493 | unsigned long deadline) | ||
| 493 | { | 494 | { |
| 494 | struct ata_ioports *ioaddr = &ap->ioaddr; | 495 | struct ata_ioports *ioaddr = &ap->ioaddr; |
| 495 | unsigned int dev0 = devmask & (1 << 0); | 496 | unsigned int dev0 = devmask & (1 << 0); |
| 496 | unsigned int dev1 = devmask & (1 << 1); | 497 | unsigned int dev1 = devmask & (1 << 1); |
| 497 | unsigned long timeout; | 498 | int rc; |
| 498 | 499 | ||
| 499 | /* if device 0 was found in ata_devchk, wait for its | 500 | /* if device 0 was found in ata_devchk, wait for its |
| 500 | * BSY bit to clear | 501 | * BSY bit to clear |
| 501 | */ | 502 | */ |
| 502 | if (dev0) | 503 | if (dev0) { |
| 503 | ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); | 504 | rc = ata_wait_ready(ap, deadline); |
| 505 | if (rc && rc != -ENODEV) | ||
| 506 | return rc; | ||
| 507 | } | ||
| 504 | 508 | ||
| 505 | /* if device 1 was found in ata_devchk, wait for | 509 | /* if device 1 was found in ata_devchk, wait for |
| 506 | * register access, then wait for BSY to clear | 510 | * register access, then wait for BSY to clear |
| 507 | */ | 511 | */ |
| 508 | timeout = jiffies + ATA_TMOUT_BOOT; | ||
| 509 | while (dev1) { | 512 | while (dev1) { |
| 510 | u8 nsect, lbal; | 513 | u8 nsect, lbal; |
| 511 | 514 | ||
| @@ -514,14 +517,15 @@ static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask) | |||
| 514 | lbal = in_be32(ioaddr->lbal_addr); | 517 | lbal = in_be32(ioaddr->lbal_addr); |
| 515 | if ((nsect == 1) && (lbal == 1)) | 518 | if ((nsect == 1) && (lbal == 1)) |
| 516 | break; | 519 | break; |
| 517 | if (time_after(jiffies, timeout)) { | 520 | if (time_after(jiffies, deadline)) |
| 518 | dev1 = 0; | 521 | return -EBUSY; |
| 519 | break; | ||
| 520 | } | ||
| 521 | msleep(50); /* give drive a breather */ | 522 | msleep(50); /* give drive a breather */ |
| 522 | } | 523 | } |
| 523 | if (dev1) | 524 | if (dev1) { |
| 524 | ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); | 525 | rc = ata_wait_ready(ap, deadline); |
| 526 | if (rc && rc != -ENODEV) | ||
| 527 | return rc; | ||
| 528 | } | ||
| 525 | 529 | ||
| 526 | /* is all this really necessary? */ | 530 | /* is all this really necessary? */ |
| 527 | ap->ops->dev_select(ap, 0); | 531 | ap->ops->dev_select(ap, 0); |
| @@ -529,6 +533,8 @@ static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask) | |||
| 529 | ap->ops->dev_select(ap, 1); | 533 | ap->ops->dev_select(ap, 1); |
| 530 | if (dev0) | 534 | if (dev0) |
| 531 | ap->ops->dev_select(ap, 0); | 535 | ap->ops->dev_select(ap, 0); |
| 536 | |||
| 537 | return 0; | ||
| 532 | } | 538 | } |
| 533 | 539 | ||
| 534 | /** | 540 | /** |
| @@ -537,8 +543,8 @@ static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask) | |||
| 537 | * Note: Original code is ata_bus_softreset(). | 543 | * Note: Original code is ata_bus_softreset(). |
| 538 | */ | 544 | */ |
| 539 | 545 | ||
| 540 | static unsigned int scc_bus_softreset (struct ata_port *ap, | 546 | static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, |
| 541 | unsigned int devmask) | 547 | unsigned long deadline) |
| 542 | { | 548 | { |
| 543 | struct ata_ioports *ioaddr = &ap->ioaddr; | 549 | struct ata_ioports *ioaddr = &ap->ioaddr; |
| 544 | 550 | ||
| @@ -570,7 +576,7 @@ static unsigned int scc_bus_softreset (struct ata_port *ap, | |||
| 570 | if (scc_check_status(ap) == 0xFF) | 576 | if (scc_check_status(ap) == 0xFF) |
| 571 | return 0; | 577 | return 0; |
| 572 | 578 | ||
| 573 | scc_bus_post_reset(ap, devmask); | 579 | scc_bus_post_reset(ap, devmask, deadline); |
| 574 | 580 | ||
| 575 | return 0; | 581 | return 0; |
| 576 | } | 582 | } |
| @@ -579,11 +585,13 @@ static unsigned int scc_bus_softreset (struct ata_port *ap, | |||
| 579 | * scc_std_softreset - reset host port via ATA SRST | 585 | * scc_std_softreset - reset host port via ATA SRST |
| 580 | * @ap: port to reset | 586 | * @ap: port to reset |
| 581 | * @classes: resulting classes of attached devices | 587 | * @classes: resulting classes of attached devices |
| 588 | * @deadline: deadline jiffies for the operation | ||
| 582 | * | 589 | * |
| 583 | * Note: Original code is ata_std_softreset(). | 590 | * Note: Original code is ata_std_softreset(). |
| 584 | */ | 591 | */ |
| 585 | 592 | ||
| 586 | static int scc_std_softreset (struct ata_port *ap, unsigned int *classes) | 593 | static int scc_std_softreset (struct ata_port *ap, unsigned int *classes, |
| 594 | unsigned long deadline) | ||
| 587 | { | 595 | { |
| 588 | unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; | 596 | unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; |
| 589 | unsigned int devmask = 0, err_mask; | 597 | unsigned int devmask = 0, err_mask; |
| @@ -607,7 +615,7 @@ static int scc_std_softreset (struct ata_port *ap, unsigned int *classes) | |||
| 607 | 615 | ||
| 608 | /* issue bus reset */ | 616 | /* issue bus reset */ |
| 609 | DPRINTK("about to softreset, devmask=%x\n", devmask); | 617 | DPRINTK("about to softreset, devmask=%x\n", devmask); |
| 610 | err_mask = scc_bus_softreset(ap, devmask); | 618 | err_mask = scc_bus_softreset(ap, devmask, deadline); |
| 611 | if (err_mask) { | 619 | if (err_mask) { |
| 612 | ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n", | 620 | ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n", |
| 613 | err_mask); | 621 | err_mask); |
| @@ -676,10 +684,11 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc) | |||
| 676 | 684 | ||
| 677 | if (reg & INTSTS_BMSINT) { | 685 | if (reg & INTSTS_BMSINT) { |
| 678 | unsigned int classes; | 686 | unsigned int classes; |
| 687 | unsigned long deadline = jiffies + ATA_TMOUT_BOOT; | ||
| 679 | printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME); | 688 | printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME); |
| 680 | out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT); | 689 | out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT); |
| 681 | /* TBD: SW reset */ | 690 | /* TBD: SW reset */ |
| 682 | scc_std_softreset(ap, &classes); | 691 | scc_std_softreset(ap, &classes, deadline); |
| 683 | continue; | 692 | continue; |
| 684 | } | 693 | } |
| 685 | 694 | ||
| @@ -862,9 +871,10 @@ static void scc_bmdma_freeze (struct ata_port *ap) | |||
| 862 | /** | 871 | /** |
| 863 | * scc_pata_prereset - prepare for reset | 872 | * scc_pata_prereset - prepare for reset |
| 864 | * @ap: ATA port to be reset | 873 | * @ap: ATA port to be reset |
| 874 | * @deadline: deadline jiffies for the operation | ||
| 865 | */ | 875 | */ |
| 866 | 876 | ||
| 867 | static int scc_pata_prereset (struct ata_port *ap, unsigned long deadline) | 877 | static int scc_pata_prereset(struct ata_port *ap, unsigned long deadline) |
| 868 | { | 878 | { |
| 869 | ap->cbl = ATA_CBL_PATA80; | 879 | ap->cbl = ATA_CBL_PATA80; |
| 870 | return ata_std_prereset(ap, deadline); | 880 | return ata_std_prereset(ap, deadline); |
