[PATCH] libata: PCI IDE legacy mode fix

In PCI IDE legacy mode ap->port_no is incorrectly set to zero for
the second port.  Fix it by adding ->hard_port_no to struct ata_probe_ent
and struct ata_port (per Jeff's suggestion) and teaching ata_piix.c
to use it instead of ->port_no.
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent 825d5976
...@@ -268,7 +268,7 @@ static void piix_pata_cbl_detect(struct ata_port *ap) ...@@ -268,7 +268,7 @@ static void piix_pata_cbl_detect(struct ata_port *ap)
goto cbl40; goto cbl40;
/* check BIOS cable detect results */ /* check BIOS cable detect results */
mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC; mask = ap->hard_port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
pci_read_config_byte(pdev, PIIX_IOCFG, &tmp); pci_read_config_byte(pdev, PIIX_IOCFG, &tmp);
if ((tmp & mask) == 0) if ((tmp & mask) == 0)
goto cbl40; goto cbl40;
...@@ -294,7 +294,7 @@ static void piix_pata_cbl_detect(struct ata_port *ap) ...@@ -294,7 +294,7 @@ static void piix_pata_cbl_detect(struct ata_port *ap)
static void piix_pata_phy_reset(struct ata_port *ap) static void piix_pata_phy_reset(struct ata_port *ap)
{ {
if (!pci_test_config_bits(ap->host_set->pdev, if (!pci_test_config_bits(ap->host_set->pdev,
&piix_enable_bits[ap->port_no])) { &piix_enable_bits[ap->hard_port_no])) {
ata_port_disable(ap); ata_port_disable(ap);
printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id);
return; return;
...@@ -327,8 +327,8 @@ static int piix_sata_probe (struct ata_port *ap) ...@@ -327,8 +327,8 @@ static int piix_sata_probe (struct ata_port *ap)
int orig_mask, mask, i; int orig_mask, mask, i;
u8 pcs; u8 pcs;
mask = (PIIX_PORT_PRESENT << ap->port_no) | mask = (PIIX_PORT_PRESENT << ap->hard_port_no) |
(PIIX_PORT_ENABLED << ap->port_no); (PIIX_PORT_ENABLED << ap->hard_port_no);
pci_read_config_byte(pdev, ICH5_PCS, &pcs); pci_read_config_byte(pdev, ICH5_PCS, &pcs);
orig_mask = (int) pcs & 0xff; orig_mask = (int) pcs & 0xff;
...@@ -345,7 +345,7 @@ static int piix_sata_probe (struct ata_port *ap) ...@@ -345,7 +345,7 @@ static int piix_sata_probe (struct ata_port *ap)
mask = (PIIX_PORT_PRESENT << i) | (PIIX_PORT_ENABLED << i); mask = (PIIX_PORT_PRESENT << i) | (PIIX_PORT_ENABLED << i);
if ((orig_mask & mask) == mask) if ((orig_mask & mask) == mask)
if (combined || (i == ap->port_no)) if (combined || (i == ap->hard_port_no))
return 1; return 1;
} }
...@@ -394,7 +394,7 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev) ...@@ -394,7 +394,7 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev)
unsigned int pio = adev->pio_mode - XFER_PIO_0; unsigned int pio = adev->pio_mode - XFER_PIO_0;
struct pci_dev *dev = ap->host_set->pdev; struct pci_dev *dev = ap->host_set->pdev;
unsigned int is_slave = (adev->devno != 0); unsigned int is_slave = (adev->devno != 0);
unsigned int master_port= ap->port_no ? 0x42 : 0x40; unsigned int master_port= ap->hard_port_no ? 0x42 : 0x40;
unsigned int slave_port = 0x44; unsigned int slave_port = 0x44;
u16 master_data; u16 master_data;
u8 slave_data; u8 slave_data;
...@@ -412,10 +412,10 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev) ...@@ -412,10 +412,10 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev)
/* enable PPE, IE and TIME */ /* enable PPE, IE and TIME */
master_data |= 0x0070; master_data |= 0x0070;
pci_read_config_byte(dev, slave_port, &slave_data); pci_read_config_byte(dev, slave_port, &slave_data);
slave_data &= (ap->port_no ? 0x0f : 0xf0); slave_data &= (ap->hard_port_no ? 0x0f : 0xf0);
slave_data |= slave_data |=
(timings[pio][0] << 2) | (timings[pio][0] << 2) |
(timings[pio][1] << (ap->port_no ? 4 : 0)); (timings[pio][1] << (ap->hard_port_no ? 4 : 0));
} else { } else {
master_data &= 0xccf8; master_data &= 0xccf8;
/* enable PPE, IE and TIME */ /* enable PPE, IE and TIME */
...@@ -445,9 +445,9 @@ static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev) ...@@ -445,9 +445,9 @@ static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev)
{ {
unsigned int udma = adev->dma_mode; /* FIXME: MWDMA too */ unsigned int udma = adev->dma_mode; /* FIXME: MWDMA too */
struct pci_dev *dev = ap->host_set->pdev; struct pci_dev *dev = ap->host_set->pdev;
u8 maslave = ap->port_no ? 0x42 : 0x40; u8 maslave = ap->hard_port_no ? 0x42 : 0x40;
u8 speed = udma; u8 speed = udma;
unsigned int drive_dn = (ap->port_no ? 2 : 0) + adev->devno; unsigned int drive_dn = (ap->hard_port_no ? 2 : 0) + adev->devno;
int a_speed = 3 << (drive_dn * 4); int a_speed = 3 << (drive_dn * 4);
int u_flag = 1 << drive_dn; int u_flag = 1 << drive_dn;
int v_flag = 0x01 << drive_dn; int v_flag = 0x01 << drive_dn;
......
...@@ -3032,6 +3032,8 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, ...@@ -3032,6 +3032,8 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
ap->ctl = ATA_DEVCTL_OBS; ap->ctl = ATA_DEVCTL_OBS;
ap->host_set = host_set; ap->host_set = host_set;
ap->port_no = port_no; ap->port_no = port_no;
ap->hard_port_no =
ent->legacy_mode ? ent->hard_port_no : port_no;
ap->pio_mask = ent->pio_mask; ap->pio_mask = ent->pio_mask;
ap->mwdma_mask = ent->mwdma_mask; ap->mwdma_mask = ent->mwdma_mask;
ap->udma_mask = ent->udma_mask; ap->udma_mask = ent->udma_mask;
...@@ -3338,9 +3340,15 @@ ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port) ...@@ -3338,9 +3340,15 @@ ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port)
probe_ent[0].n_ports = 1; probe_ent[0].n_ports = 1;
probe_ent[0].irq = 14; probe_ent[0].irq = 14;
probe_ent[0].hard_port_no = 0;
probe_ent[0].legacy_mode = 1;
probe_ent[1].n_ports = 1; probe_ent[1].n_ports = 1;
probe_ent[1].irq = 15; probe_ent[1].irq = 15;
probe_ent[1].hard_port_no = 1;
probe_ent[1].legacy_mode = 1;
probe_ent[0].port[0].cmd_addr = 0x1f0; probe_ent[0].port[0].cmd_addr = 0x1f0;
probe_ent[0].port[0].altstatus_addr = probe_ent[0].port[0].altstatus_addr =
probe_ent[0].port[0].ctl_addr = 0x3f6; probe_ent[0].port[0].ctl_addr = 0x3f6;
......
...@@ -189,6 +189,7 @@ struct ata_probe_ent { ...@@ -189,6 +189,7 @@ struct ata_probe_ent {
Scsi_Host_Template *sht; Scsi_Host_Template *sht;
struct ata_ioports port[ATA_MAX_PORTS]; struct ata_ioports port[ATA_MAX_PORTS];
unsigned int n_ports; unsigned int n_ports;
unsigned int hard_port_no;
unsigned int pio_mask; unsigned int pio_mask;
unsigned int mwdma_mask; unsigned int mwdma_mask;
unsigned int udma_mask; unsigned int udma_mask;
...@@ -273,6 +274,7 @@ struct ata_port { ...@@ -273,6 +274,7 @@ struct ata_port {
unsigned long flags; /* ATA_FLAG_xxx */ unsigned long flags; /* ATA_FLAG_xxx */
unsigned int id; /* unique id req'd by scsi midlyr */ unsigned int id; /* unique id req'd by scsi midlyr */
unsigned int port_no; /* unique port #; from zero */ unsigned int port_no; /* unique port #; from zero */
unsigned int hard_port_no; /* hardware port #; from zero */
struct ata_prd *prd; /* our SG list */ struct ata_prd *prd; /* our SG list */
dma_addr_t prd_dma; /* and its DMA mapping */ dma_addr_t prd_dma; /* and its DMA mapping */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment