diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-09-29 21:50:17 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-10-13 10:49:23 -0400 |
commit | 7aed3fb73f4ac7912ce9e0c232a15ee012bf4be5 (patch) | |
tree | 3a07769d97225612892db92a8917b3460465b9f5 /drivers/input | |
parent | 05e93a746a0781429de73117b2f2ef48d2312759 (diff) |
Input: emu10k1 - do not leave device enabled when probe fails
Rework emu_probe() to make sure we leave the device disabled if probe
fails for any reason.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/gameport/emu10k1-gp.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c index f85620590b66..422aa0a6b77f 100644 --- a/drivers/input/gameport/emu10k1-gp.c +++ b/drivers/input/gameport/emu10k1-gp.c | |||
@@ -59,45 +59,52 @@ MODULE_DEVICE_TABLE(pci, emu_tbl); | |||
59 | 59 | ||
60 | static int __devinit emu_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 60 | static int __devinit emu_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
61 | { | 61 | { |
62 | int ioport, iolen; | ||
63 | struct emu *emu; | 62 | struct emu *emu; |
64 | struct gameport *port; | 63 | struct gameport *port; |
65 | 64 | int error; | |
66 | if (pci_enable_device(pdev)) | ||
67 | return -EBUSY; | ||
68 | |||
69 | ioport = pci_resource_start(pdev, 0); | ||
70 | iolen = pci_resource_len(pdev, 0); | ||
71 | |||
72 | if (!request_region(ioport, iolen, "emu10k1-gp")) | ||
73 | return -EBUSY; | ||
74 | 65 | ||
75 | emu = kzalloc(sizeof(struct emu), GFP_KERNEL); | 66 | emu = kzalloc(sizeof(struct emu), GFP_KERNEL); |
76 | port = gameport_allocate_port(); | 67 | port = gameport_allocate_port(); |
77 | if (!emu || !port) { | 68 | if (!emu || !port) { |
78 | printk(KERN_ERR "emu10k1-gp: Memory allocation failed\n"); | 69 | printk(KERN_ERR "emu10k1-gp: Memory allocation failed\n"); |
79 | release_region(ioport, iolen); | 70 | error = -ENOMEM; |
80 | pci_disable_device(pdev); | 71 | goto err_out_free; |
81 | kfree(emu); | ||
82 | gameport_free_port(port); | ||
83 | return -ENOMEM; | ||
84 | } | 72 | } |
85 | 73 | ||
86 | emu->io = ioport; | 74 | error = pci_enable_device(pdev); |
87 | emu->size = iolen; | 75 | if (error) |
76 | goto err_out_free; | ||
77 | |||
78 | emu->io = pci_resource_start(pdev, 0); | ||
79 | emu->size = pci_resource_len(pdev, 0); | ||
80 | |||
88 | emu->dev = pdev; | 81 | emu->dev = pdev; |
89 | emu->gameport = port; | 82 | emu->gameport = port; |
90 | 83 | ||
91 | gameport_set_name(port, "EMU10K1"); | 84 | gameport_set_name(port, "EMU10K1"); |
92 | gameport_set_phys(port, "pci%s/gameport0", pci_name(pdev)); | 85 | gameport_set_phys(port, "pci%s/gameport0", pci_name(pdev)); |
93 | port->dev.parent = &pdev->dev; | 86 | port->dev.parent = &pdev->dev; |
94 | port->io = ioport; | 87 | port->io = emu->io; |
88 | |||
89 | if (!request_region(emu->io, emu->size, "emu10k1-gp")) { | ||
90 | printk(KERN_ERR "emu10k1-gp: unable to grab region 0x%x-0x%x\n", | ||
91 | emu->io, emu->io + emu->size - 1); | ||
92 | error = -EBUSY; | ||
93 | goto err_out_disable_dev; | ||
94 | } | ||
95 | 95 | ||
96 | pci_set_drvdata(pdev, emu); | 96 | pci_set_drvdata(pdev, emu); |
97 | 97 | ||
98 | gameport_register_port(port); | 98 | gameport_register_port(port); |
99 | 99 | ||
100 | return 0; | 100 | return 0; |
101 | |||
102 | err_out_disable_dev: | ||
103 | pci_disable_device(pdev); | ||
104 | err_out_free: | ||
105 | gameport_free_port(port); | ||
106 | kfree(emu); | ||
107 | return error; | ||
101 | } | 108 | } |
102 | 109 | ||
103 | static void __devexit emu_remove(struct pci_dev *pdev) | 110 | static void __devexit emu_remove(struct pci_dev *pdev) |