Commit 130199a3 authored by Pete Zaitcev's avatar Pete Zaitcev Committed by Jeff Garzik

[libata] fix probe object allocation bugs

The code previously alloced a 2-entry array, then freed each
entry individually, for users of "combined mode".

Convert code to use allocation function that only allocates
one object at a time.

Also, un-export ata_pci_init_legacy_mode(), as its only user is
libata-core.
parent 9c690cbf
......@@ -3535,32 +3535,28 @@ void ata_std_ports(struct ata_ioports *ioaddr)
}
static struct ata_probe_ent *
ata_probe_ent_alloc(int n, struct device *dev, struct ata_port_info **port)
ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port)
{
struct ata_probe_ent *probe_ent;
int i;
probe_ent = kmalloc(sizeof(*probe_ent) * n, GFP_KERNEL);
probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
if (!probe_ent) {
printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
kobject_name(&(dev->kobj)));
return NULL;
}
memset(probe_ent, 0, sizeof(*probe_ent) * n);
for (i = 0; i < n; i++) {
INIT_LIST_HEAD(&probe_ent[i].node);
probe_ent[i].dev = dev;
memset(probe_ent, 0, sizeof(*probe_ent));
probe_ent[i].sht = port[i]->sht;
probe_ent[i].host_flags = port[i]->host_flags;
probe_ent[i].pio_mask = port[i]->pio_mask;
probe_ent[i].mwdma_mask = port[i]->mwdma_mask;
probe_ent[i].udma_mask = port[i]->udma_mask;
probe_ent[i].port_ops = port[i]->port_ops;
INIT_LIST_HEAD(&probe_ent->node);
probe_ent->dev = dev;
}
probe_ent->sht = port->sht;
probe_ent->host_flags = port->host_flags;
probe_ent->pio_mask = port->pio_mask;
probe_ent->mwdma_mask = port->mwdma_mask;
probe_ent->udma_mask = port->udma_mask;
probe_ent->port_ops = port->port_ops;
return probe_ent;
}
......@@ -3570,7 +3566,7 @@ struct ata_probe_ent *
ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
{
struct ata_probe_ent *probe_ent =
ata_probe_ent_alloc(1, pci_dev_to_dev(pdev), port);
ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
if (!probe_ent)
return NULL;
......@@ -3596,39 +3592,47 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
return probe_ent;
}
struct ata_probe_ent *
ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port)
static struct ata_probe_ent *
ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
struct ata_probe_ent **ppe2)
{
struct ata_probe_ent *probe_ent =
ata_probe_ent_alloc(2, pci_dev_to_dev(pdev), port);
struct ata_probe_ent *probe_ent, *probe_ent2;
probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
if (!probe_ent)
return NULL;
probe_ent2 = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[1]);
if (!probe_ent2) {
kfree(probe_ent);
return NULL;
}
probe_ent[0].n_ports = 1;
probe_ent[0].irq = 14;
probe_ent->n_ports = 1;
probe_ent->irq = 14;
probe_ent[0].hard_port_no = 0;
probe_ent[0].legacy_mode = 1;
probe_ent->hard_port_no = 0;
probe_ent->legacy_mode = 1;
probe_ent[1].n_ports = 1;
probe_ent[1].irq = 15;
probe_ent2->n_ports = 1;
probe_ent2->irq = 15;
probe_ent[1].hard_port_no = 1;
probe_ent[1].legacy_mode = 1;
probe_ent2->hard_port_no = 1;
probe_ent2->legacy_mode = 1;
probe_ent[0].port[0].cmd_addr = 0x1f0;
probe_ent[0].port[0].altstatus_addr =
probe_ent[0].port[0].ctl_addr = 0x3f6;
probe_ent[0].port[0].bmdma_addr = pci_resource_start(pdev, 4);
probe_ent->port[0].cmd_addr = 0x1f0;
probe_ent->port[0].altstatus_addr =
probe_ent->port[0].ctl_addr = 0x3f6;
probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
probe_ent[1].port[0].cmd_addr = 0x170;
probe_ent[1].port[0].altstatus_addr =
probe_ent[1].port[0].ctl_addr = 0x376;
probe_ent[1].port[0].bmdma_addr = pci_resource_start(pdev, 4)+8;
probe_ent2->port[0].cmd_addr = 0x170;
probe_ent2->port[0].altstatus_addr =
probe_ent2->port[0].ctl_addr = 0x376;
probe_ent2->port[0].bmdma_addr = pci_resource_start(pdev, 4)+8;
ata_std_ports(&probe_ent[0].port[0]);
ata_std_ports(&probe_ent[1].port[0]);
ata_std_ports(&probe_ent->port[0]);
ata_std_ports(&probe_ent2->port[0]);
*ppe2 = probe_ent2;
return probe_ent;
}
......@@ -3724,9 +3728,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
goto err_out_regions;
if (legacy_mode) {
probe_ent = ata_pci_init_legacy_mode(pdev, port);
if (probe_ent)
probe_ent2 = &probe_ent[1];
probe_ent = ata_pci_init_legacy_mode(pdev, port, &probe_ent2);
} else
probe_ent = ata_pci_init_native_mode(pdev, port);
if (!probe_ent) {
......@@ -3740,8 +3742,12 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
if (legacy_mode) {
if (legacy_mode & (1 << 0))
ata_device_add(probe_ent);
else
kfree(probe_ent);
if (legacy_mode & (1 << 1))
ata_device_add(probe_ent2);
else
kfree(probe_ent2);
} else {
ata_device_add(probe_ent);
}
......@@ -3931,7 +3937,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_simulate);
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(pci_test_config_bits);
EXPORT_SYMBOL_GPL(ata_pci_init_legacy_mode);
EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
EXPORT_SYMBOL_GPL(ata_pci_init_one);
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
......
......@@ -436,8 +436,6 @@ struct pci_bits {
extern struct ata_probe_ent *
ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port);
extern struct ata_probe_ent *
ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port);
extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
#endif /* CONFIG_PCI */
......
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