aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-07-26 02:59:26 -0400
committerJeff Garzik <jeff@garzik.org>2006-07-29 04:01:31 -0400
commitd91542c11f3981768367815cf087ad36e792ea4a (patch)
treeceefba529bf78fa2b8f044ffadd6e2da33a59160 /drivers/scsi
parent0be0aa98985dfec42502c0d0af2a1baff9bdb19f (diff)
[PATCH] ahci: separate out ahci_reset_controller() and ahci_init_controller()
Separate out ahci_reset_controller() and ahci_init_controller() from ata_host_init(). These will be used by PM callbacks. This patch doesn't introduce any behavior change. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Zhao, Forrest <forrest.zhao@intel.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/ahci.c171
1 files changed, 94 insertions, 77 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index fb71fa7bc5de..a9e0c5f79096 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -572,6 +572,94 @@ static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg)
572 return 0; 572 return 0;
573} 573}
574 574
575static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
576{
577 u32 cap_save, tmp;
578
579 cap_save = readl(mmio + HOST_CAP);
580 cap_save &= ( (1<<28) | (1<<17) );
581 cap_save |= (1 << 27);
582
583 /* global controller reset */
584 tmp = readl(mmio + HOST_CTL);
585 if ((tmp & HOST_RESET) == 0) {
586 writel(tmp | HOST_RESET, mmio + HOST_CTL);
587 readl(mmio + HOST_CTL); /* flush */
588 }
589
590 /* reset must complete within 1 second, or
591 * the hardware should be considered fried.
592 */
593 ssleep(1);
594
595 tmp = readl(mmio + HOST_CTL);
596 if (tmp & HOST_RESET) {
597 dev_printk(KERN_ERR, &pdev->dev,
598 "controller reset failed (0x%x)\n", tmp);
599 return -EIO;
600 }
601
602 writel(HOST_AHCI_EN, mmio + HOST_CTL);
603 (void) readl(mmio + HOST_CTL); /* flush */
604 writel(cap_save, mmio + HOST_CAP);
605 writel(0xf, mmio + HOST_PORTS_IMPL);
606 (void) readl(mmio + HOST_PORTS_IMPL); /* flush */
607
608 if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
609 u16 tmp16;
610
611 /* configure PCS */
612 pci_read_config_word(pdev, 0x92, &tmp16);
613 tmp16 |= 0xf;
614 pci_write_config_word(pdev, 0x92, tmp16);
615 }
616
617 return 0;
618}
619
620static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
621 int n_ports, u32 cap)
622{
623 int i, rc;
624 u32 tmp;
625
626 for (i = 0; i < n_ports; i++) {
627 void __iomem *port_mmio = ahci_port_base(mmio, i);
628 const char *emsg = NULL;
629
630#if 0 /* BIOSen initialize this incorrectly */
631 if (!(hpriv->port_map & (1 << i)))
632 continue;
633#endif
634
635 /* make sure port is not active */
636 rc = ahci_deinit_port(port_mmio, cap, &emsg);
637 if (rc)
638 dev_printk(KERN_WARNING, &pdev->dev,
639 "%s (%d)\n", emsg, rc);
640
641 /* clear SError */
642 tmp = readl(port_mmio + PORT_SCR_ERR);
643 VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
644 writel(tmp, port_mmio + PORT_SCR_ERR);
645
646 /* clear & turn off port IRQ */
647 tmp = readl(port_mmio + PORT_IRQ_STAT);
648 VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
649 if (tmp)
650 writel(tmp, port_mmio + PORT_IRQ_STAT);
651
652 writel(1 << i, mmio + HOST_IRQ_STAT);
653 writel(0, port_mmio + PORT_IRQ_MASK);
654 }
655
656 tmp = readl(mmio + HOST_CTL);
657 VPRINTK("HOST_CTL 0x%x\n", tmp);
658 writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
659 tmp = readl(mmio + HOST_CTL);
660 VPRINTK("HOST_CTL 0x%x\n", tmp);
661}
662
575static unsigned int ahci_dev_classify(struct ata_port *ap) 663static unsigned int ahci_dev_classify(struct ata_port *ap)
576{ 664{
577 void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; 665 void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
@@ -1215,47 +1303,12 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
1215 struct ahci_host_priv *hpriv = probe_ent->private_data; 1303 struct ahci_host_priv *hpriv = probe_ent->private_data;
1216 struct pci_dev *pdev = to_pci_dev(probe_ent->dev); 1304 struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
1217 void __iomem *mmio = probe_ent->mmio_base; 1305 void __iomem *mmio = probe_ent->mmio_base;
1218 u32 tmp, cap_save;
1219 unsigned int i, using_dac; 1306 unsigned int i, using_dac;
1220 int rc; 1307 int rc;
1221 void __iomem *port_mmio;
1222
1223 cap_save = readl(mmio + HOST_CAP);
1224 cap_save &= ( (1<<28) | (1<<17) );
1225 cap_save |= (1 << 27);
1226
1227 /* global controller reset */
1228 tmp = readl(mmio + HOST_CTL);
1229 if ((tmp & HOST_RESET) == 0) {
1230 writel(tmp | HOST_RESET, mmio + HOST_CTL);
1231 readl(mmio + HOST_CTL); /* flush */
1232 }
1233
1234 /* reset must complete within 1 second, or
1235 * the hardware should be considered fried.
1236 */
1237 ssleep(1);
1238
1239 tmp = readl(mmio + HOST_CTL);
1240 if (tmp & HOST_RESET) {
1241 dev_printk(KERN_ERR, &pdev->dev,
1242 "controller reset failed (0x%x)\n", tmp);
1243 return -EIO;
1244 }
1245 1308
1246 writel(HOST_AHCI_EN, mmio + HOST_CTL); 1309 rc = ahci_reset_controller(mmio, pdev);
1247 (void) readl(mmio + HOST_CTL); /* flush */ 1310 if (rc)
1248 writel(cap_save, mmio + HOST_CAP); 1311 return rc;
1249 writel(0xf, mmio + HOST_PORTS_IMPL);
1250 (void) readl(mmio + HOST_PORTS_IMPL); /* flush */
1251
1252 if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
1253 u16 tmp16;
1254
1255 pci_read_config_word(pdev, 0x92, &tmp16);
1256 tmp16 |= 0xf;
1257 pci_write_config_word(pdev, 0x92, tmp16);
1258 }
1259 1312
1260 hpriv->cap = readl(mmio + HOST_CAP); 1313 hpriv->cap = readl(mmio + HOST_CAP);
1261 hpriv->port_map = readl(mmio + HOST_PORTS_IMPL); 1314 hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
@@ -1291,46 +1344,10 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
1291 } 1344 }
1292 } 1345 }
1293 1346
1294 for (i = 0; i < probe_ent->n_ports; i++) { 1347 for (i = 0; i < probe_ent->n_ports; i++)
1295 const char *emsg = NULL; 1348 ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i);
1296
1297#if 0 /* BIOSen initialize this incorrectly */
1298 if (!(hpriv->port_map & (1 << i)))
1299 continue;
1300#endif
1301 1349
1302 port_mmio = ahci_port_base(mmio, i); 1350 ahci_init_controller(mmio, pdev, probe_ent->n_ports, hpriv->cap);
1303 VPRINTK("mmio %p port_mmio %p\n", mmio, port_mmio);
1304
1305 ahci_setup_port(&probe_ent->port[i],
1306 (unsigned long) mmio, i);
1307
1308 /* make sure port is not active */
1309 rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
1310 if (rc)
1311 dev_printk(KERN_WARNING, &pdev->dev,
1312 "%s (%d)\n", emsg, rc);
1313
1314 /* clear SError */
1315 tmp = readl(port_mmio + PORT_SCR_ERR);
1316 VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
1317 writel(tmp, port_mmio + PORT_SCR_ERR);
1318
1319 /* clear & turn off port IRQ */
1320 tmp = readl(port_mmio + PORT_IRQ_STAT);
1321 VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
1322 if (tmp)
1323 writel(tmp, port_mmio + PORT_IRQ_STAT);
1324
1325 writel(1 << i, mmio + HOST_IRQ_STAT);
1326 writel(0, port_mmio + PORT_IRQ_MASK);
1327 }
1328
1329 tmp = readl(mmio + HOST_CTL);
1330 VPRINTK("HOST_CTL 0x%x\n", tmp);
1331 writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
1332 tmp = readl(mmio + HOST_CTL);
1333 VPRINTK("HOST_CTL 0x%x\n", tmp);
1334 1351
1335 pci_set_master(pdev); 1352 pci_set_master(pdev);
1336 1353