forked from luck/tmp_suning_uos_patched
[libata sata_uli] kill scr_addr abuse
sata_uli was storing PCI config addresses in a variable intended for port addresses, a variable soon to become void __iomem *. Update the driver to store the SCR address, found in PCI config space, in the driver-private data area.
This commit is contained in:
parent
02cbd926e9
commit
50106c5a03
@ -44,6 +44,8 @@ enum {
|
|||||||
uli_5287 = 1,
|
uli_5287 = 1,
|
||||||
uli_5281 = 2,
|
uli_5281 = 2,
|
||||||
|
|
||||||
|
uli_max_ports = 4,
|
||||||
|
|
||||||
/* PCI configuration registers */
|
/* PCI configuration registers */
|
||||||
ULI5287_BASE = 0x90, /* sata0 phy SCR registers */
|
ULI5287_BASE = 0x90, /* sata0 phy SCR registers */
|
||||||
ULI5287_OFFS = 0x10, /* offset from sata0->sata1 phy regs */
|
ULI5287_OFFS = 0x10, /* offset from sata0->sata1 phy regs */
|
||||||
@ -51,6 +53,10 @@ enum {
|
|||||||
ULI5281_OFFS = 0x60, /* offset from sata0->sata1 phy regs */
|
ULI5281_OFFS = 0x60, /* offset from sata0->sata1 phy regs */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct uli_priv {
|
||||||
|
unsigned int scr_cfg_addr[uli_max_ports];
|
||||||
|
};
|
||||||
|
|
||||||
static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
|
static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
|
||||||
static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg);
|
static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg);
|
||||||
static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
|
static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
|
||||||
@ -137,7 +143,8 @@ MODULE_VERSION(DRV_VERSION);
|
|||||||
|
|
||||||
static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
|
static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
|
||||||
{
|
{
|
||||||
return ap->ioaddr.scr_addr + (4 * sc_reg);
|
struct uli_priv *hpriv = ap->host_set->private_data;
|
||||||
|
return hpriv->scr_cfg_addr[ap->port_no] + (4 * sc_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
|
static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
|
||||||
@ -182,6 +189,7 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
int rc;
|
int rc;
|
||||||
unsigned int board_idx = (unsigned int) ent->driver_data;
|
unsigned int board_idx = (unsigned int) ent->driver_data;
|
||||||
int pci_dev_busy = 0;
|
int pci_dev_busy = 0;
|
||||||
|
struct uli_priv *hpriv;
|
||||||
|
|
||||||
if (!printed_version++)
|
if (!printed_version++)
|
||||||
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
|
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
|
||||||
@ -210,10 +218,18 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
goto err_out_regions;
|
goto err_out_regions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL);
|
||||||
|
if (!hpriv) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto err_out_probe_ent;
|
||||||
|
}
|
||||||
|
|
||||||
|
probe_ent->private_data = hpriv;
|
||||||
|
|
||||||
switch (board_idx) {
|
switch (board_idx) {
|
||||||
case uli_5287:
|
case uli_5287:
|
||||||
probe_ent->port[0].scr_addr = ULI5287_BASE;
|
hpriv->scr_cfg_addr[0] = ULI5287_BASE;
|
||||||
probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS;
|
hpriv->scr_cfg_addr[1] = ULI5287_BASE + ULI5287_OFFS;
|
||||||
probe_ent->n_ports = 4;
|
probe_ent->n_ports = 4;
|
||||||
|
|
||||||
probe_ent->port[2].cmd_addr = pci_resource_start(pdev, 0) + 8;
|
probe_ent->port[2].cmd_addr = pci_resource_start(pdev, 0) + 8;
|
||||||
@ -221,27 +237,27 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
probe_ent->port[2].ctl_addr =
|
probe_ent->port[2].ctl_addr =
|
||||||
(pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS) + 4;
|
(pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS) + 4;
|
||||||
probe_ent->port[2].bmdma_addr = pci_resource_start(pdev, 4) + 16;
|
probe_ent->port[2].bmdma_addr = pci_resource_start(pdev, 4) + 16;
|
||||||
probe_ent->port[2].scr_addr = ULI5287_BASE + ULI5287_OFFS*4;
|
hpriv->scr_cfg_addr[2] = ULI5287_BASE + ULI5287_OFFS*4;
|
||||||
|
|
||||||
probe_ent->port[3].cmd_addr = pci_resource_start(pdev, 2) + 8;
|
probe_ent->port[3].cmd_addr = pci_resource_start(pdev, 2) + 8;
|
||||||
probe_ent->port[3].altstatus_addr =
|
probe_ent->port[3].altstatus_addr =
|
||||||
probe_ent->port[3].ctl_addr =
|
probe_ent->port[3].ctl_addr =
|
||||||
(pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS) + 4;
|
(pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS) + 4;
|
||||||
probe_ent->port[3].bmdma_addr = pci_resource_start(pdev, 4) + 24;
|
probe_ent->port[3].bmdma_addr = pci_resource_start(pdev, 4) + 24;
|
||||||
probe_ent->port[3].scr_addr = ULI5287_BASE + ULI5287_OFFS*5;
|
hpriv->scr_cfg_addr[3] = ULI5287_BASE + ULI5287_OFFS*5;
|
||||||
|
|
||||||
ata_std_ports(&probe_ent->port[2]);
|
ata_std_ports(&probe_ent->port[2]);
|
||||||
ata_std_ports(&probe_ent->port[3]);
|
ata_std_ports(&probe_ent->port[3]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case uli_5289:
|
case uli_5289:
|
||||||
probe_ent->port[0].scr_addr = ULI5287_BASE;
|
hpriv->scr_cfg_addr[0] = ULI5287_BASE;
|
||||||
probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS;
|
hpriv->scr_cfg_addr[1] = ULI5287_BASE + ULI5287_OFFS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case uli_5281:
|
case uli_5281:
|
||||||
probe_ent->port[0].scr_addr = ULI5281_BASE;
|
hpriv->scr_cfg_addr[0] = ULI5281_BASE;
|
||||||
probe_ent->port[1].scr_addr = ULI5281_BASE + ULI5281_OFFS;
|
hpriv->scr_cfg_addr[1] = ULI5281_BASE + ULI5281_OFFS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -258,9 +274,10 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_out_probe_ent:
|
||||||
|
kfree(probe_ent);
|
||||||
err_out_regions:
|
err_out_regions:
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
|
|
||||||
err_out:
|
err_out:
|
||||||
if (!pci_dev_busy)
|
if (!pci_dev_busy)
|
||||||
pci_disable_device(pdev);
|
pci_disable_device(pdev);
|
||||||
|
Loading…
Reference in New Issue
Block a user