Commit f09e59b4 authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Linus Torvalds

[PATCH] tpam_main.c: add missing pci_enable_device()

Add pci_enable_device()/pci_disable_device().  In the past, drivers
often worked without this, but it is now required in order to route
PCI interrupts correctly.
Signed-off-by: default avatarBjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent dcd769e6
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
/* Local functions prototypes */ /* Local functions prototypes */
static int __devinit tpam_probe(struct pci_dev *, const struct pci_device_id *); static int __devinit tpam_probe(struct pci_dev *, const struct pci_device_id *);
static void __devexit tpam_unregister_card(tpam_card *); static void __devexit tpam_unregister_card(struct pci_dev *, tpam_card *);
static void __devexit tpam_remove(struct pci_dev *); static void __devexit tpam_remove(struct pci_dev *);
static int __init tpam_init(void); static int __init tpam_init(void);
static void __exit tpam_exit(void); static void __exit tpam_exit(void);
...@@ -86,13 +86,20 @@ u32 tpam_findchannel(tpam_card *card, u32 ncoid) { ...@@ -86,13 +86,20 @@ u32 tpam_findchannel(tpam_card *card, u32 ncoid) {
*/ */
static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) { static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) {
tpam_card *card, *c; tpam_card *card, *c;
int i; int i, err;
if (pci_enable_device(dev)) {
printk(KERN_ERR "TurboPAM: can't enable PCI device at %s\n",
pci_name(dev));
return -ENODEV;
}
/* allocate memory for the board structure */ /* allocate memory for the board structure */
if (!(card = (tpam_card *)kmalloc(sizeof(tpam_card), GFP_KERNEL))) { if (!(card = (tpam_card *)kmalloc(sizeof(tpam_card), GFP_KERNEL))) {
printk(KERN_ERR "TurboPAM: tpam_register_card: " printk(KERN_ERR "TurboPAM: tpam_register_card: "
"kmalloc failed!\n"); "kmalloc failed!\n");
return -ENOMEM; err = -ENOMEM;
goto err_out_disable_dev;
} }
memset((char *)card, 0, sizeof(tpam_card)); memset((char *)card, 0, sizeof(tpam_card));
...@@ -106,8 +113,8 @@ static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id ...@@ -106,8 +113,8 @@ static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id
card->interface.id, card)) { card->interface.id, card)) {
printk(KERN_ERR "TurboPAM: tpam_register_card: " printk(KERN_ERR "TurboPAM: tpam_register_card: "
"could not request irq %d\n", card->irq); "could not request irq %d\n", card->irq);
kfree(card); err = -EIO;
return -EIO; goto err_out_free_card;
} }
/* remap board memory */ /* remap board memory */
...@@ -115,9 +122,8 @@ static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id ...@@ -115,9 +122,8 @@ static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id
0x800000))) { 0x800000))) {
printk(KERN_ERR "TurboPAM: tpam_register_card: " printk(KERN_ERR "TurboPAM: tpam_register_card: "
"unable to remap bar0\n"); "unable to remap bar0\n");
free_irq(card->irq, card); err = -EIO;
kfree(card); goto err_out_free_irq;
return -EIO;
} }
/* reset the board */ /* reset the board */
...@@ -150,10 +156,8 @@ static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id ...@@ -150,10 +156,8 @@ static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id
if (!register_isdn(&card->interface)) { if (!register_isdn(&card->interface)) {
printk(KERN_ERR "TurboPAM: tpam_register_card: " printk(KERN_ERR "TurboPAM: tpam_register_card: "
"unable to register %s\n", card->interface.id); "unable to register %s\n", card->interface.id);
free_irq(card->irq, card); err = -EIO;
iounmap((void *)card->bar0); goto err_out_iounmap;
kfree(card);
return -EIO;
} }
card->id = card->interface.channels; card->id = card->interface.channels;
...@@ -195,6 +199,19 @@ static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id ...@@ -195,6 +199,19 @@ static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id
pci_set_drvdata(dev, card); pci_set_drvdata(dev, card);
return 0; return 0;
err_out_iounmap:
iounmap((void *)card->bar0);
err_out_free_irq:
free_irq(card->irq, card);
err_out_free_card:
kfree(card);
err_out_disable_dev:
pci_disable_device(dev);
return err;
} }
/* /*
...@@ -202,7 +219,7 @@ static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id ...@@ -202,7 +219,7 @@ static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id
* *
* card: the board. * card: the board.
*/ */
static void __devexit tpam_unregister_card(tpam_card *card) { static void __devexit tpam_unregister_card(struct pci_dev *pcidev, tpam_card *card) {
isdn_ctrl cmd; isdn_ctrl cmd;
/* prevent the ISDN link layer that the driver will be unloaded */ /* prevent the ISDN link layer that the driver will be unloaded */
...@@ -215,6 +232,8 @@ static void __devexit tpam_unregister_card(tpam_card *card) { ...@@ -215,6 +232,8 @@ static void __devexit tpam_unregister_card(tpam_card *card) {
/* release mapped memory */ /* release mapped memory */
iounmap((void *)card->bar0); iounmap((void *)card->bar0);
pci_disable_device(pcidev);
} }
/* /*
...@@ -235,7 +254,7 @@ static void __devexit tpam_remove(struct pci_dev *pcidev) { ...@@ -235,7 +254,7 @@ static void __devexit tpam_remove(struct pci_dev *pcidev) {
} }
/* unregister each board */ /* unregister each board */
tpam_unregister_card(card); tpam_unregister_card(pcidev, card);
/* and free the board structure itself */ /* and free the board structure itself */
kfree(card); kfree(card);
......
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