aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ahci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r--drivers/scsi/ahci.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 19bd346951dd..f3dfdab173f2 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -446,6 +446,43 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in,
446 writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); 446 writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
447} 447}
448 448
449static int ahci_stop_engine(struct ata_port *ap)
450{
451 void __iomem *mmio = ap->host_set->mmio_base;
452 void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
453 int work;
454 u32 tmp;
455
456 tmp = readl(port_mmio + PORT_CMD);
457 tmp &= ~PORT_CMD_START;
458 writel(tmp, port_mmio + PORT_CMD);
459
460 /* wait for engine to stop. TODO: this could be
461 * as long as 500 msec
462 */
463 work = 1000;
464 while (work-- > 0) {
465 tmp = readl(port_mmio + PORT_CMD);
466 if ((tmp & PORT_CMD_LIST_ON) == 0)
467 return 0;
468 udelay(10);
469 }
470
471 return -EIO;
472}
473
474static void ahci_start_engine(struct ata_port *ap)
475{
476 void __iomem *mmio = ap->host_set->mmio_base;
477 void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
478 u32 tmp;
479
480 tmp = readl(port_mmio + PORT_CMD);
481 tmp |= PORT_CMD_START;
482 writel(tmp, port_mmio + PORT_CMD);
483 readl(port_mmio + PORT_CMD); /* flush */
484}
485
449static void ahci_phy_reset(struct ata_port *ap) 486static void ahci_phy_reset(struct ata_port *ap)
450{ 487{
451 void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; 488 void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
@@ -572,7 +609,6 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
572 void __iomem *mmio = ap->host_set->mmio_base; 609 void __iomem *mmio = ap->host_set->mmio_base;
573 void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); 610 void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
574 u32 tmp; 611 u32 tmp;
575 int work;
576 612
577 if ((ap->device[0].class != ATA_DEV_ATAPI) || 613 if ((ap->device[0].class != ATA_DEV_ATAPI) ||
578 ((irq_stat & PORT_IRQ_TF_ERR) == 0)) 614 ((irq_stat & PORT_IRQ_TF_ERR) == 0))
@@ -588,20 +624,7 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
588 readl(port_mmio + PORT_SCR_ERR)); 624 readl(port_mmio + PORT_SCR_ERR));
589 625
590 /* stop DMA */ 626 /* stop DMA */
591 tmp = readl(port_mmio + PORT_CMD); 627 ahci_stop_engine(ap);
592 tmp &= ~PORT_CMD_START;
593 writel(tmp, port_mmio + PORT_CMD);
594
595 /* wait for engine to stop. TODO: this could be
596 * as long as 500 msec
597 */
598 work = 1000;
599 while (work-- > 0) {
600 tmp = readl(port_mmio + PORT_CMD);
601 if ((tmp & PORT_CMD_LIST_ON) == 0)
602 break;
603 udelay(10);
604 }
605 628
606 /* clear SATA phy error, if any */ 629 /* clear SATA phy error, if any */
607 tmp = readl(port_mmio + PORT_SCR_ERR); 630 tmp = readl(port_mmio + PORT_SCR_ERR);
@@ -620,10 +643,7 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
620 } 643 }
621 644
622 /* re-start DMA */ 645 /* re-start DMA */
623 tmp = readl(port_mmio + PORT_CMD); 646 ahci_start_engine(ap);
624 tmp |= PORT_CMD_START;
625 writel(tmp, port_mmio + PORT_CMD);
626 readl(port_mmio + PORT_CMD); /* flush */
627} 647}
628 648
629static void ahci_eng_timeout(struct ata_port *ap) 649static void ahci_eng_timeout(struct ata_port *ap)