diff options
-rw-r--r-- | drivers/ata/libata-core.c | 18 | ||||
-rw-r--r-- | drivers/ata/libata-sff.c | 2 | ||||
-rw-r--r-- | include/linux/libata.h | 8 |
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, ap->host = host; ap->dev = ent->dev; ap->port_no = port_no; - ap->pio_mask = ent->pio_mask; - ap->mwdma_mask = ent->mwdma_mask; - ap->udma_mask = ent->udma_mask; - ap->flags |= ent->port_flags; - ap->ops = ent->port_ops; + if (port_no == 1 && ent->pinfo2) { + ap->pio_mask = ent->pinfo2->pio_mask; + ap->mwdma_mask = ent->pinfo2->mwdma_mask; + ap->udma_mask = ent->pinfo2->udma_mask; + ap->flags |= ent->pinfo2->flags; + ap->ops = ent->pinfo2->port_ops; + } else { + ap->pio_mask = ent->pio_mask; + ap->mwdma_mask = ent->mwdma_mask; + ap->udma_mask = ent->udma_mask; + ap->flags |= ent->port_flags; + ap->ops = ent->port_ops; + } ap->hw_sata_spd_limit = UINT_MAX; ap->active_tag = ATA_TAG_POISON; 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 probe_ent->port[p].bmdma_addr = bmdma; } ata_std_ports(&probe_ent->port[p]); + probe_ent->pinfo2 = port[1]; p++; } @@ -907,6 +908,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, probe_ent->_host_flags |= ATA_HOST_SIMPLEX; } ata_std_ports(&probe_ent->port[1]); + probe_ent->pinfo2 = port[1]; } else probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY; 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 { unsigned long _host_flags; void __iomem *mmio_base; void *private_data; + + /* port_info for the secondary port. Together with irq2, it's + * used to implement non-uniform secondary port. Currently, + * the only user is ata_piix combined mode. This workaround + * will be removed together with ata_probe_ent when init model + * is updated. + */ + const struct ata_port_info *pinfo2; }; struct ata_host { |