diff options
Diffstat (limited to 'drivers/media/video/gspca/gspca.c')
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 45 |
1 files changed, 17 insertions, 28 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 1767991c1f4b..fe096e76e5c3 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -558,10 +558,12 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev) | |||
558 | gspca_dev->streaming = 0; | 558 | gspca_dev->streaming = 0; |
559 | atomic_set(&gspca_dev->nevent, 0); | 559 | atomic_set(&gspca_dev->nevent, 0); |
560 | if (gspca_dev->present) { | 560 | if (gspca_dev->present) { |
561 | gspca_dev->sd_desc->stopN(gspca_dev); | 561 | if (gspca_dev->sd_desc->stopN) |
562 | gspca_dev->sd_desc->stopN(gspca_dev); | ||
562 | destroy_urbs(gspca_dev); | 563 | destroy_urbs(gspca_dev); |
563 | gspca_set_alt0(gspca_dev); | 564 | gspca_set_alt0(gspca_dev); |
564 | gspca_dev->sd_desc->stop0(gspca_dev); | 565 | if (gspca_dev->sd_desc->stop0) |
566 | gspca_dev->sd_desc->stop0(gspca_dev); | ||
565 | PDEBUG(D_STREAM, "stream off OK"); | 567 | PDEBUG(D_STREAM, "stream off OK"); |
566 | } | 568 | } |
567 | } | 569 | } |
@@ -770,19 +772,7 @@ static int dev_open(struct inode *inode, struct file *file) | |||
770 | goto out; | 772 | goto out; |
771 | } | 773 | } |
772 | 774 | ||
773 | /* if not done yet, initialize the sensor */ | 775 | if (gspca_dev->users > 4) { /* (arbitrary value) */ |
774 | if (gspca_dev->users == 0) { | ||
775 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { | ||
776 | ret = -ERESTARTSYS; | ||
777 | goto out; | ||
778 | } | ||
779 | ret = gspca_dev->sd_desc->open(gspca_dev); | ||
780 | mutex_unlock(&gspca_dev->usb_lock); | ||
781 | if (ret != 0) { | ||
782 | PDEBUG(D_ERR|D_CONF, "init device failed %d", ret); | ||
783 | goto out; | ||
784 | } | ||
785 | } else if (gspca_dev->users > 4) { /* (arbitrary value) */ | ||
786 | ret = -EBUSY; | 776 | ret = -EBUSY; |
787 | goto out; | 777 | goto out; |
788 | } | 778 | } |
@@ -795,6 +785,7 @@ static int dev_open(struct inode *inode, struct file *file) | |||
795 | else | 785 | else |
796 | gspca_dev->vdev.debug &= ~3; | 786 | gspca_dev->vdev.debug &= ~3; |
797 | #endif | 787 | #endif |
788 | ret = 0; | ||
798 | out: | 789 | out: |
799 | mutex_unlock(&gspca_dev->queue_lock); | 790 | mutex_unlock(&gspca_dev->queue_lock); |
800 | if (ret != 0) | 791 | if (ret != 0) |
@@ -815,11 +806,6 @@ static int dev_close(struct inode *inode, struct file *file) | |||
815 | 806 | ||
816 | /* if the file did the capture, free the streaming resources */ | 807 | /* if the file did the capture, free the streaming resources */ |
817 | if (gspca_dev->capt_file == file) { | 808 | if (gspca_dev->capt_file == file) { |
818 | mutex_lock(&gspca_dev->usb_lock); | ||
819 | if (gspca_dev->streaming) | ||
820 | gspca_stream_off(gspca_dev); | ||
821 | gspca_dev->sd_desc->close(gspca_dev); | ||
822 | mutex_unlock(&gspca_dev->usb_lock); | ||
823 | frame_free(gspca_dev); | 809 | frame_free(gspca_dev); |
824 | gspca_dev->capt_file = NULL; | 810 | gspca_dev->capt_file = NULL; |
825 | gspca_dev->memory = GSPCA_MEMORY_NO; | 811 | gspca_dev->memory = GSPCA_MEMORY_NO; |
@@ -1747,10 +1733,13 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
1747 | /* gspca_dev->users = 0; (done by kzalloc) */ | 1733 | /* gspca_dev->users = 0; (done by kzalloc) */ |
1748 | gspca_dev->nbufread = 2; | 1734 | gspca_dev->nbufread = 2; |
1749 | 1735 | ||
1750 | /* configure the subdriver */ | 1736 | /* configure the subdriver and initialize the USB device */ |
1751 | ret = gspca_dev->sd_desc->config(gspca_dev, id); | 1737 | ret = gspca_dev->sd_desc->config(gspca_dev, id); |
1752 | if (ret < 0) | 1738 | if (ret < 0) |
1753 | goto out; | 1739 | goto out; |
1740 | ret = gspca_dev->sd_desc->init(gspca_dev); | ||
1741 | if (ret < 0) | ||
1742 | goto out; | ||
1754 | ret = gspca_set_alt0(gspca_dev); | 1743 | ret = gspca_set_alt0(gspca_dev); |
1755 | if (ret < 0) | 1744 | if (ret < 0) |
1756 | goto out; | 1745 | goto out; |
@@ -1825,10 +1814,12 @@ int gspca_suspend(struct usb_interface *intf, pm_message_t message) | |||
1825 | if (!gspca_dev->streaming) | 1814 | if (!gspca_dev->streaming) |
1826 | return 0; | 1815 | return 0; |
1827 | gspca_dev->frozen = 1; /* avoid urb error messages */ | 1816 | gspca_dev->frozen = 1; /* avoid urb error messages */ |
1828 | gspca_dev->sd_desc->stopN(gspca_dev); | 1817 | if (gspca_dev->sd_desc->stopN) |
1818 | gspca_dev->sd_desc->stopN(gspca_dev); | ||
1829 | destroy_urbs(gspca_dev); | 1819 | destroy_urbs(gspca_dev); |
1830 | gspca_set_alt0(gspca_dev); | 1820 | gspca_set_alt0(gspca_dev); |
1831 | gspca_dev->sd_desc->stop0(gspca_dev); | 1821 | if (gspca_dev->sd_desc->stop0) |
1822 | gspca_dev->sd_desc->stop0(gspca_dev); | ||
1832 | return 0; | 1823 | return 0; |
1833 | } | 1824 | } |
1834 | EXPORT_SYMBOL(gspca_suspend); | 1825 | EXPORT_SYMBOL(gspca_suspend); |
@@ -1838,11 +1829,9 @@ int gspca_resume(struct usb_interface *intf) | |||
1838 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); | 1829 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); |
1839 | 1830 | ||
1840 | gspca_dev->frozen = 0; | 1831 | gspca_dev->frozen = 0; |
1841 | if (gspca_dev->users != 0) { | 1832 | gspca_dev->sd_desc->init(gspca_dev); |
1842 | gspca_dev->sd_desc->open(gspca_dev); | 1833 | if (gspca_dev->streaming) |
1843 | if (gspca_dev->streaming) | 1834 | return gspca_init_transfer(gspca_dev); |
1844 | return gspca_init_transfer(gspca_dev); | ||
1845 | } | ||
1846 | return 0; | 1835 | return 0; |
1847 | } | 1836 | } |
1848 | EXPORT_SYMBOL(gspca_resume); | 1837 | EXPORT_SYMBOL(gspca_resume); |