diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-07-22 05:56:38 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-07-27 05:04:10 -0400 |
commit | b6d9c125e6610591c04ca9045f641e35ce1a9226 (patch) | |
tree | 416672c79a3ee4b0764561ba5ebcf9ed3ba4d5c7 /drivers/firewire/nosy.c | |
parent | 165476671f731b4c3d6cf401d0e1886f4a4f4a8e (diff) |
firewire: nosy: handle errors in device probe
and add a missing pci_disable_device() to device shutdown.
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/nosy.c')
-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 = { |