diff options
author | Alexey Khoroshilov <khoroshilov@ispras.ru> | 2012-09-25 08:56:02 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-25 18:48:25 -0400 |
commit | 4c229df0b19cda41a8ea93f26497374004299fda (patch) | |
tree | a9e3254733012de324061a1708726f2bceffc4d2 | |
parent | 62fea8c8f1bf5ca33ba55b3f421d9598a68297ee (diff) |
staging: sbe-2t3e3: fix error handling in t3e3_init_channel()
t3e3_init_channel() incorrectly handles errors in several places:
it returns zero and does not deallocate all required resources.
The patch fixes that places.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/sbe-2t3e3/module.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/staging/sbe-2t3e3/module.c b/drivers/staging/sbe-2t3e3/module.c index cd778b3a02b2..8adb17816ad9 100644 --- a/drivers/staging/sbe-2t3e3/module.c +++ b/drivers/staging/sbe-2t3e3/module.c | |||
@@ -67,6 +67,7 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev * | |||
67 | dev = alloc_hdlcdev(channel); | 67 | dev = alloc_hdlcdev(channel); |
68 | if (!dev) { | 68 | if (!dev) { |
69 | printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n"); | 69 | printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n"); |
70 | err = -ENOMEM; | ||
70 | goto free_regions; | 71 | goto free_regions; |
71 | } | 72 | } |
72 | 73 | ||
@@ -82,8 +83,9 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev * | |||
82 | else | 83 | else |
83 | channel->h.slot = 0; | 84 | channel->h.slot = 0; |
84 | 85 | ||
85 | if (setup_device(dev, channel)) | 86 | err = setup_device(dev, channel); |
86 | goto free_regions; | 87 | if (err) |
88 | goto free_dev; | ||
87 | 89 | ||
88 | pci_read_config_dword(channel->pdev, 0x40, &val); /* mask sleep mode */ | 90 | pci_read_config_dword(channel->pdev, 0x40, &val); /* mask sleep mode */ |
89 | pci_write_config_dword(channel->pdev, 0x40, val & 0x3FFFFFFF); | 91 | pci_write_config_dword(channel->pdev, 0x40, val & 0x3FFFFFFF); |
@@ -92,14 +94,19 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev * | |||
92 | pci_read_config_dword(channel->pdev, PCI_COMMAND, &channel->h.command); | 94 | pci_read_config_dword(channel->pdev, PCI_COMMAND, &channel->h.command); |
93 | t3e3_init(channel); | 95 | t3e3_init(channel); |
94 | 96 | ||
95 | if (request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev)) { | 97 | err = request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev); |
98 | if (err) { | ||
96 | printk(KERN_WARNING "%s: could not get irq: %d\n", dev->name, dev->irq); | 99 | printk(KERN_WARNING "%s: could not get irq: %d\n", dev->name, dev->irq); |
97 | goto free_regions; | 100 | goto unregister_dev; |
98 | } | 101 | } |
99 | 102 | ||
100 | pci_set_drvdata(pdev, channel); | 103 | pci_set_drvdata(pdev, channel); |
101 | return 0; | 104 | return 0; |
102 | 105 | ||
106 | unregister_dev: | ||
107 | unregister_hdlc_device(dev); | ||
108 | free_dev: | ||
109 | free_netdev(dev); | ||
103 | free_regions: | 110 | free_regions: |
104 | pci_release_regions(pdev); | 111 | pci_release_regions(pdev); |
105 | disable: | 112 | disable: |