aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/nosy.c
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2010-07-22 05:56:38 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2010-07-27 05:04:10 -0400
commitb6d9c125e6610591c04ca9045f641e35ce1a9226 (patch)
tree416672c79a3ee4b0764561ba5ebcf9ed3ba4d5c7 /drivers/firewire/nosy.c
parent165476671f731b4c3d6cf401d0e1886f4a4f4a8e (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.c40
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
633fail_free_irq:
634 reg_write(lynx, PCI_INT_ENABLE, 0);
635 free_irq(lynx->pci_device->irq, lynx);
636
637fail_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
650fail_disable:
651 pci_disable_device(dev);
652
653 return ret;
628} 654}
629 655
630static struct pci_device_id pci_table[] __devinitdata = { 656static struct pci_device_id pci_table[] __devinitdata = {