The device information structure is currently copied field by field in the uvc_device structure. As we only have two fields at the moment this isn't much of an issue, but it prevents easy addition of new info fields. Fix this by storing the uvc_device_info pointer in the uvc_device structure. As a result the uvc_device meta_format field can be removed. The quirks field, however, needs to stay as it can be modified through a module parameter. As not all device have an information structure, we declare a global "NULL" info instance that is used as a fallback when the driver_info is empty.
Unified · Split
| @@ -2040,10 +2040,7 @@ static int uvc_register_chains(struct uvc_device *dev) · 2039 unmodified lines | ||
| 2040 | 2040 | * USB probe, disconnect, suspend and resume |
| 2041 | 2041 | */ |
| 2042 | 2042 | |
| 2043 | −struct uvc_device_info { | |
| 2044 | − u32 quirks; | |
| 2045 | − u32 meta_format; | |
| 2046 | −}; | |
| 2043 | +static const struct uvc_device_info uvc_quirk_none = { 0 }; | |
| 2047 | 2044 | |
| 2048 | 2045 | static int uvc_probe(struct usb_interface *intf, |
| 2049 | 2046 | const struct usb_device_id *id) |
| @@ -2052,7 +2049,6 @@ static int uvc_probe(struct usb_interface *intf, · 2 unmodified lines | ||
| 2052 | 2049 | struct uvc_device *dev; |
| 2053 | 2050 | const struct uvc_device_info *info = |
| 2054 | 2051 | (const struct uvc_device_info *)id->driver_info; |
| 2055 | − u32 quirks = info ? info->quirks : 0; | |
| 2056 | 2052 | int function; |
| 2057 | 2053 | int ret; |
| 2058 | 2054 | |
| @@ -2079,10 +2075,9 @@ static int uvc_probe(struct usb_interface *intf, · 20 unmodified lines | ||
| 2079 | 2075 | dev->udev = usb_get_dev(udev); |
| 2080 | 2076 | dev->intf = usb_get_intf(intf); |
| 2081 | 2077 | dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; |
| 2082 | − dev->quirks = (uvc_quirks_param == -1) | |
| 2083 | − ? quirks : uvc_quirks_param; | |
| 2084 | − if (info) | |
| 2085 | − dev->meta_format = info->meta_format; | |
| 2078 | + dev->info = info ? info : &uvc_quirk_none; | |
| 2079 | + dev->quirks = uvc_quirks_param == -1 | |
| 2080 | + ? dev->info->quirks : uvc_quirks_param; | |
| 2086 | 2081 | |
| 2087 | 2082 | if (udev->product != NULL) |
| 2088 | 2083 | strlcpy(dev->name, udev->product, sizeof(dev->name)); |
| @@ -2123,7 +2118,7 @@ static int uvc_probe(struct usb_interface *intf, · 34 unmodified lines | ||
| 2123 | 2118 | le16_to_cpu(udev->descriptor.idVendor), |
| 2124 | 2119 | le16_to_cpu(udev->descriptor.idProduct)); |
| 2125 | 2120 | |
| 2126 | − if (dev->quirks != quirks) { | |
| 2121 | + if (dev->quirks != dev->info->quirks) { | |
| 2127 | 2122 | uvc_printk(KERN_INFO, "Forcing device quirks to 0x%x by module " |
| 2128 | 2123 | "parameter for testing purpose.\n", dev->quirks); |
| 2129 | 2124 | uvc_printk(KERN_INFO, "Please report required quirks to the " |
| @@ -74,7 +74,8 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *fh, · 73 unmodified lines | ||
| 74 | 74 | |
| 75 | 75 | memset(fmt, 0, sizeof(*fmt)); |
| 76 | 76 | |
| 77 | − fmt->dataformat = fmeta == dev->meta_format ? fmeta : V4L2_META_FMT_UVC; | |
| 77 | + fmt->dataformat = fmeta == dev->info->meta_format | |
| 78 | + ? fmeta : V4L2_META_FMT_UVC; | |
| 78 | 79 | fmt->buffersize = UVC_METATADA_BUF_SIZE; |
| 79 | 80 | |
| 80 | 81 | return 0; |
| @@ -118,14 +119,14 @@ static int uvc_meta_v4l2_enum_formats(struct file *file, void *fh, · 37 unmodified lines | ||
| 118 | 119 | u32 index = fdesc->index; |
| 119 | 120 | |
| 120 | 121 | if (fdesc->type != vfh->vdev->queue->type || |
| 121 | − index > 1U || (index && !dev->meta_format)) | |
| 122 | + index > 1U || (index && !dev->info->meta_format)) | |
| 122 | 123 | return -EINVAL; |
| 123 | 124 | |
| 124 | 125 | memset(fdesc, 0, sizeof(*fdesc)); |
| 125 | 126 | |
| 126 | 127 | fdesc->type = vfh->vdev->queue->type; |
| 127 | 128 | fdesc->index = index; |
| 128 | − fdesc->pixelformat = index ? dev->meta_format : V4L2_META_FMT_UVC; | |
| 129 | + fdesc->pixelformat = index ? dev->info->meta_format : V4L2_META_FMT_UVC; | |
| 129 | 130 | |
| 130 | 131 | return 0; |
| 131 | 132 | } |
| @@ -572,15 +572,21 @@ struct uvc_streaming { · 571 unmodified lines | ||
| 572 | 572 | } clock; |
| 573 | 573 | }; |
| 574 | 574 | |
| 575 | +struct uvc_device_info { | |
| 576 | + u32 quirks; | |
| 577 | + u32 meta_format; | |
| 578 | +}; | |
| 579 | + | |
| 575 | 580 | struct uvc_device { |
| 576 | 581 | struct usb_device *udev; |
| 577 | 582 | struct usb_interface *intf; |
| 578 | 583 | unsigned long warnings; |
| 579 | 584 | u32 quirks; |
| 580 | − u32 meta_format; | |
| 581 | 585 | int intfnum; |
| 582 | 586 | char name[32]; |
| 583 | 587 | |
| 588 | + const struct uvc_device_info *info; | |
| 589 | + | |
| 584 | 590 | struct mutex lock; /* Protects users */ |
| 585 | 591 | unsigned int users; |
| 586 | 592 | atomic_t nmappings; |