diff options
| -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 19817b37616..aea005d5663 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 | ||
