aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-09-15 14:04:15 -0400
committerJeff Garzik <jeff@garzik.org>2006-09-19 00:29:20 -0400
commitfea63e38013ec628ab3f7fddc4c2148064b7910a (patch)
treea3e1cd7f50562a20584cd28ef9d71e0cd6c7c896
parenta64f97f2c351410dfb3099c2369eacf7154b5532 (diff)
[PATCH] libata: fix non-uniform ports handling
Non-uniform ports handling got broken while updating libata to handle those in the same host. Only separate irq for the non-uniform secondary port was implemented while all other fields (host flags, transfer mode...) of the secondary port simply shared those of the first. For ata_piix combined mode, which ATM is the only user of non-uniform ports, this causes the secondary port assume the wrong type. This can cause PATA port to use SATA ops, which results in bogus check on PCS and detection failure. This patch adds ata_probe_ent->pinfo2 which points to optional port_info for the secondary port. For the time being, this seems to be the simplest solution. This workaround will be removed together with ata_probe_ent itself after init model is updated to allow more flexibility. Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Cc: Nelson A. de Oliveira <naoliv@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/ata/libata-core.c18
-rw-r--r--drivers/ata/libata-sff.c2
-rw-r--r--include/linux/libata.h8
3 files changed, 23 insertions, 5 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 1c9315401f7a..bb66a12c84e5 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5269,11 +5269,19 @@ void ata_port_init(struct ata_port *ap, struct ata_host *host,
5269 ap->host = host; 5269 ap->host = host;
5270 ap->dev = ent->dev; 5270 ap->dev = ent->dev;
5271 ap->port_no = port_no; 5271 ap->port_no = port_no;
5272 ap->pio_mask = ent->pio_mask; 5272 if (port_no == 1 && ent->pinfo2) {
5273 ap->mwdma_mask = ent->mwdma_mask; 5273 ap->pio_mask = ent->pinfo2->pio_mask;
5274 ap->udma_mask = ent->udma_mask; 5274 ap->mwdma_mask = ent->pinfo2->mwdma_mask;
5275 ap->flags |= ent->port_flags; 5275 ap->udma_mask = ent->pinfo2->udma_mask;
5276 ap->ops = ent->port_ops; 5276 ap->flags |= ent->pinfo2->flags;
5277 ap->ops = ent->pinfo2->port_ops;
5278 } else {
5279 ap->pio_mask = ent->pio_mask;
5280 ap->mwdma_mask = ent->mwdma_mask;
5281 ap->udma_mask = ent->udma_mask;
5282 ap->flags |= ent->port_flags;
5283 ap->ops = ent->port_ops;
5284 }
5277 ap->hw_sata_spd_limit = UINT_MAX; 5285 ap->hw_sata_spd_limit = UINT_MAX;
5278 ap->active_tag = ATA_TAG_POISON; 5286 ap->active_tag = ATA_TAG_POISON;
5279 ap->last_ctl = 0xFF; 5287 ap->last_ctl = 0xFF;
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index d51dc41fa195..688bb55e197a 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -858,6 +858,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
858 probe_ent->port[p].bmdma_addr = bmdma; 858 probe_ent->port[p].bmdma_addr = bmdma;
859 } 859 }
860 ata_std_ports(&probe_ent->port[p]); 860 ata_std_ports(&probe_ent->port[p]);
861 probe_ent->pinfo2 = port[1];
861 p++; 862 p++;
862 } 863 }
863 864
@@ -907,6 +908,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
907 probe_ent->_host_flags |= ATA_HOST_SIMPLEX; 908 probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
908 } 909 }
909 ata_std_ports(&probe_ent->port[1]); 910 ata_std_ports(&probe_ent->port[1]);
911 probe_ent->pinfo2 = port[1];
910 } else 912 } else
911 probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY; 913 probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY;
912 914
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 8715305f611f..ff67e7524fe9 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -361,6 +361,14 @@ struct ata_probe_ent {
361 unsigned long _host_flags; 361 unsigned long _host_flags;
362 void __iomem *mmio_base; 362 void __iomem *mmio_base;
363 void *private_data; 363 void *private_data;
364
365 /* port_info for the secondary port. Together with irq2, it's
366 * used to implement non-uniform secondary port. Currently,
367 * the only user is ata_piix combined mode. This workaround
368 * will be removed together with ata_probe_ent when init model
369 * is updated.
370 */
371 const struct ata_port_info *pinfo2;
364}; 372};
365 373
366struct ata_host { 374struct ata_host {