Commit 054446cf authored by Russell King's avatar Russell King Committed by Russell King

[PCMCIA] Fix cardbus init failure paths.

Currently, yenta does not try to clean up after an error occurs while
initialising a cardbus socket.  This cset ensures that we release
resources.  We also claim the cardbus MMIO memory resource.
parent 6b8ed7d3
...@@ -752,6 +752,7 @@ static void yenta_close(struct pci_dev *dev) ...@@ -752,6 +752,7 @@ static void yenta_close(struct pci_dev *dev)
iounmap(sock->base); iounmap(sock->base);
yenta_free_resources(sock); yenta_free_resources(sock);
pci_release_regions(dev);
pci_set_drvdata(dev, NULL); pci_set_drvdata(dev, NULL);
} }
...@@ -823,6 +824,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i ...@@ -823,6 +824,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
{ {
struct yenta_socket *socket; struct yenta_socket *socket;
struct cardbus_override_struct *d; struct cardbus_override_struct *d;
int ret;
socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL); socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL);
if (!socket) if (!socket)
...@@ -842,11 +844,19 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i ...@@ -842,11 +844,19 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
/* /*
* Do some basic sanity checking.. * Do some basic sanity checking..
*/ */
if (pci_enable_device(dev)) if (pci_enable_device(dev)) {
return -1; ret = -EBUSY;
goto free;
}
ret = pci_request_regions(dev, "yenta_socket");
if (ret)
goto disable;
if (!pci_resource_start(dev, 0)) { if (!pci_resource_start(dev, 0)) {
printk("No cardbus resource!\n"); printk("No cardbus resource!\n");
return -1; ret = -ENODEV;
goto release;
} }
/* /*
...@@ -854,8 +864,12 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i ...@@ -854,8 +864,12 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
* and request the IRQ. * and request the IRQ.
*/ */
socket->base = ioremap(pci_resource_start(dev, 0), 0x1000); socket->base = ioremap(pci_resource_start(dev, 0), 0x1000);
if (!socket->base) if (!socket->base) {
return -1; ret = -ENOMEM;
goto release;
}
printk(KERN_INFO "Yenta: CardBus bridge found at %s\n", dev->slot_name);
yenta_config_init(socket); yenta_config_init(socket);
...@@ -871,9 +885,9 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i ...@@ -871,9 +885,9 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
d = cardbus_override; d = cardbus_override;
while (d->override) { while (d->override) {
if ((dev->vendor == d->vendor) && (dev->device == d->device)) { if ((dev->vendor == d->vendor) && (dev->device == d->device)) {
int retval = d->override(socket); ret = d->override(socket);
if (retval < 0) if (ret < 0)
return retval; goto unmap;
} }
d++; d++;
} }
...@@ -895,7 +909,20 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i ...@@ -895,7 +909,20 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
/* Register it with the pcmcia layer.. */ /* Register it with the pcmcia layer.. */
return pcmcia_register_socket(&socket->socket); ret = pcmcia_register_socket(&socket->socket);
if (ret == 0)
goto out;
unmap:
iounmap(socket->base);
release:
pci_release_regions(dev);
disable:
pci_disable_device(dev);
free:
kfree(socket);
out:
return ret;
} }
......
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