* [PATCH] ahci: fix CAP.NP and PI handling
@ 2008-02-06 6:13 Tejun Heo
2008-02-06 12:03 ` Jeff Garzik
0 siblings, 1 reply; 2+ messages in thread
From: Tejun Heo @ 2008-02-06 6:13 UTC (permalink / raw)
To: Jeff Garzik, IDE/ATA development list; +Cc: Jan Beulich
AHCI uses CAP.NP to indicate the number of ports and PI to tell which
ports are enabled. The only requirement is that the number of ports
indicated by CAP.NP should equal or be higher than the number of
enabled ports in PI.
CAP.NP and PI carry duplicate information and there have been some
interesting cases. Some early AHCI controllers didn't set PI at all
and just implement from port 0 to CAP.NP. An ICH8 board which wired
four out of six available ports had 3 (4 ports) for CAP.NP and 0x33
for PI. While ESB2 has less bits set in PI than the value in CAP.NP.
Till now, ahci driver assumed that PI is invalid if it doesn't match
CAP.NP exactly. This violates AHCI standard and the driver ends up
accessing unmimplemented ports on ESB2.
This patch updates CAP.NP and PI handling such that PI can have less
number of bits set than indicated in CAP.NP and the highest port is
determined as the maximum port of what CAP.NP and PI indicate.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: Jan Beulich <jbeulich@novell.com>
---
drivers/ata/ahci.c | 35 +++++++++++++++++++----------------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 27c8d56..29e71bd 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,
/* cross check port_map and cap.n_ports */
if (port_map) {
- u32 tmp_port_map = port_map;
- int n_ports = ahci_nr_ports(cap);
+ int map_ports = 0;
- for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) {
- if (tmp_port_map & (1 << i)) {
- n_ports--;
- tmp_port_map &= ~(1 << i);
- }
- }
+ for (i = 0; i < AHCI_MAX_PORTS; i++)
+ if (port_map & (1 << i))
+ map_ports++;
- /* If n_ports and port_map are inconsistent, whine and
- * clear port_map and let it be generated from n_ports.
+ /* If PI has more ports than n_ports, whine, clear
+ * port_map and let it be generated from n_ports.
*/
- if (n_ports || tmp_port_map) {
+ if (map_ports > ahci_nr_ports(cap)) {
dev_printk(KERN_WARNING, &pdev->dev,
- "nr_ports (%u) and implemented port map "
- "(0x%x) don't match, using nr_ports\n",
- ahci_nr_ports(cap), port_map);
+ "implemented port map (0x%x) contains more "
+ "ports than nr_ports (%u), using nr_ports\n",
+ port_map, ahci_nr_ports(cap));
port_map = 0;
}
}
@@ -2201,7 +2197,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
struct device *dev = &pdev->dev;
struct ahci_host_priv *hpriv;
struct ata_host *host;
- int i, rc;
+ int n_ports, i, rc;
VPRINTK("ENTER\n");
@@ -2255,7 +2251,14 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (hpriv->cap & HOST_CAP_PMP)
pi.flags |= ATA_FLAG_PMP;
- host = ata_host_alloc_pinfo(&pdev->dev, ppi, fls(hpriv->port_map));
+ /* CAP.NP sometimes indicate the index of the last enabled
+ * port, at other times, that of the last possible port, so
+ * determining the maximum port number requires looking at
+ * both CAP.NP and port_map.
+ */
+ n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
+
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
if (!host)
return -ENOMEM;
host->iomap = pcim_iomap_table(pdev);
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] ahci: fix CAP.NP and PI handling
2008-02-06 6:13 [PATCH] ahci: fix CAP.NP and PI handling Tejun Heo
@ 2008-02-06 12:03 ` Jeff Garzik
0 siblings, 0 replies; 2+ messages in thread
From: Jeff Garzik @ 2008-02-06 12:03 UTC (permalink / raw)
To: Tejun Heo; +Cc: IDE/ATA development list, Jan Beulich
Tejun Heo wrote:
> AHCI uses CAP.NP to indicate the number of ports and PI to tell which
> ports are enabled. The only requirement is that the number of ports
> indicated by CAP.NP should equal or be higher than the number of
> enabled ports in PI.
>
> CAP.NP and PI carry duplicate information and there have been some
> interesting cases. Some early AHCI controllers didn't set PI at all
> and just implement from port 0 to CAP.NP. An ICH8 board which wired
> four out of six available ports had 3 (4 ports) for CAP.NP and 0x33
> for PI. While ESB2 has less bits set in PI than the value in CAP.NP.
>
> Till now, ahci driver assumed that PI is invalid if it doesn't match
> CAP.NP exactly. This violates AHCI standard and the driver ends up
> accessing unmimplemented ports on ESB2.
>
> This patch updates CAP.NP and PI handling such that PI can have less
> number of bits set than indicated in CAP.NP and the highest port is
> determined as the maximum port of what CAP.NP and PI indicate.
>
> Signed-off-by: Tejun Heo <htejun@gmail.com>
> Cc: Jan Beulich <jbeulich@novell.com>
applied
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-02-06 12:03 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-06 6:13 [PATCH] ahci: fix CAP.NP and PI handling Tejun Heo
2008-02-06 12:03 ` Jeff Garzik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).