aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_scc.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-04-07 09:47:19 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-17 15:44:22 -0400
commit705e76beb90b97421e1f61e857c4246799781bb5 (patch)
treee571ad9229d469cd73d1388c76823922400823d5 /drivers/ata/pata_scc.c
parent203c75b8245c5386044721d9c5eda5c6b71b3d14 (diff)
libata: restructure SFF post-reset readiness waits
Previously, post-softreset readiness is waited as follows. 1. ata_sff_wait_after_reset() waits for 150ms and then for ATA_TMOUT_FF_WAIT if status is 0xff and other conditions meet. 2. ata_bus_softreset() finishes with -ENODEV if status is still 0xff. If not, continue to #3. 3. ata_bus_post_reset() waits readiness of dev0 and/or dev1 depending on devmask using ata_sff_wait_ready(). And for post-hardreset readiness, 1. ata_sff_wait_after_reset() waits for 150ms and then for ATA_TMOUT_FF_WAIT if status is 0xff and other conditions meet. 2. sata_sff_hardreset waits for device readiness using ata_sff_wait_ready(). This patch merges and unifies post-reset readiness waits into ata_sff_wait_ready() and ata_sff_wait_after_reset(). ATA_TMOUT_FF_WAIT handling is merged into ata_sff_wait_ready(). If TF status is 0xff, link status is unknown and the port is SATA, it will continue polling till ATA_TMOUT_FF_WAIT. ata_sff_wait_after_reset() is updated to perform the following steps. 1. waits for 150ms. 2. waits for dev0 readiness using ata_sff_wait_ready(). Note that this is done regardless of devmask, as ata_sff_wait_ready() handles 0xff status correctly, this preserves the original behavior except that it may wait longer after softreset if link is online but status is 0xff. This behavior change is very unlikely to cause any actual difference and is intended. It brings softreset behavior to that of hardreset. 3. waits for dev1 readiness just the same way ata_bus_post_reset() did. Now both soft and hard resets call ata_sff_wait_after_reset() after reset to wait for readiness after resets. As ata_sff_wait_after_reset() contains calls to ->sff_dev_select(), explicit call near the end of sata_sff_hardreset() is removed. This change makes reset implementation simpler and more consistent. While at it, make the magical 150ms wait post-reset wait duration a constant and ata_sff_wait_ready() and ata_sff_wait_after_reset() take @link instead of @ap. This is to make them consistent with other reset helpers and ease core changes. pata_scc is updated accordingly. Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/ata/pata_scc.c')
-rw-r--r--drivers/ata/pata_scc.c91
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
505static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask, 505int 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}