diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/firewire/nosy.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c index a241b62630b2..ccf9c461bd86 100644 --- a/drivers/firewire/nosy.c +++ b/drivers/firewire/nosy.c | |||
| @@ -497,6 +497,7 @@ remove_card(struct pci_dev *dev) | |||
| 497 | lynx->rcv_buffer, lynx->rcv_buffer_bus); | 497 | lynx->rcv_buffer, lynx->rcv_buffer_bus); |
| 498 | 498 | ||
| 499 | iounmap(lynx->registers); | 499 | iounmap(lynx->registers); |
| 500 | pci_disable_device(dev); | ||
| 500 | 501 | ||
| 501 | minors[lynx->misc.minor] = NULL; | 502 | minors[lynx->misc.minor] = NULL; |
| 502 | misc_deregister(&lynx->misc); | 503 | misc_deregister(&lynx->misc); |
| @@ -511,7 +512,7 @@ add_card(struct pci_dev *dev, const struct pci_device_id *unused) | |||
| 511 | { | 512 | { |
| 512 | struct pcilynx *lynx; | 513 | struct pcilynx *lynx; |
| 513 | u32 p, end; | 514 | u32 p, end; |
| 514 | int i; | 515 | int ret, i; |
| 515 | 516 | ||
| 516 | if (pci_set_dma_mask(dev, 0xffffffff)) { | 517 | if (pci_set_dma_mask(dev, 0xffffffff)) { |
| 517 | error("DMA address limits not supported " | 518 | error("DMA address limits not supported " |
| @@ -527,7 +528,8 @@ add_card(struct pci_dev *dev, const struct pci_device_id *unused) | |||
| 527 | lynx = kzalloc(sizeof *lynx, GFP_KERNEL); | 528 | lynx = kzalloc(sizeof *lynx, GFP_KERNEL); |
| 528 | if (lynx == NULL) { | 529 | if (lynx == NULL) { |
| 529 | error("Failed to allocate control structure memory\n"); | 530 | error("Failed to allocate control structure memory\n"); |
| 530 | return -ENOMEM; | 531 | ret = -ENOMEM; |
| 532 | goto fail_disable; | ||
| 531 | } | 533 | } |
| 532 | lynx->pci_device = dev; | 534 | lynx->pci_device = dev; |
| 533 | pci_set_drvdata(dev, lynx); | 535 | pci_set_drvdata(dev, lynx); |
| @@ -547,9 +549,9 @@ add_card(struct pci_dev *dev, const struct pci_device_id *unused) | |||
| 547 | if (lynx->rcv_start_pcl == NULL || | 549 | if (lynx->rcv_start_pcl == NULL || |
| 548 | lynx->rcv_pcl == NULL || | 550 | lynx->rcv_pcl == NULL || |
| 549 | lynx->rcv_buffer == NULL) { | 551 | lynx->rcv_buffer == NULL) { |
| 550 | /* FIXME: do proper error handling. */ | ||
| 551 | error("Failed to allocate receive buffer\n"); | 552 | error("Failed to allocate receive buffer\n"); |
| 552 | return -ENOMEM; | 553 | ret = -ENOMEM; |
| 554 | goto fail_deallocate; | ||
| 553 | } | 555 | } |
| 554 | lynx->rcv_start_pcl->next = lynx->rcv_pcl_bus; | 556 | lynx->rcv_start_pcl->next = lynx->rcv_pcl_bus; |
| 555 | lynx->rcv_pcl->next = PCL_NEXT_INVALID; | 557 | lynx->rcv_pcl->next = PCL_NEXT_INVALID; |
| @@ -609,22 +611,46 @@ add_card(struct pci_dev *dev, const struct pci_device_id *unused) | |||
| 609 | if (request_irq(dev->irq, irq_handler, IRQF_SHARED, | 611 | if (request_irq(dev->irq, irq_handler, IRQF_SHARED, |
| 610 | driver_name, lynx)) { | 612 | driver_name, lynx)) { |
| 611 | error("Failed to allocate shared interrupt %d\n", dev->irq); | 613 | error("Failed to allocate shared interrupt %d\n", dev->irq); |
| 612 | return -EIO; | 614 | ret = -EIO; |
| 615 | goto fail_deallocate; | ||
| 613 | } | 616 | } |
| 614 | 617 | ||
| 615 | lynx->misc.parent = &dev->dev; | 618 | lynx->misc.parent = &dev->dev; |
| 616 | lynx->misc.minor = MISC_DYNAMIC_MINOR; | 619 | lynx->misc.minor = MISC_DYNAMIC_MINOR; |
| 617 | lynx->misc.name = "nosy"; | 620 | lynx->misc.name = "nosy"; |
| 618 | lynx->misc.fops = &nosy_ops; | 621 | lynx->misc.fops = &nosy_ops; |
| 619 | if (misc_register(&lynx->misc)) { | 622 | ret = misc_register(&lynx->misc); |
| 623 | if (ret) { | ||
| 620 | error("Failed to register misc char device\n"); | 624 | error("Failed to register misc char device\n"); |
| 621 | return -ENOMEM; | 625 | goto fail_free_irq; |
| 622 | } | 626 | } |
| 623 | minors[lynx->misc.minor] = lynx; | 627 | minors[lynx->misc.minor] = lynx; |
| 624 | 628 | ||
| 625 | notify("Initialized PCILynx IEEE1394 card, irq=%d\n", dev->irq); | 629 | notify("Initialized PCILynx IEEE1394 card, irq=%d\n", dev->irq); |
| 626 | 630 | ||
| 627 | return 0; | 631 | return 0; |
| 632 | |||
| 633 | fail_free_irq: | ||
| 634 | reg_write(lynx, PCI_INT_ENABLE, 0); | ||
| 635 | free_irq(lynx->pci_device->irq, lynx); | ||
| 636 | |||
| 637 | fail_deallocate: | ||
| 638 | if (lynx->rcv_start_pcl) | ||
| 639 | pci_free_consistent(lynx->pci_device, sizeof(struct pcl), | ||
| 640 | lynx->rcv_start_pcl, lynx->rcv_start_pcl_bus); | ||
| 641 | if (lynx->rcv_pcl) | ||
| 642 | pci_free_consistent(lynx->pci_device, sizeof(struct pcl), | ||
| 643 | lynx->rcv_pcl, lynx->rcv_pcl_bus); | ||
| 644 | if (lynx->rcv_buffer) | ||
| 645 | pci_free_consistent(lynx->pci_device, PAGE_SIZE, | ||
| 646 | lynx->rcv_buffer, lynx->rcv_buffer_bus); | ||
| 647 | iounmap(lynx->registers); | ||
| 648 | kfree(lynx); | ||
| 649 | |||
| 650 | fail_disable: | ||
| 651 | pci_disable_device(dev); | ||
| 652 | |||
| 653 | return ret; | ||
| 628 | } | 654 | } |
| 629 | 655 | ||
| 630 | static struct pci_device_id pci_table[] __devinitdata = { | 656 | static struct pci_device_id pci_table[] __devinitdata = { |
