From 054446cffa62bfa25e825ded35c1b5b5611c5c4c Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 7 Aug 2003 01:53:14 +0100 Subject: [PATCH] [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. --- drivers/pcmcia/yenta_socket.c | 45 ++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index cb36024e055c4..ffafa4d90ee01 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -752,6 +752,7 @@ static void yenta_close(struct pci_dev *dev) iounmap(sock->base); yenta_free_resources(sock); + pci_release_regions(dev); pci_set_drvdata(dev, NULL); } @@ -823,6 +824,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i { struct yenta_socket *socket; struct cardbus_override_struct *d; + int ret; socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL); if (!socket) @@ -842,11 +844,19 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i /* * Do some basic sanity checking.. */ - if (pci_enable_device(dev)) - return -1; + if (pci_enable_device(dev)) { + ret = -EBUSY; + goto free; + } + + ret = pci_request_regions(dev, "yenta_socket"); + if (ret) + goto disable; + if (!pci_resource_start(dev, 0)) { 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 * and request the IRQ. */ socket->base = ioremap(pci_resource_start(dev, 0), 0x1000); - if (!socket->base) - return -1; + if (!socket->base) { + ret = -ENOMEM; + goto release; + } + + printk(KERN_INFO "Yenta: CardBus bridge found at %s\n", dev->slot_name); yenta_config_init(socket); @@ -871,9 +885,9 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i d = cardbus_override; while (d->override) { if ((dev->vendor == d->vendor) && (dev->device == d->device)) { - int retval = d->override(socket); - if (retval < 0) - return retval; + ret = d->override(socket); + if (ret < 0) + goto unmap; } d++; } @@ -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)); /* 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; } -- 2.53.0