diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/sata_nv.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 19817b376161..aea005d5663c 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -512,14 +512,38 @@ static void nv_adma_register_mode(struct ata_port *ap) | |||
512 | { | 512 | { |
513 | struct nv_adma_port_priv *pp = ap->private_data; | 513 | struct nv_adma_port_priv *pp = ap->private_data; |
514 | void __iomem *mmio = pp->ctl_block; | 514 | void __iomem *mmio = pp->ctl_block; |
515 | u16 tmp; | 515 | u16 tmp, status; |
516 | int count = 0; | ||
516 | 517 | ||
517 | if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) | 518 | if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) |
518 | return; | 519 | return; |
519 | 520 | ||
521 | status = readw(mmio + NV_ADMA_STAT); | ||
522 | while(!(status & NV_ADMA_STAT_IDLE) && count < 20) { | ||
523 | ndelay(50); | ||
524 | status = readw(mmio + NV_ADMA_STAT); | ||
525 | count++; | ||
526 | } | ||
527 | if(count == 20) | ||
528 | ata_port_printk(ap, KERN_WARNING, | ||
529 | "timeout waiting for ADMA IDLE, stat=0x%hx\n", | ||
530 | status); | ||
531 | |||
520 | tmp = readw(mmio + NV_ADMA_CTL); | 532 | tmp = readw(mmio + NV_ADMA_CTL); |
521 | writew(tmp & ~NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL); | 533 | writew(tmp & ~NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL); |
522 | 534 | ||
535 | count = 0; | ||
536 | status = readw(mmio + NV_ADMA_STAT); | ||
537 | while(!(status & NV_ADMA_STAT_LEGACY) && count < 20) { | ||
538 | ndelay(50); | ||
539 | status = readw(mmio + NV_ADMA_STAT); | ||
540 | count++; | ||
541 | } | ||
542 | if(count == 20) | ||
543 | ata_port_printk(ap, KERN_WARNING, | ||
544 | "timeout waiting for ADMA LEGACY, stat=0x%hx\n", | ||
545 | status); | ||
546 | |||
523 | pp->flags |= NV_ADMA_PORT_REGISTER_MODE; | 547 | pp->flags |= NV_ADMA_PORT_REGISTER_MODE; |
524 | } | 548 | } |
525 | 549 | ||
@@ -527,7 +551,8 @@ static void nv_adma_mode(struct ata_port *ap) | |||
527 | { | 551 | { |
528 | struct nv_adma_port_priv *pp = ap->private_data; | 552 | struct nv_adma_port_priv *pp = ap->private_data; |
529 | void __iomem *mmio = pp->ctl_block; | 553 | void __iomem *mmio = pp->ctl_block; |
530 | u16 tmp; | 554 | u16 tmp, status; |
555 | int count = 0; | ||
531 | 556 | ||
532 | if (!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) | 557 | if (!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) |
533 | return; | 558 | return; |
@@ -537,6 +562,18 @@ static void nv_adma_mode(struct ata_port *ap) | |||
537 | tmp = readw(mmio + NV_ADMA_CTL); | 562 | tmp = readw(mmio + NV_ADMA_CTL); |
538 | writew(tmp | NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL); | 563 | writew(tmp | NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL); |
539 | 564 | ||
565 | status = readw(mmio + NV_ADMA_STAT); | ||
566 | while(((status & NV_ADMA_STAT_LEGACY) || | ||
567 | !(status & NV_ADMA_STAT_IDLE)) && count < 20) { | ||
568 | ndelay(50); | ||
569 | status = readw(mmio + NV_ADMA_STAT); | ||
570 | count++; | ||
571 | } | ||
572 | if(count == 20) | ||
573 | ata_port_printk(ap, KERN_WARNING, | ||
574 | "timeout waiting for ADMA LEGACY clear and IDLE, stat=0x%hx\n", | ||
575 | status); | ||
576 | |||
540 | pp->flags &= ~NV_ADMA_PORT_REGISTER_MODE; | 577 | pp->flags &= ~NV_ADMA_PORT_REGISTER_MODE; |
541 | } | 578 | } |
542 | 579 | ||