diff options
Diffstat (limited to 'drivers/media/video/ov511.c')
-rw-r--r-- | drivers/media/video/ov511.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index 9af5532db142..08cfd3e4ae8a 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c | |||
@@ -112,6 +112,8 @@ static int framedrop = -1; | |||
112 | static int fastset; | 112 | static int fastset; |
113 | static int force_palette; | 113 | static int force_palette; |
114 | static int backlight; | 114 | static int backlight; |
115 | /* Bitmask marking allocated devices from 0 to OV511_MAX_UNIT_VIDEO */ | ||
116 | static unsigned long ov511_devused; | ||
115 | static int unit_video[OV511_MAX_UNIT_VIDEO]; | 117 | static int unit_video[OV511_MAX_UNIT_VIDEO]; |
116 | static int remove_zeros; | 118 | static int remove_zeros; |
117 | static int mirror; | 119 | static int mirror; |
@@ -5720,7 +5722,7 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
5720 | struct usb_device *dev = interface_to_usbdev(intf); | 5722 | struct usb_device *dev = interface_to_usbdev(intf); |
5721 | struct usb_interface_descriptor *idesc; | 5723 | struct usb_interface_descriptor *idesc; |
5722 | struct usb_ov511 *ov; | 5724 | struct usb_ov511 *ov; |
5723 | int i; | 5725 | int i, rc, nr; |
5724 | 5726 | ||
5725 | PDEBUG(1, "probing for device..."); | 5727 | PDEBUG(1, "probing for device..."); |
5726 | 5728 | ||
@@ -5845,33 +5847,41 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
5845 | ov->vdev->parent = &intf->dev; | 5847 | ov->vdev->parent = &intf->dev; |
5846 | video_set_drvdata(ov->vdev, ov); | 5848 | video_set_drvdata(ov->vdev, ov); |
5847 | 5849 | ||
5848 | for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) { | 5850 | mutex_lock(&ov->lock); |
5849 | /* Minor 0 cannot be specified; assume user wants autodetect */ | ||
5850 | if (unit_video[i] == 0) | ||
5851 | break; | ||
5852 | 5851 | ||
5853 | if (video_register_device(ov->vdev, VFL_TYPE_GRABBER, | 5852 | /* Check to see next free device and mark as used */ |
5854 | unit_video[i]) >= 0) { | 5853 | nr = find_first_zero_bit(&ov511_devused, OV511_MAX_UNIT_VIDEO); |
5855 | break; | 5854 | |
5856 | } | 5855 | /* Registers device */ |
5857 | } | 5856 | if (unit_video[nr] != 0) |
5857 | rc = video_register_device(ov->vdev, VFL_TYPE_GRABBER, | ||
5858 | unit_video[nr]); | ||
5859 | else | ||
5860 | rc = video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1); | ||
5858 | 5861 | ||
5859 | /* Use the next available one */ | 5862 | if (rc < 0) { |
5860 | if ((ov->vdev->minor == -1) && | ||
5861 | video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1) < 0) { | ||
5862 | err("video_register_device failed"); | 5863 | err("video_register_device failed"); |
5864 | mutex_unlock(&ov->lock); | ||
5863 | goto error; | 5865 | goto error; |
5864 | } | 5866 | } |
5865 | 5867 | ||
5868 | /* Mark device as used */ | ||
5869 | ov511_devused |= 1 << nr; | ||
5870 | ov->nr = nr; | ||
5871 | |||
5866 | dev_info(&intf->dev, "Device at %s registered to minor %d\n", | 5872 | dev_info(&intf->dev, "Device at %s registered to minor %d\n", |
5867 | ov->usb_path, ov->vdev->minor); | 5873 | ov->usb_path, ov->vdev->minor); |
5868 | 5874 | ||
5869 | usb_set_intfdata(intf, ov); | 5875 | usb_set_intfdata(intf, ov); |
5870 | if (ov_create_sysfs(ov->vdev)) { | 5876 | if (ov_create_sysfs(ov->vdev)) { |
5871 | err("ov_create_sysfs failed"); | 5877 | err("ov_create_sysfs failed"); |
5878 | ov511_devused &= ~(1 << nr); | ||
5879 | mutex_unlock(&ov->lock); | ||
5872 | goto error; | 5880 | goto error; |
5873 | } | 5881 | } |
5874 | 5882 | ||
5883 | mutex_lock(&ov->lock); | ||
5884 | |||
5875 | return 0; | 5885 | return 0; |
5876 | 5886 | ||
5877 | error: | 5887 | error: |
@@ -5906,10 +5916,16 @@ ov51x_disconnect(struct usb_interface *intf) | |||
5906 | 5916 | ||
5907 | PDEBUG(3, ""); | 5917 | PDEBUG(3, ""); |
5908 | 5918 | ||
5919 | mutex_lock(&ov->lock); | ||
5909 | usb_set_intfdata (intf, NULL); | 5920 | usb_set_intfdata (intf, NULL); |
5910 | 5921 | ||
5911 | if (!ov) | 5922 | if (!ov) { |
5923 | mutex_unlock(&ov->lock); | ||
5912 | return; | 5924 | return; |
5925 | } | ||
5926 | |||
5927 | /* Free device number */ | ||
5928 | ov511_devused &= ~(1 << ov->nr); | ||
5913 | 5929 | ||
5914 | if (ov->vdev) | 5930 | if (ov->vdev) |
5915 | video_unregister_device(ov->vdev); | 5931 | video_unregister_device(ov->vdev); |
@@ -5927,6 +5943,7 @@ ov51x_disconnect(struct usb_interface *intf) | |||
5927 | 5943 | ||
5928 | ov->streaming = 0; | 5944 | ov->streaming = 0; |
5929 | ov51x_unlink_isoc(ov); | 5945 | ov51x_unlink_isoc(ov); |
5946 | mutex_unlock(&ov->lock); | ||
5930 | 5947 | ||
5931 | ov->dev = NULL; | 5948 | ov->dev = NULL; |
5932 | 5949 | ||