diff options
Diffstat (limited to 'drivers/media/video/cx88/cx88-mpeg.c')
-rw-r--r-- | drivers/media/video/cx88/cx88-mpeg.c | 60 |
1 files changed, 29 insertions, 31 deletions
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 1b1418241b4..11d9865e34f 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -594,24 +594,14 @@ EXPORT_SYMBOL(cx8802_get_device); | |||
594 | 594 | ||
595 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype) | 595 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype) |
596 | { | 596 | { |
597 | struct cx8802_dev *h = NULL; | 597 | struct cx8802_driver *d; |
598 | struct cx8802_driver *d = NULL; | ||
599 | struct list_head *list; | 598 | struct list_head *list; |
600 | struct list_head *list2; | ||
601 | |||
602 | list_for_each(list,&cx8802_devlist) { | ||
603 | h = list_entry(list, struct cx8802_dev, devlist); | ||
604 | if (h != dev) | ||
605 | continue; | ||
606 | 599 | ||
607 | list_for_each(list2, &h->drvlist.devlist) { | 600 | list_for_each(list, &dev->drvlist) { |
608 | d = list_entry(list2, struct cx8802_driver, devlist); | 601 | d = list_entry(list, struct cx8802_driver, drvlist); |
609 | 602 | ||
610 | /* only unregister the correct driver type */ | 603 | if (d->type_id == btype) |
611 | if (d->type_id == btype) { | 604 | return d; |
612 | return d; | ||
613 | } | ||
614 | } | ||
615 | } | 605 | } |
616 | 606 | ||
617 | return NULL; | 607 | return NULL; |
@@ -717,7 +707,7 @@ int cx8802_register_driver(struct cx8802_driver *drv) | |||
717 | if (err == 0) { | 707 | if (err == 0) { |
718 | i++; | 708 | i++; |
719 | mutex_lock(&drv->core->lock); | 709 | mutex_lock(&drv->core->lock); |
720 | list_add_tail(&driver->devlist,&h->drvlist.devlist); | 710 | list_add_tail(&driver->drvlist, &h->drvlist); |
721 | mutex_unlock(&drv->core->lock); | 711 | mutex_unlock(&drv->core->lock); |
722 | } else { | 712 | } else { |
723 | printk(KERN_ERR | 713 | printk(KERN_ERR |
@@ -757,8 +747,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv) | |||
757 | h->pci->subsystem_device, h->core->board.name, | 747 | h->pci->subsystem_device, h->core->board.name, |
758 | h->core->boardnr); | 748 | h->core->boardnr); |
759 | 749 | ||
760 | list_for_each_safe(list2, q, &h->drvlist.devlist) { | 750 | list_for_each_safe(list2, q, &h->drvlist) { |
761 | d = list_entry(list2, struct cx8802_driver, devlist); | 751 | d = list_entry(list2, struct cx8802_driver, drvlist); |
762 | 752 | ||
763 | /* only unregister the correct driver type */ | 753 | /* only unregister the correct driver type */ |
764 | if (d->type_id != drv->type_id) | 754 | if (d->type_id != drv->type_id) |
@@ -772,7 +762,6 @@ int cx8802_unregister_driver(struct cx8802_driver *drv) | |||
772 | } else | 762 | } else |
773 | printk(KERN_ERR "%s/2: cx8802 driver remove " | 763 | printk(KERN_ERR "%s/2: cx8802 driver remove " |
774 | "failed (%d)\n", h->core->name, err); | 764 | "failed (%d)\n", h->core->name, err); |
775 | |||
776 | } | 765 | } |
777 | 766 | ||
778 | } | 767 | } |
@@ -810,7 +799,7 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, | |||
810 | if (err != 0) | 799 | if (err != 0) |
811 | goto fail_free; | 800 | goto fail_free; |
812 | 801 | ||
813 | INIT_LIST_HEAD(&dev->drvlist.devlist); | 802 | INIT_LIST_HEAD(&dev->drvlist); |
814 | list_add_tail(&dev->devlist,&cx8802_devlist); | 803 | list_add_tail(&dev->devlist,&cx8802_devlist); |
815 | 804 | ||
816 | /* Maintain a reference so cx88-video can query the 8802 device. */ | 805 | /* Maintain a reference so cx88-video can query the 8802 device. */ |
@@ -830,23 +819,32 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, | |||
830 | static void __devexit cx8802_remove(struct pci_dev *pci_dev) | 819 | static void __devexit cx8802_remove(struct pci_dev *pci_dev) |
831 | { | 820 | { |
832 | struct cx8802_dev *dev; | 821 | struct cx8802_dev *dev; |
833 | struct cx8802_driver *h; | ||
834 | struct list_head *list; | ||
835 | 822 | ||
836 | dev = pci_get_drvdata(pci_dev); | 823 | dev = pci_get_drvdata(pci_dev); |
837 | 824 | ||
838 | dprintk( 1, "%s\n", __FUNCTION__); | 825 | dprintk( 1, "%s\n", __FUNCTION__); |
839 | 826 | ||
840 | list_for_each(list,&dev->drvlist.devlist) { | 827 | if (!list_empty(&dev->drvlist)) { |
841 | h = list_entry(list, struct cx8802_driver, devlist); | 828 | struct list_head *list, *tmp; |
842 | dprintk( 1, " ->driver\n"); | 829 | struct cx8802_driver *drv; |
843 | if (h->remove == NULL) { | 830 | int err; |
844 | printk(KERN_ERR "%s .. skipping driver, no probe function\n", __FUNCTION__); | 831 | |
845 | continue; | 832 | printk(KERN_WARNING "%s/2: Trying to remove cx8802 driver " |
833 | "while cx8802 sub-drivers still loaded?!\n", | ||
834 | dev->core->name); | ||
835 | |||
836 | list_for_each_safe(list, tmp, &dev->drvlist) { | ||
837 | drv = list_entry(list, struct cx8802_driver, drvlist); | ||
838 | |||
839 | err = drv->remove(drv); | ||
840 | if (err == 0) { | ||
841 | mutex_lock(&drv->core->lock); | ||
842 | list_del(list); | ||
843 | mutex_unlock(&drv->core->lock); | ||
844 | } else | ||
845 | printk(KERN_ERR "%s/2: cx8802 driver remove " | ||
846 | "failed (%d)\n", dev->core->name, err); | ||
846 | } | 847 | } |
847 | printk(KERN_INFO "%s .. Removing driver type %d\n", __FUNCTION__, h->type_id); | ||
848 | cx8802_unregister_driver(h); | ||
849 | list_del(&dev->drvlist.devlist); | ||
850 | } | 848 | } |
851 | 849 | ||
852 | /* Destroy any 8802 reference. */ | 850 | /* Destroy any 8802 reference. */ |