aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-11-09 01:08:40 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-01 22:44:53 -0500
commit648a88be4a016d2637ace3ae74b85a0512255ee8 (patch)
treefb4143ad12f506aa82d3c6e39cec790414d902f1 /drivers
parent0df0d0a0ea9ffcee4e56f96cd9d9e32b0644eb21 (diff)
[PATCH] ahci: honor PORTS_IMPL on ICH8s
Some ICH8s use non-linear port mapping. ahci driver didn't use to honor PORTS_IMPL and this made ports after hole nonfunctional. This patch makes ahci mark those ports as dummy and properly initialize all the implemented ports after the dummies. As it's unknown whether other AHCIs implement PORTS_IMPL register properly, new board id board_ahci_pi is added and selectively applied to ICH8s. All other AHCIs continue to use linear mapping regardless of PORTS_IMPL value. Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Robin H. Johnson <robbat2@gentoo.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/ahci.c95
1 files changed, 67 insertions, 28 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index f2277be70c0..af3565d1fef 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -53,6 +53,7 @@
53 53
54enum { 54enum {
55 AHCI_PCI_BAR = 5, 55 AHCI_PCI_BAR = 5,
56 AHCI_MAX_PORTS = 32,
56 AHCI_MAX_SG = 168, /* hardware max is 64K */ 57 AHCI_MAX_SG = 168, /* hardware max is 64K */
57 AHCI_DMA_BOUNDARY = 0xffffffff, 58 AHCI_DMA_BOUNDARY = 0xffffffff,
58 AHCI_USE_CLUSTERING = 0, 59 AHCI_USE_CLUSTERING = 0,
@@ -77,8 +78,9 @@ enum {
77 RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */ 78 RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */
78 79
79 board_ahci = 0, 80 board_ahci = 0,
80 board_ahci_vt8251 = 1, 81 board_ahci_pi = 1,
81 board_ahci_ign_iferr = 2, 82 board_ahci_vt8251 = 2,
83 board_ahci_ign_iferr = 3,
82 84
83 /* global controller registers */ 85 /* global controller registers */
84 HOST_CAP = 0x00, /* host capabilities */ 86 HOST_CAP = 0x00, /* host capabilities */
@@ -169,6 +171,7 @@ enum {
169 /* ap->flags bits */ 171 /* ap->flags bits */
170 AHCI_FLAG_NO_NCQ = (1 << 24), 172 AHCI_FLAG_NO_NCQ = (1 << 24),
171 AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */ 173 AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */
174 AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */
172}; 175};
173 176
174struct ahci_cmd_hdr { 177struct ahci_cmd_hdr {
@@ -317,6 +320,16 @@ static const struct ata_port_info ahci_port_info[] = {
317 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 320 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
318 .port_ops = &ahci_ops, 321 .port_ops = &ahci_ops,
319 }, 322 },
323 /* board_ahci_pi */
324 {
325 .sht = &ahci_sht,
326 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
327 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
328 ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI,
329 .pio_mask = 0x1f, /* pio0-4 */
330 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
331 .port_ops = &ahci_ops,
332 },
320 /* board_ahci_vt8251 */ 333 /* board_ahci_vt8251 */
321 { 334 {
322 .sht = &ahci_sht, 335 .sht = &ahci_sht,
@@ -353,22 +366,22 @@ static const struct pci_device_id ahci_pci_tbl[] = {
353 { PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */ 366 { PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */
354 { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */ 367 { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
355 { PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */ 368 { PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */
356 { PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */ 369 { PCI_VDEVICE(INTEL, 0x2821), board_ahci_pi }, /* ICH8 */
357 { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* ICH8 */ 370 { PCI_VDEVICE(INTEL, 0x2822), board_ahci_pi }, /* ICH8 */
358 { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */ 371 { PCI_VDEVICE(INTEL, 0x2824), board_ahci_pi }, /* ICH8 */
359 { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */ 372 { PCI_VDEVICE(INTEL, 0x2829), board_ahci_pi }, /* ICH8M */
360 { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */ 373 { PCI_VDEVICE(INTEL, 0x282a), board_ahci_pi }, /* ICH8M */
361 { PCI_VDEVICE(INTEL, 0x2922), board_ahci }, /* ICH9 */ 374 { PCI_VDEVICE(INTEL, 0x2922), board_ahci_pi }, /* ICH9 */
362 { PCI_VDEVICE(INTEL, 0x2923), board_ahci }, /* ICH9 */ 375 { PCI_VDEVICE(INTEL, 0x2923), board_ahci_pi }, /* ICH9 */
363 { PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */ 376 { PCI_VDEVICE(INTEL, 0x2924), board_ahci_pi }, /* ICH9 */
364 { PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */ 377 { PCI_VDEVICE(INTEL, 0x2925), board_ahci_pi }, /* ICH9 */
365 { PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */ 378 { PCI_VDEVICE(INTEL, 0x2927), board_ahci_pi }, /* ICH9 */
366 { PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */ 379 { PCI_VDEVICE(INTEL, 0x2929), board_ahci_pi }, /* ICH9M */
367 { PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */ 380 { PCI_VDEVICE(INTEL, 0x292a), board_ahci_pi }, /* ICH9M */
368 { PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */ 381 { PCI_VDEVICE(INTEL, 0x292b), board_ahci_pi }, /* ICH9M */
369 { PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */ 382 { PCI_VDEVICE(INTEL, 0x292f), board_ahci_pi }, /* ICH9M */
370 { PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */ 383 { PCI_VDEVICE(INTEL, 0x294d), board_ahci_pi }, /* ICH9 */
371 { PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */ 384 { PCI_VDEVICE(INTEL, 0x294e), board_ahci_pi }, /* ICH9M */
372 385
373 /* JMicron */ 386 /* JMicron */
374 { PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */ 387 { PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */
@@ -691,7 +704,8 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
691} 704}
692 705
693static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev, 706static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
694 int n_ports, u32 cap) 707 int n_ports, unsigned int port_flags,
708 struct ahci_host_priv *hpriv)
695{ 709{
696 int i, rc; 710 int i, rc;
697 u32 tmp; 711 u32 tmp;
@@ -700,13 +714,12 @@ static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
700 void __iomem *port_mmio = ahci_port_base(mmio, i); 714 void __iomem *port_mmio = ahci_port_base(mmio, i);
701 const char *emsg = NULL; 715 const char *emsg = NULL;
702 716
703#if 0 /* BIOSen initialize this incorrectly */ 717 if ((port_flags & AHCI_FLAG_HONOR_PI) &&
704 if (!(hpriv->port_map & (1 << i))) 718 !(hpriv->port_map & (1 << i)))
705 continue; 719 continue;
706#endif
707 720
708 /* make sure port is not active */ 721 /* make sure port is not active */
709 rc = ahci_deinit_port(port_mmio, cap, &emsg); 722 rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
710 if (rc) 723 if (rc)
711 dev_printk(KERN_WARNING, &pdev->dev, 724 dev_printk(KERN_WARNING, &pdev->dev,
712 "%s (%d)\n", emsg, rc); 725 "%s (%d)\n", emsg, rc);
@@ -1363,7 +1376,8 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
1363 if (rc) 1376 if (rc)
1364 return rc; 1377 return rc;
1365 1378
1366 ahci_init_controller(mmio, pdev, host->n_ports, hpriv->cap); 1379 ahci_init_controller(mmio, pdev, host->n_ports,
1380 host->ports[0]->flags, hpriv);
1367 } 1381 }
1368 1382
1369 ata_host_resume(host); 1383 ata_host_resume(host);
@@ -1475,7 +1489,7 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
1475 struct ahci_host_priv *hpriv = probe_ent->private_data; 1489 struct ahci_host_priv *hpriv = probe_ent->private_data;
1476 struct pci_dev *pdev = to_pci_dev(probe_ent->dev); 1490 struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
1477 void __iomem *mmio = probe_ent->mmio_base; 1491 void __iomem *mmio = probe_ent->mmio_base;
1478 unsigned int i, using_dac; 1492 unsigned int i, cap_n_ports, using_dac;
1479 int rc; 1493 int rc;
1480 1494
1481 rc = ahci_reset_controller(mmio, pdev); 1495 rc = ahci_reset_controller(mmio, pdev);
@@ -1484,10 +1498,34 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
1484 1498
1485 hpriv->cap = readl(mmio + HOST_CAP); 1499 hpriv->cap = readl(mmio + HOST_CAP);
1486 hpriv->port_map = readl(mmio + HOST_PORTS_IMPL); 1500 hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
1487 probe_ent->n_ports = ahci_nr_ports(hpriv->cap); 1501 cap_n_ports = ahci_nr_ports(hpriv->cap);
1488 1502
1489 VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n", 1503 VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n",
1490 hpriv->cap, hpriv->port_map, probe_ent->n_ports); 1504 hpriv->cap, hpriv->port_map, cap_n_ports);
1505
1506 if (probe_ent->port_flags & AHCI_FLAG_HONOR_PI) {
1507 unsigned int n_ports = cap_n_ports;
1508 u32 port_map = hpriv->port_map;
1509 int max_port = 0;
1510
1511 for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) {
1512 if (port_map & (1 << i)) {
1513 n_ports--;
1514 port_map &= ~(1 << i);
1515 max_port = i;
1516 } else
1517 probe_ent->dummy_port_mask |= 1 << i;
1518 }
1519
1520 if (n_ports || port_map)
1521 dev_printk(KERN_WARNING, &pdev->dev,
1522 "nr_ports (%u) and implemented port map "
1523 "(0x%x) don't match\n",
1524 cap_n_ports, hpriv->port_map);
1525
1526 probe_ent->n_ports = max_port + 1;
1527 } else
1528 probe_ent->n_ports = cap_n_ports;
1491 1529
1492 using_dac = hpriv->cap & HOST_CAP_64; 1530 using_dac = hpriv->cap & HOST_CAP_64;
1493 if (using_dac && 1531 if (using_dac &&
@@ -1519,7 +1557,8 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
1519 for (i = 0; i < probe_ent->n_ports; i++) 1557 for (i = 0; i < probe_ent->n_ports; i++)
1520 ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i); 1558 ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i);
1521 1559
1522 ahci_init_controller(mmio, pdev, probe_ent->n_ports, hpriv->cap); 1560 ahci_init_controller(mmio, pdev, probe_ent->n_ports,
1561 probe_ent->port_flags, hpriv);
1523 1562
1524 pci_set_master(pdev); 1563 pci_set_master(pdev);
1525 1564