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.c82
1 files changed, 55 insertions, 27 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 19bd346951dd..30676b0eb366 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -446,10 +446,61 @@ 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 void ahci_phy_reset(struct ata_port *ap) 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
486static unsigned int ahci_dev_classify(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;
452 struct ata_taskfile tf; 489 struct ata_taskfile tf;
490 u32 tmp;
491
492 tmp = readl(port_mmio + PORT_SIG);
493 tf.lbah = (tmp >> 24) & 0xff;
494 tf.lbam = (tmp >> 16) & 0xff;
495 tf.lbal = (tmp >> 8) & 0xff;
496 tf.nsect = (tmp) & 0xff;
497
498 return ata_dev_classify(&tf);
499}
500
501static void ahci_phy_reset(struct ata_port *ap)
502{
503 void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
453 struct ata_device *dev = &ap->device[0]; 504 struct ata_device *dev = &ap->device[0];
454 u32 new_tmp, tmp; 505 u32 new_tmp, tmp;
455 506
@@ -458,13 +509,7 @@ static void ahci_phy_reset(struct ata_port *ap)
458 if (ap->flags & ATA_FLAG_PORT_DISABLED) 509 if (ap->flags & ATA_FLAG_PORT_DISABLED)
459 return; 510 return;
460 511
461 tmp = readl(port_mmio + PORT_SIG); 512 dev->class = ahci_dev_classify(ap);
462 tf.lbah = (tmp >> 24) & 0xff;
463 tf.lbam = (tmp >> 16) & 0xff;
464 tf.lbal = (tmp >> 8) & 0xff;
465 tf.nsect = (tmp) & 0xff;
466
467 dev->class = ata_dev_classify(&tf);
468 if (!ata_dev_present(dev)) { 513 if (!ata_dev_present(dev)) {
469 ata_port_disable(ap); 514 ata_port_disable(ap);
470 return; 515 return;
@@ -572,7 +617,6 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
572 void __iomem *mmio = ap->host_set->mmio_base; 617 void __iomem *mmio = ap->host_set->mmio_base;
573 void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); 618 void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
574 u32 tmp; 619 u32 tmp;
575 int work;
576 620
577 if ((ap->device[0].class != ATA_DEV_ATAPI) || 621 if ((ap->device[0].class != ATA_DEV_ATAPI) ||
578 ((irq_stat & PORT_IRQ_TF_ERR) == 0)) 622 ((irq_stat & PORT_IRQ_TF_ERR) == 0))
@@ -588,20 +632,7 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
588 readl(port_mmio + PORT_SCR_ERR)); 632 readl(port_mmio + PORT_SCR_ERR));
589 633
590 /* stop DMA */ 634 /* stop DMA */
591 tmp = readl(port_mmio + PORT_CMD); 635 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 636
606 /* clear SATA phy error, if any */ 637 /* clear SATA phy error, if any */
607 tmp = readl(port_mmio + PORT_SCR_ERR); 638 tmp = readl(port_mmio + PORT_SCR_ERR);
@@ -620,10 +651,7 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
620 } 651 }
621 652
622 /* re-start DMA */ 653 /* re-start DMA */
623 tmp = readl(port_mmio + PORT_CMD); 654 ahci_start_engine(ap);
624 tmp |= PORT_CMD_START;
625 writel(tmp, port_mmio + PORT_CMD);
626 readl(port_mmio + PORT_CMD); /* flush */
627} 655}
628 656
629static void ahci_eng_timeout(struct ata_port *ap) 657static void ahci_eng_timeout(struct ata_port *ap)