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.c31
1 files changed, 6 insertions, 25 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 0e7fb9bf2cd1..1b8429cb3c96 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -516,24 +516,6 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts)
516 pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); 516 pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16);
517} 517}
518 518
519static int ahci_poll_register(void __iomem *reg, u32 mask, u32 val,
520 unsigned long interval_msec,
521 unsigned long timeout_msec)
522{
523 unsigned long timeout;
524 u32 tmp;
525
526 timeout = jiffies + (timeout_msec * HZ) / 1000;
527 do {
528 tmp = readl(reg);
529 if ((tmp & mask) == val)
530 return 0;
531 msleep(interval_msec);
532 } while (time_before(jiffies, timeout));
533
534 return -1;
535}
536
537static int ahci_softreset(struct ata_port *ap, unsigned int *class) 519static int ahci_softreset(struct ata_port *ap, unsigned int *class)
538{ 520{
539 struct ahci_host_priv *hpriv = ap->host_set->private_data; 521 struct ahci_host_priv *hpriv = ap->host_set->private_data;
@@ -543,6 +525,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
543 const u32 cmd_fis_len = 5; /* five dwords */ 525 const u32 cmd_fis_len = 5; /* five dwords */
544 const char *reason = NULL; 526 const char *reason = NULL;
545 struct ata_taskfile tf; 527 struct ata_taskfile tf;
528 u32 tmp;
546 u8 *fis; 529 u8 *fis;
547 int rc; 530 int rc;
548 531
@@ -564,8 +547,6 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
564 /* check BUSY/DRQ, perform Command List Override if necessary */ 547 /* check BUSY/DRQ, perform Command List Override if necessary */
565 ahci_tf_read(ap, &tf); 548 ahci_tf_read(ap, &tf);
566 if (tf.command & (ATA_BUSY | ATA_DRQ)) { 549 if (tf.command & (ATA_BUSY | ATA_DRQ)) {
567 u32 tmp;
568
569 if (!(hpriv->cap & HOST_CAP_CLO)) { 550 if (!(hpriv->cap & HOST_CAP_CLO)) {
570 rc = -EIO; 551 rc = -EIO;
571 reason = "port busy but no CLO"; 552 reason = "port busy but no CLO";
@@ -575,10 +556,10 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
575 tmp = readl(port_mmio + PORT_CMD); 556 tmp = readl(port_mmio + PORT_CMD);
576 tmp |= PORT_CMD_CLO; 557 tmp |= PORT_CMD_CLO;
577 writel(tmp, port_mmio + PORT_CMD); 558 writel(tmp, port_mmio + PORT_CMD);
578 readl(port_mmio + PORT_CMD); /* flush */
579 559
580 if (ahci_poll_register(port_mmio + PORT_CMD, PORT_CMD_CLO, 0x0, 560 tmp = ata_wait_register(port_mmio + PORT_CMD,
581 1, 500)) { 561 PORT_CMD_CLO, PORT_CMD_CLO, 1, 500);
562 if (tmp & PORT_CMD_CLO) {
582 rc = -EIO; 563 rc = -EIO;
583 reason = "CLO failed"; 564 reason = "CLO failed";
584 goto fail_restart; 565 goto fail_restart;
@@ -599,9 +580,9 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
599 fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ 580 fis[1] &= ~(1 << 7); /* turn off Command FIS bit */
600 581
601 writel(1, port_mmio + PORT_CMD_ISSUE); 582 writel(1, port_mmio + PORT_CMD_ISSUE);
602 readl(port_mmio + PORT_CMD_ISSUE); /* flush */
603 583
604 if (ahci_poll_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x0, 1, 500)) { 584 tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1, 500);
585 if (tmp & 0x1) {
605 rc = -EIO; 586 rc = -EIO;
606 reason = "1st FIS failed"; 587 reason = "1st FIS failed";
607 goto fail; 588 goto fail;