aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/ahci.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 27c8d56111c2..29e71bddd6ff 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -679,24 +679,20 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
679 679
680 /* cross check port_map and cap.n_ports */ 680 /* cross check port_map and cap.n_ports */
681 if (port_map) { 681 if (port_map) {
682 u32 tmp_port_map = port_map; 682 int map_ports = 0;
683 int n_ports = ahci_nr_ports(cap);
684 683
685 for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) { 684 for (i = 0; i < AHCI_MAX_PORTS; i++)
686 if (tmp_port_map & (1 << i)) { 685 if (port_map & (1 << i))
687 n_ports--; 686 map_ports++;
688 tmp_port_map &= ~(1 << i);
689 }
690 }
691 687
692 /* If n_ports and port_map are inconsistent, whine and 688 /* If PI has more ports than n_ports, whine, clear
693 * clear port_map and let it be generated from n_ports. 689 * port_map and let it be generated from n_ports.
694 */ 690 */
695 if (n_ports || tmp_port_map) { 691 if (map_ports > ahci_nr_ports(cap)) {
696 dev_printk(KERN_WARNING, &pdev->dev, 692 dev_printk(KERN_WARNING, &pdev->dev,
697 "nr_ports (%u) and implemented port map " 693 "implemented port map (0x%x) contains more "
698 "(0x%x) don't match, using nr_ports\n", 694 "ports than nr_ports (%u), using nr_ports\n",
699 ahci_nr_ports(cap), port_map); 695 port_map, ahci_nr_ports(cap));
700 port_map = 0; 696 port_map = 0;
701 } 697 }
702 } 698 }
@@ -2201,7 +2197,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2201 struct device *dev = &pdev->dev; 2197 struct device *dev = &pdev->dev;
2202 struct ahci_host_priv *hpriv; 2198 struct ahci_host_priv *hpriv;
2203 struct ata_host *host; 2199 struct ata_host *host;
2204 int i, rc; 2200 int n_ports, i, rc;
2205 2201
2206 VPRINTK("ENTER\n"); 2202 VPRINTK("ENTER\n");
2207 2203
@@ -2255,7 +2251,14 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2255 if (hpriv->cap & HOST_CAP_PMP) 2251 if (hpriv->cap & HOST_CAP_PMP)
2256 pi.flags |= ATA_FLAG_PMP; 2252 pi.flags |= ATA_FLAG_PMP;
2257 2253
2258 host = ata_host_alloc_pinfo(&pdev->dev, ppi, fls(hpriv->port_map)); 2254 /* CAP.NP sometimes indicate the index of the last enabled
2255 * port, at other times, that of the last possible port, so
2256 * determining the maximum port number requires looking at
2257 * both CAP.NP and port_map.
2258 */
2259 n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
2260
2261 host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
2259 if (!host) 2262 if (!host)
2260 return -ENOMEM; 2263 return -ENOMEM;
2261 host->iomap = pcim_iomap_table(pdev); 2264 host->iomap = pcim_iomap_table(pdev);