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 | |
| 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>
| -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) |
