aboutsummaryrefslogtreecommitdiffstats
path: root/usb
diff options
Diffstat (limited to 'usb')
-rw-r--r--usb/revert-usb-adding-support-for-htc-smartphones-to-ipaq.patch35
-rw-r--r--usb/usb-add-a-serial-number-parameter-to-g_file_storage-module.patch149
-rw-r--r--usb/usb-conexant-fixed-spacing-and-brace-coding-style-issues.patch66
-rw-r--r--usb/usb-ehci-ehci-1.1-addendum-basic-lpm-feature-support.patch243
-rw-r--r--usb/usb-ehci-ehci-1.1-addendum-enable-per-port-change-detect-bits.patch104
-rw-r--r--usb/usb-ehci-ehci-1.1-addendum-preparation.patch323
-rw-r--r--usb/usb-gadget-langwell_udc.c-printk-needs-a-unsigned-long-long-cast-for-a-dma_t.patch31
-rw-r--r--usb/usb-option-remove-duplicate-amoi_vendor_id.patch41
-rw-r--r--usb/usb-throw-away-custom-hex-digit-methods.patch81
-rw-r--r--usb/usb-uvc-move-constants-and-structures-definitions-to-linux-usb-video.h.patch1044
10 files changed, 2117 insertions, 0 deletions
diff --git a/usb/revert-usb-adding-support-for-htc-smartphones-to-ipaq.patch b/usb/revert-usb-adding-support-for-htc-smartphones-to-ipaq.patch
new file mode 100644
index 00000000000000..840cce4f42565f
--- /dev/null
+++ b/usb/revert-usb-adding-support-for-htc-smartphones-to-ipaq.patch
@@ -0,0 +1,35 @@
+From leann.ogasawara@canonical.com Wed Jun 16 13:29:49 2010
+From: Leann Ogasawara <leann.ogasawara@canonical.com>
+Date: Thu, 10 Jun 2010 15:49:24 -0700
+Subject: Revert "USB: Adding support for HTC Smartphones to ipaq"
+To: gregkh <gregkh@suse.de>
+Cc: linux-usb <linux-usb@vger.kernel.org>
+Message-ID: <1276210164.1221.3656.camel@emiko>
+
+
+ipaq already had this device id defined:
+
+{ USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC USB Modem */
+
+Revert the commit which adds the duplicate entry.
+
+This reverts commit 04cab1329336d4577d6638360c905e360934b425.
+
+Originally-by: Ben Collins <ben.collins@canonical.com>
+Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/ipaq.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/usb/serial/ipaq.c
++++ b/drivers/usb/serial/ipaq.c
+@@ -534,7 +534,6 @@ static struct usb_device_id ipaq_id_tabl
+ { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */
+ { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */
+ { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */
+- { USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC smartphone modems */
+ { } /* Terminating entry */
+ };
+
diff --git a/usb/usb-add-a-serial-number-parameter-to-g_file_storage-module.patch b/usb/usb-add-a-serial-number-parameter-to-g_file_storage-module.patch
new file mode 100644
index 00000000000000..5202a997ee66c7
--- /dev/null
+++ b/usb/usb-add-a-serial-number-parameter-to-g_file_storage-module.patch
@@ -0,0 +1,149 @@
+From yann.cantin@laposte.net Wed Jun 16 13:53:56 2010
+From: Yann Cantin <yann.cantin@laposte.net>
+Date: Sat, 5 Jun 2010 23:06:31 +0200
+Subject: USB: Add a serial number parameter to g_file_storage module
+To: dbrownell@users.sourceforge.net
+Cc: linux-usb@vger.kernel.org, Yann Cantin <yann.cantin@laposte.net>
+Message-ID: <1275771991-26392-1-git-send-email-yann.cantin@laposte.net>
+
+
+This patch add a serial number parameter to the g_file_storage
+module. There's validity checks against the string passed to comply
+with the specs.
+
+Signed-off-by: Yann Cantin <yann.cantin@laposte.net>
+Cc: MichaƂ Nazarewicz <m.nazarewicz@samsung.com>
+Cc: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/file_storage.c | 69 +++++++++++++++++++++++++++++++-------
+ 1 file changed, 58 insertions(+), 11 deletions(-)
+
+--- a/drivers/usb/gadget/file_storage.c
++++ b/drivers/usb/gadget/file_storage.c
+@@ -56,7 +56,7 @@
+ * following protocols: RBC (0x01), ATAPI or SFF-8020i (0x02), QIC-157 (0c03),
+ * UFI (0x04), SFF-8070i (0x05), and transparent SCSI (0x06), selected by
+ * the optional "protocol" module parameter. In addition, the default
+- * Vendor ID, Product ID, and release number can be overridden.
++ * Vendor ID, Product ID, release number and serial number can be overridden.
+ *
+ * There is support for multiple logical units (LUNs), each of which has
+ * its own backing file. The number of LUNs can be set using the optional
+@@ -106,6 +106,7 @@
+ * vendor=0xVVVV Default 0x0525 (NetChip), USB Vendor ID
+ * product=0xPPPP Default 0xa4a5 (FSG), USB Product ID
+ * release=0xRRRR Override the USB release number (bcdDevice)
++ * serial=HHHH... Override serial number (string of hex chars)
+ * buflen=N Default N=16384, buffer size used (will be
+ * rounded down to a multiple of
+ * PAGE_CACHE_SIZE)
+@@ -270,6 +271,8 @@
+
+ #define DRIVER_DESC "File-backed Storage Gadget"
+ #define DRIVER_NAME "g_file_storage"
++/* DRIVER_VERSION must be at least 6 characters long, as it is used
++ * to generate a fallback serial number. */
+ #define DRIVER_VERSION "20 November 2008"
+
+ static char fsg_string_manufacturer[64];
+@@ -314,6 +317,7 @@ static struct {
+ unsigned short vendor;
+ unsigned short product;
+ unsigned short release;
++ char *serial_parm;
+ unsigned int buflen;
+
+ int transport_type;
+@@ -374,6 +378,9 @@ MODULE_PARM_DESC(product, "USB Product I
+ module_param_named(release, mod_data.release, ushort, S_IRUGO);
+ MODULE_PARM_DESC(release, "USB release number");
+
++module_param_named(serial, mod_data.serial_parm, charp, S_IRUGO);
++MODULE_PARM_DESC(serial, "USB serial number");
++
+ module_param_named(buflen, mod_data.buflen, uint, S_IRUGO);
+ MODULE_PARM_DESC(buflen, "I/O buffer size");
+
+@@ -3197,6 +3204,7 @@ static int __init check_parameters(struc
+ {
+ int prot;
+ int gcnum;
++ int i;
+
+ /* Store the default values */
+ mod_data.transport_type = USB_PR_BULK;
+@@ -3272,6 +3280,55 @@ static int __init check_parameters(struc
+ ERROR(fsg, "invalid buflen\n");
+ return -ETOOSMALL;
+ }
++
++ /* Serial string handling.
++ * On a real device, the serial string would be loaded
++ * from permanent storage. */
++ if (mod_data.serial_parm) {
++ const char *ch;
++ unsigned len = 0;
++
++ /* Sanity check :
++ * The CB[I] specification limits the serial string to
++ * 12 uppercase hexadecimal characters.
++ * BBB need at least 12 uppercase hexadecimal characters,
++ * with a maximum of 126. */
++ for (ch = mod_data.serial_parm; *ch; ++ch) {
++ ++len;
++ if ((*ch < '0' || *ch > '9') &&
++ (*ch < 'A' || *ch > 'F')) { /* not uppercase hex */
++ WARNING(fsg,
++ "Invalid serial string character: %c; "
++ "Failing back to default\n",
++ *ch);
++ goto fill_serial;
++ }
++ }
++ if (len > 126 ||
++ (mod_data.transport_type == USB_PR_BULK && len < 12) ||
++ (mod_data.transport_type != USB_PR_BULK && len > 12)) {
++ WARNING(fsg,
++ "Invalid serial string length; "
++ "Failing back to default\n");
++ goto fill_serial;
++ }
++ fsg_strings[FSG_STRING_SERIAL - 1].s = mod_data.serial_parm;
++ } else {
++fill_serial:
++ /* Serial number not specified or invalid, make our own.
++ * We just encode it from the driver version string,
++ * 12 characters to comply with both CB[I] and BBB spec.
++ * Warning : Two devices running the same kernel will have
++ * the same fallback serial number. */
++ for (i = 0; i < 12; i += 2) {
++ unsigned char c = DRIVER_VERSION[i / 2];
++
++ if (!c)
++ break;
++ sprintf(&fsg_string_serial[i], "%02X", c);
++ }
++ }
++
+ #endif /* CONFIG_USB_FILE_STORAGE_TEST */
+
+ return 0;
+@@ -3447,16 +3504,6 @@ static int __init fsg_bind(struct usb_ga
+ init_utsname()->sysname, init_utsname()->release,
+ gadget->name);
+
+- /* On a real device, serial[] would be loaded from permanent
+- * storage. We just encode it from the driver version string. */
+- for (i = 0; i < sizeof fsg_string_serial - 2; i += 2) {
+- unsigned char c = DRIVER_VERSION[i / 2];
+-
+- if (!c)
+- break;
+- sprintf(&fsg_string_serial[i], "%02X", c);
+- }
+-
+ fsg->thread_task = kthread_create(fsg_main_thread, fsg,
+ "file-storage-gadget");
+ if (IS_ERR(fsg->thread_task)) {
diff --git a/usb/usb-conexant-fixed-spacing-and-brace-coding-style-issues.patch b/usb/usb-conexant-fixed-spacing-and-brace-coding-style-issues.patch
new file mode 100644
index 00000000000000..59a8ad701cd57e
--- /dev/null
+++ b/usb/usb-conexant-fixed-spacing-and-brace-coding-style-issues.patch
@@ -0,0 +1,66 @@
+From nikai@nikai.net Wed Jun 16 13:49:22 2010
+From: Nicolas Kaiser <nikai@nikai.net>
+Date: Wed, 16 Jun 2010 18:56:05 +0200
+Subject: usb: conexant: fixed spacing and brace coding style issues
+To: Simon Arlott <cxacru@fire.lp0.eu>
+Cc: Greg Kroah-Hartman <gregkh@suse.de>, accessrunner-general@lists.sourceforge.net, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
+Message-ID: <20100616185605.00ce6f31@absol.kitzblitz>
+
+
+Fixed spacing and brace coding style issues.
+
+Signed-off-by: Nicolas Kaiser <nikai@nikai.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/atm/cxacru.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/atm/cxacru.c
++++ b/drivers/usb/atm/cxacru.c
+@@ -564,7 +564,7 @@ static void cxacru_timeout_kill(unsigned
+ }
+
+ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done,
+- int* actual_length)
++ int *actual_length)
+ {
+ struct timer_list timer;
+
+@@ -952,7 +952,7 @@ static int cxacru_fw(struct usb_device *
+ put_unaligned(cpu_to_le32(addr), (__le32 *)(buf + offb));
+ offb += 4;
+ addr += l;
+- if(l)
++ if (l)
+ memcpy(buf + offb, data + offd, l);
+ if (l < stride)
+ memset(buf + offb + l, 0, stride - l);
+@@ -967,7 +967,7 @@ static int cxacru_fw(struct usb_device *
+ }
+ offb = 0;
+ }
+- } while(offd < size);
++ } while (offd < size);
+ dbg("sent fw %#x", fw);
+
+ ret = 0;
+@@ -1043,8 +1043,7 @@ static void cxacru_upload_firmware(struc
+ if (instance->modem_type->boot_rom_patch) {
+ val = cpu_to_le32(BR_ADDR);
+ ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4);
+- }
+- else {
++ } else {
+ ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0);
+ }
+ if (ret) {
+@@ -1068,7 +1067,7 @@ static void cxacru_upload_firmware(struc
+ }
+
+ static int cxacru_find_firmware(struct cxacru_data *instance,
+- char* phase, const struct firmware **fw_p)
++ char *phase, const struct firmware **fw_p)
+ {
+ struct usbatm_data *usbatm = instance->usbatm;
+ struct device *dev = &usbatm->usb_intf->dev;
diff --git a/usb/usb-ehci-ehci-1.1-addendum-basic-lpm-feature-support.patch b/usb/usb-ehci-ehci-1.1-addendum-basic-lpm-feature-support.patch
new file mode 100644
index 00000000000000..95fac8396679ba
--- /dev/null
+++ b/usb/usb-ehci-ehci-1.1-addendum-basic-lpm-feature-support.patch
@@ -0,0 +1,243 @@
+From alek.du@intel.com Wed Jun 16 13:28:26 2010
+From: Alek Du <alek.du@intel.com>
+Date: Fri, 4 Jun 2010 15:47:55 +0800
+Subject: USB: EHCI: EHCI 1.1 addendum: Basic LPM feature support
+To: greg@kroah.com
+Cc: david-b@pacbell.net, linux-usb@vger.kernel.org, oneukum@suse.de, Alek Du <alek.du@intel.com>, Jacob Pan <jacob.jun.pan@intel.com>
+Message-ID: <1275637676-24880-3-git-send-email-alek.du@intel.com>
+
+
+From: Alek Du <alek.du@intel.com>
+
+With this patch, the LPM capable EHCI host controller can put device
+into L1 sleep state which is a mode that can enter/exit quickly, and
+reduce power consumption.
+
+Signed-off-by: Jacob Pan <jacob.jun.pan@intel.com>
+Signed-off-by: Alek Du <alek.du@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/hub.c | 4 +-
+ drivers/usb/host/ehci-hcd.c | 17 +++++++++
+ drivers/usb/host/ehci-hub.c | 5 ++
+ drivers/usb/host/ehci-lpm.c | 83 ++++++++++++++++++++++++++++++++++++++++++++
+ drivers/usb/host/ehci-pci.c | 21 +++++++++++
+ drivers/usb/host/ehci.h | 2 -
+ include/linux/usb/hcd.h | 4 ++
+ 7 files changed, 134 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2878,7 +2878,9 @@ hub_port_init (struct usb_hub *hub, stru
+ }
+
+ retval = 0;
+-
++ /* notify HCD that we have a device connected and addressed */
++ if (hcd->driver->update_device)
++ hcd->driver->update_device(hcd, udev);
+ fail:
+ if (retval) {
+ hub_port_disable(hub, port1, 0);
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -100,6 +100,11 @@ static int ignore_oc = 0;
+ module_param (ignore_oc, bool, S_IRUGO);
+ MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications");
+
++/* for link power management(LPM) feature */
++static unsigned int hird;
++module_param(hird, int, S_IRUGO);
++MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us\n");
++
+ #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
+
+ /*-------------------------------------------------------------------------*/
+@@ -304,6 +309,7 @@ static void end_unlink_async(struct ehci
+ static void ehci_work(struct ehci_hcd *ehci);
+
+ #include "ehci-hub.c"
++#include "ehci-lpm.c"
+ #include "ehci-mem.c"
+ #include "ehci-q.c"
+ #include "ehci-sched.c"
+@@ -603,6 +609,17 @@ static int ehci_init(struct usb_hcd *hcd
+ default: BUG();
+ }
+ }
++ if (HCC_LPM(hcc_params)) {
++ /* support link power management EHCI 1.1 addendum */
++ ehci_dbg(ehci, "support lpm\n");
++ ehci->has_lpm = 1;
++ if (hird > 0xf) {
++ ehci_dbg(ehci, "hird %d invalid, use default 0",
++ hird);
++ hird = 0;
++ }
++ temp |= hird << 24;
++ }
+ ehci->command = temp;
+
+ /* Accept arbitrarily long scatter-gather lists */
+--- a/drivers/usb/host/ehci-hub.c
++++ b/drivers/usb/host/ehci-hub.c
+@@ -790,6 +790,11 @@ static int ehci_hub_control (
+ status_reg);
+ break;
+ case USB_PORT_FEAT_C_CONNECTION:
++ if (ehci->has_lpm) {
++ /* clear PORTSC bits on disconnect */
++ temp &= ~PORT_LPM;
++ temp &= ~PORT_DEV_ADDR;
++ }
+ ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_CSC,
+ status_reg);
+ break;
+--- /dev/null
++++ b/drivers/usb/host/ehci-lpm.c
+@@ -0,0 +1,83 @@
++/* ehci-lpm.c EHCI HCD LPM support code
++ * Copyright (c) 2008 - 2010, Intel Corporation.
++ * Author: Jacob Pan <jacob.jun.pan@intel.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++*/
++
++/* this file is part of ehci-hcd.c */
++static int ehci_lpm_set_da(struct ehci_hcd *ehci, int dev_addr, int port_num)
++{
++ u32 __iomem portsc;
++
++ ehci_dbg(ehci, "set dev address %d for port %d\n", dev_addr, port_num);
++ if (port_num > HCS_N_PORTS(ehci->hcs_params)) {
++ ehci_dbg(ehci, "invalid port number %d\n", port_num);
++ return -ENODEV;
++ }
++ portsc = ehci_readl(ehci, &ehci->regs->port_status[port_num-1]);
++ portsc &= ~PORT_DEV_ADDR;
++ portsc |= dev_addr<<25;
++ ehci_writel(ehci, portsc, &ehci->regs->port_status[port_num-1]);
++ return 0;
++}
++
++/*
++ * this function is used to check if the device support LPM
++ * if yes, mark the PORTSC register with PORT_LPM bit
++ */
++static int ehci_lpm_check(struct ehci_hcd *ehci, int port)
++{
++ u32 __iomem *portsc ;
++ u32 val32;
++ int retval;
++
++ portsc = &ehci->regs->port_status[port-1];
++ val32 = ehci_readl(ehci, portsc);
++ if (!(val32 & PORT_DEV_ADDR)) {
++ ehci_dbg(ehci, "LPM: no device attached\n");
++ return -ENODEV;
++ }
++ val32 |= PORT_LPM;
++ ehci_writel(ehci, val32, portsc);
++ msleep(5);
++ val32 |= PORT_SUSPEND;
++ ehci_dbg(ehci, "Sending LPM 0x%08x to port %d\n", val32, port);
++ ehci_writel(ehci, val32, portsc);
++ /* wait for ACK */
++ msleep(10);
++ retval = handshake(ehci, &ehci->regs->port_status[port-1], PORT_SSTS,
++ PORTSC_SUSPEND_STS_ACK, 125);
++ dbg_port(ehci, "LPM", port, val32);
++ if (retval != -ETIMEDOUT) {
++ ehci_dbg(ehci, "LPM: device ACK for LPM\n");
++ val32 |= PORT_LPM;
++ /*
++ * now device should be in L1 sleep, let's wake up the device
++ * so that we can complete enumeration.
++ */
++ ehci_writel(ehci, val32, portsc);
++ msleep(10);
++ val32 |= PORT_RESUME;
++ ehci_writel(ehci, val32, portsc);
++ } else {
++ ehci_dbg(ehci, "LPM: device does not ACK, disable LPM %d\n",
++ retval);
++ val32 &= ~PORT_LPM;
++ retval = -ETIMEDOUT;
++ ehci_writel(ehci, val32, portsc);
++ }
++
++ return retval;
++}
+--- a/drivers/usb/host/ehci-pci.c
++++ b/drivers/usb/host/ehci-pci.c
+@@ -361,6 +361,22 @@ static int ehci_pci_resume(struct usb_hc
+ }
+ #endif
+
++static int ehci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
++{
++ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
++ int rc = 0;
++
++ if (!udev->parent) /* udev is root hub itself, impossible */
++ rc = -1;
++ /* we only support lpm device connected to root hub yet */
++ if (ehci->has_lpm && !udev->parent->parent) {
++ rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum);
++ if (!rc)
++ rc = ehci_lpm_check(ehci, udev->portnum);
++ }
++ return rc;
++}
++
+ static const struct hc_driver ehci_pci_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "EHCI Host Controller",
+@@ -407,6 +423,11 @@ static const struct hc_driver ehci_pci_h
+ .relinquish_port = ehci_relinquish_port,
+ .port_handed_over = ehci_port_handed_over,
+
++ /*
++ * call back when device connected and addressed
++ */
++ .update_device = ehci_update_device,
++
+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+ };
+
+--- a/drivers/usb/host/ehci.h
++++ b/drivers/usb/host/ehci.h
+@@ -140,7 +140,7 @@ struct ehci_hcd { /* one per controlle
+ #define OHCI_HCCTRL_LEN 0x4
+ __hc32 *ohci_hcctrl_reg;
+ unsigned has_hostpc:1;
+-
++ unsigned has_lpm:1; /* support link power management */
+ u8 sbrn; /* packed release number */
+
+ /* irq statistics */
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -300,6 +300,10 @@ struct hc_driver {
+ int (*update_hub_device)(struct usb_hcd *, struct usb_device *hdev,
+ struct usb_tt *tt, gfp_t mem_flags);
+ int (*reset_device)(struct usb_hcd *, struct usb_device *);
++ /* Notifies the HCD after a device is connected and its
++ * address is set
++ */
++ int (*update_device)(struct usb_hcd *, struct usb_device *);
+ };
+
+ extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
diff --git a/usb/usb-ehci-ehci-1.1-addendum-enable-per-port-change-detect-bits.patch b/usb/usb-ehci-ehci-1.1-addendum-enable-per-port-change-detect-bits.patch
new file mode 100644
index 00000000000000..2aa59fb010338c
--- /dev/null
+++ b/usb/usb-ehci-ehci-1.1-addendum-enable-per-port-change-detect-bits.patch
@@ -0,0 +1,104 @@
+From alek.du@intel.com Wed Jun 16 13:29:07 2010
+From: Alek Du <alek.du@intel.com>
+Date: Fri, 4 Jun 2010 15:47:56 +0800
+Subject: USB: EHCI: EHCI 1.1 addendum: Enable Per-port change detect bits
+To: greg@kroah.com
+Cc: david-b@pacbell.net, linux-usb@vger.kernel.org, oneukum@suse.de, Alek Du <alek.du@intel.com>
+Message-ID: <1275637676-24880-4-git-send-email-alek.du@intel.com>
+
+
+From: Alek Du <alek.du@intel.com>
+
+This patch will enable Per-port event feature defined in EHCI 1.1
+addendum. This feature addresses an issue where HCD is currently
+required to read and parse PORTSC for all enabled root hub ports. With
+this patch, the overhead will be reduced.
+
+Signed-off-by: Alek Du <alek.du@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-hcd.c | 19 +++++++++++++++++--
+ drivers/usb/host/ehci-hub.c | 9 +++++++++
+ drivers/usb/host/ehci.h | 1 +
+ 3 files changed, 27 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -583,6 +583,11 @@ static int ehci_init(struct usb_hcd *hcd
+ if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
+ log2_irq_thresh = 0;
+ temp = 1 << (16 + log2_irq_thresh);
++ if (HCC_PER_PORT_CHANGE_EVENT(hcc_params)) {
++ ehci->has_ppcd = 1;
++ ehci_dbg(ehci, "enable per-port change event\n");
++ temp |= CMD_PPCEE;
++ }
+ if (HCC_CANPARK(hcc_params)) {
+ /* HW default park == 3, on hardware that supports it (like
+ * NVidia and ALI silicon), maximizes throughput on the async
+@@ -781,6 +786,7 @@ static irqreturn_t ehci_irq (struct usb_
+ /* remote wakeup [4.3.1] */
+ if (status & STS_PCD) {
+ unsigned i = HCS_N_PORTS (ehci->hcs_params);
++ u32 ppcd = 0;
+
+ /* kick root hub later */
+ pcd_status = status;
+@@ -789,9 +795,18 @@ static irqreturn_t ehci_irq (struct usb_
+ if (!(cmd & CMD_RUN))
+ usb_hcd_resume_root_hub(hcd);
+
++ /* get per-port change detect bits */
++ if (ehci->has_ppcd)
++ ppcd = status >> 16;
++
+ while (i--) {
+- int pstatus = ehci_readl(ehci,
+- &ehci->regs->port_status [i]);
++ int pstatus;
++
++ /* leverage per-port change bits feature */
++ if (ehci->has_ppcd && !(ppcd & (1 << i)))
++ continue;
++ pstatus = ehci_readl(ehci,
++ &ehci->regs->port_status[i]);
+
+ if (pstatus & PORT_OWNER)
+ continue;
+--- a/drivers/usb/host/ehci-hub.c
++++ b/drivers/usb/host/ehci-hub.c
+@@ -603,6 +603,7 @@ ehci_hub_status_data (struct usb_hcd *hc
+ u32 mask;
+ int ports, i, retval = 1;
+ unsigned long flags;
++ u32 ppcd = 0;
+
+ /* if !USB_SUSPEND, root hub timers won't get shut down ... */
+ if (!HC_IS_RUNNING(hcd->state))
+@@ -632,7 +633,15 @@ ehci_hub_status_data (struct usb_hcd *hc
+
+ /* port N changes (bit N)? */
+ spin_lock_irqsave (&ehci->lock, flags);
++
++ /* get per-port change detect bits */
++ if (ehci->has_ppcd)
++ ppcd = ehci_readl(ehci, &ehci->regs->status) >> 16;
++
+ for (i = 0; i < ports; i++) {
++ /* leverage per-port change bits feature */
++ if (ehci->has_ppcd && !(ppcd & (1 << i)))
++ continue;
+ temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
+
+ /*
+--- a/drivers/usb/host/ehci.h
++++ b/drivers/usb/host/ehci.h
+@@ -141,6 +141,7 @@ struct ehci_hcd { /* one per controlle
+ __hc32 *ohci_hcctrl_reg;
+ unsigned has_hostpc:1;
+ unsigned has_lpm:1; /* support link power management */
++ unsigned has_ppcd:1; /* support per-port change bits */
+ u8 sbrn; /* packed release number */
+
+ /* irq statistics */
diff --git a/usb/usb-ehci-ehci-1.1-addendum-preparation.patch b/usb/usb-ehci-ehci-1.1-addendum-preparation.patch
new file mode 100644
index 00000000000000..21ad12d6232f20
--- /dev/null
+++ b/usb/usb-ehci-ehci-1.1-addendum-preparation.patch
@@ -0,0 +1,323 @@
+From alek.du@intel.com Wed Jun 16 13:27:54 2010
+From: Alek Du <alek.du@intel.com>
+Date: Fri, 4 Jun 2010 15:47:54 +0800
+Subject: USB: EHCI: EHCI 1.1 addendum: preparation
+To: greg@kroah.com
+Cc: david-b@pacbell.net, linux-usb@vger.kernel.org, oneukum@suse.de, Alek Du <alek.du@intel.com>, Jacob Pan <jacob.jun.pan@intel.com>
+Message-ID: <1275637676-24880-2-git-send-email-alek.du@intel.com>
+
+
+From: Alek Du <alek.du@intel.com>
+
+EHCI 1.1 addendum introduced several energy efficiency extensions for
+EHCI USB host controllers:
+1. LPM (link power management)
+2. Per-port change
+3. Shorter periodic frame list
+4. Hardware prefetching
+
+This patch is intended to define the HW bits and debug interface for
+EHCI 1.1 addendum. The LPM and Per-port change patches will be sent out
+after this patch.
+
+Signed-off-by: Jacob Pan <jacob.jun.pan@intel.com>
+Signed-off-by: Alek Du <alek.du@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-dbg.c | 144 ++++++++++++++++++++++++++++++++++++++++---
+ drivers/usb/host/ehci.h | 1
+ include/linux/usb/ehci_def.h | 23 ++++++
+ 3 files changed, 161 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/host/ehci-dbg.c
++++ b/drivers/usb/host/ehci-dbg.c
+@@ -98,13 +98,18 @@ static void dbg_hcc_params (struct ehci_
+ HCC_64BIT_ADDR(params) ? " 64 bit addr" : "");
+ } else {
+ ehci_dbg (ehci,
+- "%s hcc_params %04x thresh %d uframes %s%s%s\n",
++ "%s hcc_params %04x thresh %d uframes %s%s%s%s%s%s%s\n",
+ label,
+ params,
+ HCC_ISOC_THRES(params),
+ HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
+ HCC_CANPARK(params) ? " park" : "",
+- HCC_64BIT_ADDR(params) ? " 64 bit addr" : "");
++ HCC_64BIT_ADDR(params) ? " 64 bit addr" : "",
++ HCC_LPM(params) ? " LPM" : "",
++ HCC_PER_PORT_CHANGE_EVENT(params) ? " ppce" : "",
++ HCC_HW_PREFETCH(params) ? " hw prefetch" : "",
++ HCC_32FRAME_PERIODIC_LIST(params) ?
++ " 32 peridic list" : "");
+ }
+ }
+ #else
+@@ -191,8 +196,9 @@ static int __maybe_unused
+ dbg_status_buf (char *buf, unsigned len, const char *label, u32 status)
+ {
+ return scnprintf (buf, len,
+- "%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
++ "%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s%s",
+ label, label [0] ? " " : "", status,
++ (status & STS_PPCE_MASK) ? " PPCE" : "",
+ (status & STS_ASS) ? " Async" : "",
+ (status & STS_PSS) ? " Periodic" : "",
+ (status & STS_RECL) ? " Recl" : "",
+@@ -210,8 +216,9 @@ static int __maybe_unused
+ dbg_intr_buf (char *buf, unsigned len, const char *label, u32 enable)
+ {
+ return scnprintf (buf, len,
+- "%s%sintrenable %02x%s%s%s%s%s%s",
++ "%s%sintrenable %02x%s%s%s%s%s%s%s",
+ label, label [0] ? " " : "", enable,
++ (enable & STS_PPCE_MASK) ? " PPCE" : "",
+ (enable & STS_IAA) ? " IAA" : "",
+ (enable & STS_FATAL) ? " FATAL" : "",
+ (enable & STS_FLR) ? " FLR" : "",
+@@ -228,9 +235,15 @@ static int
+ dbg_command_buf (char *buf, unsigned len, const char *label, u32 command)
+ {
+ return scnprintf (buf, len,
+- "%s%scommand %06x %s=%d ithresh=%d%s%s%s%s period=%s%s %s",
++ "%s%scommand %07x %s%s%s%s%s%s=%d ithresh=%d%s%s%s%s "
++ "period=%s%s %s",
+ label, label [0] ? " " : "", command,
+- (command & CMD_PARK) ? "park" : "(park)",
++ (command & CMD_HIRD) ? " HIRD" : "",
++ (command & CMD_PPCEE) ? " PPCEE" : "",
++ (command & CMD_FSP) ? " FSP" : "",
++ (command & CMD_ASPE) ? " ASPE" : "",
++ (command & CMD_PSPE) ? " PSPE" : "",
++ (command & CMD_PARK) ? " park" : "(park)",
+ CMD_PARK_CNT (command),
+ (command >> 16) & 0x3f,
+ (command & CMD_LRESET) ? " LReset" : "",
+@@ -257,11 +270,22 @@ dbg_port_buf (char *buf, unsigned len, c
+ }
+
+ return scnprintf (buf, len,
+- "%s%sport %d status %06x%s%s sig=%s%s%s%s%s%s%s%s%s%s",
++ "%s%sport:%d status %06x %d %s%s%s%s%s%s "
++ "sig=%s%s%s%s%s%s%s%s%s%s%s",
+ label, label [0] ? " " : "", port, status,
++ status>>25,/*device address */
++ (status & PORT_SSTS)>>23 == PORTSC_SUSPEND_STS_ACK ?
++ " ACK" : "",
++ (status & PORT_SSTS)>>23 == PORTSC_SUSPEND_STS_NYET ?
++ " NYET" : "",
++ (status & PORT_SSTS)>>23 == PORTSC_SUSPEND_STS_STALL ?
++ " STALL" : "",
++ (status & PORT_SSTS)>>23 == PORTSC_SUSPEND_STS_ERR ?
++ " ERR" : "",
+ (status & PORT_POWER) ? " POWER" : "",
+ (status & PORT_OWNER) ? " OWNER" : "",
+ sig,
++ (status & PORT_LPM) ? " LPM" : "",
+ (status & PORT_RESET) ? " RESET" : "",
+ (status & PORT_SUSPEND) ? " SUSPEND" : "",
+ (status & PORT_RESUME) ? " RESUME" : "",
+@@ -330,6 +354,13 @@ static int debug_async_open(struct inode
+ static int debug_periodic_open(struct inode *, struct file *);
+ static int debug_registers_open(struct inode *, struct file *);
+ static int debug_async_open(struct inode *, struct file *);
++static int debug_lpm_open(struct inode *, struct file *);
++static ssize_t debug_lpm_read(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos);
++static ssize_t debug_lpm_write(struct file *file, const char __user *buffer,
++ size_t count, loff_t *ppos);
++static int debug_lpm_close(struct inode *inode, struct file *file);
++
+ static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
+ static int debug_close(struct inode *, struct file *);
+
+@@ -351,6 +382,13 @@ static const struct file_operations debu
+ .read = debug_output,
+ .release = debug_close,
+ };
++static const struct file_operations debug_lpm_fops = {
++ .owner = THIS_MODULE,
++ .open = debug_lpm_open,
++ .read = debug_lpm_read,
++ .write = debug_lpm_write,
++ .release = debug_lpm_close,
++};
+
+ static struct dentry *ehci_debug_root;
+
+@@ -917,6 +955,94 @@ static int debug_registers_open(struct i
+ return file->private_data ? 0 : -ENOMEM;
+ }
+
++static int debug_lpm_open(struct inode *inode, struct file *file)
++{
++ file->private_data = inode->i_private;
++ return 0;
++}
++
++static int debug_lpm_close(struct inode *inode, struct file *file)
++{
++ return 0;
++}
++
++static ssize_t debug_lpm_read(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ /* TODO: show lpm stats */
++ return 0;
++}
++
++static ssize_t debug_lpm_write(struct file *file, const char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct usb_hcd *hcd;
++ struct ehci_hcd *ehci;
++ char buf[50];
++ size_t len;
++ u32 temp;
++ unsigned long port;
++ u32 __iomem *portsc ;
++ u32 params;
++
++ hcd = bus_to_hcd(file->private_data);
++ ehci = hcd_to_ehci(hcd);
++
++ len = min(count, sizeof(buf) - 1);
++ if (copy_from_user(buf, user_buf, len))
++ return -EFAULT;
++ buf[len] = '\0';
++ if (len > 0 && buf[len - 1] == '\n')
++ buf[len - 1] = '\0';
++
++ if (strncmp(buf, "enable", 5) == 0) {
++ if (strict_strtoul(buf + 7, 10, &port))
++ return -EINVAL;
++ params = ehci_readl(ehci, &ehci->caps->hcs_params);
++ if (port > HCS_N_PORTS(params)) {
++ ehci_dbg(ehci, "ERR: LPM on bad port %lu\n", port);
++ return -ENODEV;
++ }
++ portsc = &ehci->regs->port_status[port-1];
++ temp = ehci_readl(ehci, portsc);
++ if (!(temp & PORT_DEV_ADDR)) {
++ ehci_dbg(ehci, "LPM: no device attached\n");
++ return -ENODEV;
++ }
++ temp |= PORT_LPM;
++ ehci_writel(ehci, temp, portsc);
++ printk(KERN_INFO "force enable LPM for port %lu\n", port);
++ } else if (strncmp(buf, "hird=", 5) == 0) {
++ unsigned long hird;
++ if (strict_strtoul(buf + 5, 16, &hird))
++ return -EINVAL;
++ printk(KERN_INFO "setting hird %s %lu\n", buf + 6, hird);
++ temp = ehci_readl(ehci, &ehci->regs->command);
++ temp &= ~CMD_HIRD;
++ temp |= hird << 24;
++ ehci_writel(ehci, temp, &ehci->regs->command);
++ } else if (strncmp(buf, "disable", 7) == 0) {
++ if (strict_strtoul(buf + 8, 10, &port))
++ return -EINVAL;
++ params = ehci_readl(ehci, &ehci->caps->hcs_params);
++ if (port > HCS_N_PORTS(params)) {
++ ehci_dbg(ehci, "ERR: LPM off bad port %lu\n", port);
++ return -ENODEV;
++ }
++ portsc = &ehci->regs->port_status[port-1];
++ temp = ehci_readl(ehci, portsc);
++ if (!(temp & PORT_DEV_ADDR)) {
++ ehci_dbg(ehci, "ERR: no device attached\n");
++ return -ENODEV;
++ }
++ temp &= ~PORT_LPM;
++ ehci_writel(ehci, temp, portsc);
++ printk(KERN_INFO "disabled LPM for port %lu\n", port);
++ } else
++ return -EOPNOTSUPP;
++ return count;
++}
++
+ static inline void create_debug_files (struct ehci_hcd *ehci)
+ {
+ struct usb_bus *bus = &ehci_to_hcd(ehci)->self;
+@@ -940,6 +1066,10 @@ static inline void create_debug_files (s
+ ehci->debug_registers = debugfs_create_file("registers", S_IRUGO,
+ ehci->debug_dir, bus,
+ &debug_registers_fops);
++
++ ehci->debug_registers = debugfs_create_file("lpm", S_IRUGO|S_IWUGO,
++ ehci->debug_dir, bus,
++ &debug_lpm_fops);
+ if (!ehci->debug_registers)
+ goto registers_error;
+ return;
+--- a/drivers/usb/host/ehci.h
++++ b/drivers/usb/host/ehci.h
+@@ -157,6 +157,7 @@ struct ehci_hcd { /* one per controlle
+ struct dentry *debug_async;
+ struct dentry *debug_periodic;
+ struct dentry *debug_registers;
++ struct dentry *debug_lpm;
+ #endif
+ };
+
+--- a/include/linux/usb/ehci_def.h
++++ b/include/linux/usb/ehci_def.h
+@@ -39,6 +39,12 @@ struct ehci_caps {
+ #define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */
+
+ u32 hcc_params; /* HCCPARAMS - offset 0x8 */
++/* EHCI 1.1 addendum */
++#define HCC_32FRAME_PERIODIC_LIST(p) ((p)&(1 << 19))
++#define HCC_PER_PORT_CHANGE_EVENT(p) ((p)&(1 << 18))
++#define HCC_LPM(p) ((p)&(1 << 17))
++#define HCC_HW_PREFETCH(p) ((p)&(1 << 16))
++
+ #define HCC_EXT_CAPS(p) (((p)>>8)&0xff) /* for pci extended caps */
+ #define HCC_ISOC_CACHE(p) ((p)&(1 << 7)) /* true: can cache isoc frame */
+ #define HCC_ISOC_THRES(p) (((p)>>4)&0x7) /* bits 6:4, uframes cached */
+@@ -54,6 +60,13 @@ struct ehci_regs {
+
+ /* USBCMD: offset 0x00 */
+ u32 command;
++
++/* EHCI 1.1 addendum */
++#define CMD_HIRD (0xf<<24) /* host initiated resume duration */
++#define CMD_PPCEE (1<<15) /* per port change event enable */
++#define CMD_FSP (1<<14) /* fully synchronized prefetch */
++#define CMD_ASPE (1<<13) /* async schedule prefetch enable */
++#define CMD_PSPE (1<<12) /* periodic schedule prefetch enable */
+ /* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
+ #define CMD_PARK (1<<11) /* enable "park" on async qh */
+ #define CMD_PARK_CNT(c) (((c)>>8)&3) /* how many transfers to park for */
+@@ -67,6 +80,7 @@ struct ehci_regs {
+
+ /* USBSTS: offset 0x04 */
+ u32 status;
++#define STS_PPCE_MASK (0xff<<16) /* Per-Port change event 1-16 */
+ #define STS_ASS (1<<15) /* Async Schedule Status */
+ #define STS_PSS (1<<14) /* Periodic Schedule Status */
+ #define STS_RECL (1<<13) /* Reclamation */
+@@ -100,6 +114,14 @@ struct ehci_regs {
+
+ /* PORTSC: offset 0x44 */
+ u32 port_status[0]; /* up to N_PORTS */
++/* EHCI 1.1 addendum */
++#define PORTSC_SUSPEND_STS_ACK 0
++#define PORTSC_SUSPEND_STS_NYET 1
++#define PORTSC_SUSPEND_STS_STALL 2
++#define PORTSC_SUSPEND_STS_ERR 3
++
++#define PORT_DEV_ADDR (0x7f<<25) /* device address */
++#define PORT_SSTS (0x3<<23) /* suspend status */
+ /* 31:23 reserved */
+ #define PORT_WKOC_E (1<<22) /* wake on overcurrent (enable) */
+ #define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */
+@@ -115,6 +137,7 @@ struct ehci_regs {
+ #define PORT_USB11(x) (((x)&(3<<10)) == (1<<10)) /* USB 1.1 device */
+ /* 11:10 for detecting lowspeed devices (reset vs release ownership) */
+ /* 9 reserved */
++#define PORT_LPM (1<<9) /* LPM transaction */
+ #define PORT_RESET (1<<8) /* reset port */
+ #define PORT_SUSPEND (1<<7) /* suspend port */
+ #define PORT_RESUME (1<<6) /* resume it */
diff --git a/usb/usb-gadget-langwell_udc.c-printk-needs-a-unsigned-long-long-cast-for-a-dma_t.patch b/usb/usb-gadget-langwell_udc.c-printk-needs-a-unsigned-long-long-cast-for-a-dma_t.patch
new file mode 100644
index 00000000000000..154221af9463b0
--- /dev/null
+++ b/usb/usb-gadget-langwell_udc.c-printk-needs-a-unsigned-long-long-cast-for-a-dma_t.patch
@@ -0,0 +1,31 @@
+From joe@perches.com Wed Jun 16 13:30:08 2010
+From: Joe Perches <joe@perches.com>
+Date: Thu, 10 Jun 2010 19:20:43 -0700
+Subject: USB: gadget: langwell_udc.c: printk needs a (unsigned long long) cast for a dma_t
+To: Xiaochen Shen <xiaochen.shen@intel.com>
+Cc: David Brownell <dbrownell@users.sourceforge.net>, Greg Kroah-Hartman <gregkh@suse.de>, linux-usb <linux-usb@vger.kernel.org>, LKML <linux-kernel@vger.kernel.org>
+Message-ID: <1276222843.1556.438.camel@Joe-Laptop.home>
+
+
+Signed-off-by: Joe Perches <joe@perches.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/langwell_udc.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/gadget/langwell_udc.c
++++ b/drivers/usb/gadget/langwell_udc.c
+@@ -842,9 +842,9 @@ static int langwell_ep_queue(struct usb_
+ VDBG(dev, "req->mapped = 0\n");
+ }
+
+- DBG(dev, "%s queue req %p, len %u, buf %p, dma 0x%08x\n",
+- _ep->name,
+- _req, _req->length, _req->buf, _req->dma);
++ DBG(dev, "%s queue req %p, len %u, buf %p, dma 0x%08llx\n",
++ _ep->name,
++ _req, _req->length, _req->buf, (unsigned long long)_req->dma);
+
+ _req->status = -EINPROGRESS;
+ _req->actual = 0;
diff --git a/usb/usb-option-remove-duplicate-amoi_vendor_id.patch b/usb/usb-option-remove-duplicate-amoi_vendor_id.patch
new file mode 100644
index 00000000000000..2d86097f361c0a
--- /dev/null
+++ b/usb/usb-option-remove-duplicate-amoi_vendor_id.patch
@@ -0,0 +1,41 @@
+From leann.ogasawara@canonical.com Wed Jun 16 13:29:36 2010
+From: Leann Ogasawara <leann.ogasawara@canonical.com>
+Date: Thu, 10 Jun 2010 14:51:51 -0700
+Subject: USB: option: Remove duplicate AMOI_VENDOR_ID
+To: smurf@smurf.noris.de
+Cc: linux-usb@vger.kernel.org
+Message-ID: <1276206711.1221.3631.camel@emiko>
+
+
+AMOI_VENDOR_ID is defined twice. Remove the duplicate entry and move
+the AMOI_PRODUCT_9508 definition to be grouped with the other AMOI
+product definitions.
+
+Originally-by: Ben Collins <ben.collins@ubuntu.com>
+Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/option.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -206,6 +206,7 @@ static void option_instat_callback(struc
+ #define AMOI_PRODUCT_H01 0x0800
+ #define AMOI_PRODUCT_H01A 0x7002
+ #define AMOI_PRODUCT_H02 0x0802
++#define AMOI_PRODUCT_9508 0x0800
+
+ #define DELL_VENDOR_ID 0x413C
+
+@@ -263,9 +264,6 @@ static void option_instat_callback(struc
+ #define BANDRICH_PRODUCT_1011 0x1011
+ #define BANDRICH_PRODUCT_1012 0x1012
+
+-#define AMOI_VENDOR_ID 0x1614
+-#define AMOI_PRODUCT_9508 0x0800
+-
+ #define QUALCOMM_VENDOR_ID 0x05C6
+
+ #define CMOTECH_VENDOR_ID 0x16d8
diff --git a/usb/usb-throw-away-custom-hex-digit-methods.patch b/usb/usb-throw-away-custom-hex-digit-methods.patch
new file mode 100644
index 00000000000000..8738f9fba0667e
--- /dev/null
+++ b/usb/usb-throw-away-custom-hex-digit-methods.patch
@@ -0,0 +1,81 @@
+From andy.shevchenko@gmail.com Wed Jun 16 13:22:24 2010
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Tue, 15 Jun 2010 17:04:44 +0300
+Subject: usb: throw away custom hex digit methods
+To: linux-kernel@vger.kernel.org
+Cc: Andy Shevchenko <ext-andriy.shevchenko@nokia.com>, Greg Kroah-Hartman <gregkh@suse.de>, David Brownell <dbrownell@users.sourceforge.net>, linux-usb@vger.kernel.org
+Message-ID: <1276610684-26335-1-git-send-email-andy.shevchenko@gmail.com>
+
+
+From: Andy Shevchenko <ext-andriy.shevchenko@nokia.com>
+
+Recent kernel has common method to convert hex digit to its value.
+
+Signed-off-by: Andy Shevchenko <ext-andriy.shevchenko@nokia.com>
+Cc: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/atm/ueagle-atm.c | 5 +++--
+ drivers/usb/gadget/u_ether.c | 15 ++-------------
+ 2 files changed, 5 insertions(+), 15 deletions(-)
+
+--- a/drivers/usb/atm/ueagle-atm.c
++++ b/drivers/usb/atm/ueagle-atm.c
+@@ -67,6 +67,7 @@
+ #include <linux/mutex.h>
+ #include <linux/freezer.h>
+ #include <linux/slab.h>
++#include <linux/kernel.h>
+
+ #include <asm/unaligned.h>
+
+@@ -2429,7 +2430,6 @@ UEA_ATTR(firmid, 0);
+
+ /* Retrieve the device End System Identifier (MAC) */
+
+-#define htoi(x) (isdigit(x) ? x-'0' : toupper(x)-'A'+10)
+ static int uea_getesi(struct uea_softc *sc, u_char * esi)
+ {
+ unsigned char mac_str[2 * ETH_ALEN + 1];
+@@ -2440,7 +2440,8 @@ static int uea_getesi(struct uea_softc *
+ return 1;
+
+ for (i = 0; i < ETH_ALEN; i++)
+- esi[i] = htoi(mac_str[2 * i]) * 16 + htoi(mac_str[2 * i + 1]);
++ esi[i] = hex_to_bin(mac_str[2 * i]) * 16 +
++ hex_to_bin(mac_str[2 * i + 1]);
+
+ return 0;
+ }
+--- a/drivers/usb/gadget/u_ether.c
++++ b/drivers/usb/gadget/u_ether.c
+@@ -704,17 +704,6 @@ static char *host_addr;
+ module_param(host_addr, charp, S_IRUGO);
+ MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
+
+-
+-static u8 __init nibble(unsigned char c)
+-{
+- if (isdigit(c))
+- return c - '0';
+- c = toupper(c);
+- if (isxdigit(c))
+- return 10 + c - 'A';
+- return 0;
+-}
+-
+ static int get_ether_addr(const char *str, u8 *dev_addr)
+ {
+ if (str) {
+@@ -725,8 +714,8 @@ static int get_ether_addr(const char *st
+
+ if ((*str == '.') || (*str == ':'))
+ str++;
+- num = nibble(*str++) << 4;
+- num |= (nibble(*str++));
++ num = hex_to_bin(*str++) << 4;
++ num |= hex_to_bin(*str++);
+ dev_addr [i] = num;
+ }
+ if (is_valid_ether_addr(dev_addr))
diff --git a/usb/usb-uvc-move-constants-and-structures-definitions-to-linux-usb-video.h.patch b/usb/usb-uvc-move-constants-and-structures-definitions-to-linux-usb-video.h.patch
new file mode 100644
index 00000000000000..59c6f4834cb351
--- /dev/null
+++ b/usb/usb-uvc-move-constants-and-structures-definitions-to-linux-usb-video.h.patch
@@ -0,0 +1,1044 @@
+From laurent.pinchart@ideasonboard.com Wed Jun 16 13:25:39 2010
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Mon, 7 Jun 2010 13:09:47 +0200
+Subject: USB: uvc: Move constants and structures definitions to linux/usb/video.h
+To: linux-usb@vger.kernel.org
+Message-ID: <1275908987-5774-1-git-send-email-laurent.pinchart@ideasonboard.com>
+
+
+The UVC host and gadget drivers both define constants and structures in
+private header files. Move all those definitions to linux/usb/video.h
+where they can be shared by the two drivers (and be available for
+userspace applications).
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/uvc/uvcvideo.h | 19 -
+ drivers/usb/gadget/f_uvc.c | 16 -
+ drivers/usb/gadget/f_uvc.h | 352 --------------------------------
+ drivers/usb/gadget/uvc.h | 36 ---
+ drivers/usb/gadget/webcam.c | 24 +-
+ include/linux/usb/video.h | 397 +++++++++++++++++++++++++++++++++++++
+ 6 files changed, 418 insertions(+), 426 deletions(-)
+
+--- a/drivers/media/video/uvc/uvcvideo.h
++++ b/drivers/media/video/uvc/uvcvideo.h
+@@ -179,25 +179,6 @@ struct uvc_device;
+ /* TODO: Put the most frequently accessed fields at the beginning of
+ * structures to maximize cache efficiency.
+ */
+-struct uvc_streaming_control {
+- __u16 bmHint;
+- __u8 bFormatIndex;
+- __u8 bFrameIndex;
+- __u32 dwFrameInterval;
+- __u16 wKeyFrameRate;
+- __u16 wPFrameRate;
+- __u16 wCompQuality;
+- __u16 wCompWindowSize;
+- __u16 wDelay;
+- __u32 dwMaxVideoFrameSize;
+- __u32 dwMaxPayloadTransferSize;
+- __u32 dwClockFrequency;
+- __u8 bmFramingInfo;
+- __u8 bPreferedVersion;
+- __u8 bMinVersion;
+- __u8 bMaxVersion;
+-};
+-
+ struct uvc_menu_info {
+ __u32 value;
+ __u8 name[32];
+--- a/drivers/usb/gadget/f_uvc.c
++++ b/drivers/usb/gadget/f_uvc.c
+@@ -61,12 +61,12 @@ static struct usb_gadget_strings *uvc_fu
+ #define UVC_INTF_VIDEO_STREAMING 1
+
+ static struct usb_interface_assoc_descriptor uvc_iad __initdata = {
+- .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
++ .bLength = sizeof(uvc_iad),
+ .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
+ .bFirstInterface = 0,
+ .bInterfaceCount = 2,
+ .bFunctionClass = USB_CLASS_VIDEO,
+- .bFunctionSubClass = 0x03,
++ .bFunctionSubClass = UVC_SC_VIDEO_INTERFACE_COLLECTION,
+ .bFunctionProtocol = 0x00,
+ .iFunction = 0,
+ };
+@@ -78,7 +78,7 @@ static struct usb_interface_descriptor u
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+- .bInterfaceSubClass = 0x01,
++ .bInterfaceSubClass = UVC_SC_VIDEOCONTROL,
+ .bInterfaceProtocol = 0x00,
+ .iInterface = 0,
+ };
+@@ -106,7 +106,7 @@ static struct usb_interface_descriptor u
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 0,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+- .bInterfaceSubClass = 0x02,
++ .bInterfaceSubClass = UVC_SC_VIDEOSTREAMING,
+ .bInterfaceProtocol = 0x00,
+ .iInterface = 0,
+ };
+@@ -118,7 +118,7 @@ static struct usb_interface_descriptor u
+ .bAlternateSetting = 1,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+- .bInterfaceSubClass = 0x02,
++ .bInterfaceSubClass = UVC_SC_VIDEOSTREAMING,
+ .bInterfaceProtocol = 0x00,
+ .iInterface = 0,
+ };
+@@ -603,15 +603,15 @@ uvc_bind_config(struct usb_configuration
+
+ /* Validate the descriptors. */
+ if (control == NULL || control[0] == NULL ||
+- control[0]->bDescriptorSubType != UVC_DT_HEADER)
++ control[0]->bDescriptorSubType != UVC_VC_HEADER)
+ goto error;
+
+ if (fs_streaming == NULL || fs_streaming[0] == NULL ||
+- fs_streaming[0]->bDescriptorSubType != UVC_DT_INPUT_HEADER)
++ fs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER)
+ goto error;
+
+ if (hs_streaming == NULL || hs_streaming[0] == NULL ||
+- hs_streaming[0]->bDescriptorSubType != UVC_DT_INPUT_HEADER)
++ hs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER)
+ goto error;
+
+ uvc->desc.control = control;
+--- a/drivers/usb/gadget/f_uvc.h
++++ b/drivers/usb/gadget/f_uvc.h
+@@ -15,357 +15,7 @@
+ #define _F_UVC_H_
+
+ #include <linux/usb/composite.h>
+-
+-#define USB_CLASS_VIDEO_CONTROL 1
+-#define USB_CLASS_VIDEO_STREAMING 2
+-
+-struct uvc_descriptor_header {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+-} __attribute__ ((packed));
+-
+-struct uvc_header_descriptor {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u16 bcdUVC;
+- __u16 wTotalLength;
+- __u32 dwClockFrequency;
+- __u8 bInCollection;
+- __u8 baInterfaceNr[];
+-} __attribute__((__packed__));
+-
+-#define UVC_HEADER_DESCRIPTOR(n) uvc_header_descriptor_##n
+-
+-#define DECLARE_UVC_HEADER_DESCRIPTOR(n) \
+-struct UVC_HEADER_DESCRIPTOR(n) { \
+- __u8 bLength; \
+- __u8 bDescriptorType; \
+- __u8 bDescriptorSubType; \
+- __u16 bcdUVC; \
+- __u16 wTotalLength; \
+- __u32 dwClockFrequency; \
+- __u8 bInCollection; \
+- __u8 baInterfaceNr[n]; \
+-} __attribute__ ((packed))
+-
+-struct uvc_input_terminal_descriptor {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u8 bTerminalID;
+- __u16 wTerminalType;
+- __u8 bAssocTerminal;
+- __u8 iTerminal;
+-} __attribute__((__packed__));
+-
+-struct uvc_output_terminal_descriptor {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u8 bTerminalID;
+- __u16 wTerminalType;
+- __u8 bAssocTerminal;
+- __u8 bSourceID;
+- __u8 iTerminal;
+-} __attribute__((__packed__));
+-
+-struct uvc_camera_terminal_descriptor {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u8 bTerminalID;
+- __u16 wTerminalType;
+- __u8 bAssocTerminal;
+- __u8 iTerminal;
+- __u16 wObjectiveFocalLengthMin;
+- __u16 wObjectiveFocalLengthMax;
+- __u16 wOcularFocalLength;
+- __u8 bControlSize;
+- __u8 bmControls[3];
+-} __attribute__((__packed__));
+-
+-struct uvc_selector_unit_descriptor {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u8 bUnitID;
+- __u8 bNrInPins;
+- __u8 baSourceID[0];
+- __u8 iSelector;
+-} __attribute__((__packed__));
+-
+-#define UVC_SELECTOR_UNIT_DESCRIPTOR(n) \
+- uvc_selector_unit_descriptor_##n
+-
+-#define DECLARE_UVC_SELECTOR_UNIT_DESCRIPTOR(n) \
+-struct UVC_SELECTOR_UNIT_DESCRIPTOR(n) { \
+- __u8 bLength; \
+- __u8 bDescriptorType; \
+- __u8 bDescriptorSubType; \
+- __u8 bUnitID; \
+- __u8 bNrInPins; \
+- __u8 baSourceID[n]; \
+- __u8 iSelector; \
+-} __attribute__ ((packed))
+-
+-struct uvc_processing_unit_descriptor {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u8 bUnitID;
+- __u8 bSourceID;
+- __u16 wMaxMultiplier;
+- __u8 bControlSize;
+- __u8 bmControls[2];
+- __u8 iProcessing;
+-} __attribute__((__packed__));
+-
+-struct uvc_extension_unit_descriptor {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u8 bUnitID;
+- __u8 guidExtensionCode[16];
+- __u8 bNumControls;
+- __u8 bNrInPins;
+- __u8 baSourceID[0];
+- __u8 bControlSize;
+- __u8 bmControls[0];
+- __u8 iExtension;
+-} __attribute__((__packed__));
+-
+-#define UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) \
+- uvc_extension_unit_descriptor_##p_##n
+-
+-#define DECLARE_UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) \
+-struct UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) { \
+- __u8 bLength; \
+- __u8 bDescriptorType; \
+- __u8 bDescriptorSubType; \
+- __u8 bUnitID; \
+- __u8 guidExtensionCode[16]; \
+- __u8 bNumControls; \
+- __u8 bNrInPins; \
+- __u8 baSourceID[p]; \
+- __u8 bControlSize; \
+- __u8 bmControls[n]; \
+- __u8 iExtension; \
+-} __attribute__ ((packed))
+-
+-struct uvc_control_endpoint_descriptor {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u16 wMaxTransferSize;
+-} __attribute__((__packed__));
+-
+-#define UVC_DT_HEADER 1
+-#define UVC_DT_INPUT_TERMINAL 2
+-#define UVC_DT_OUTPUT_TERMINAL 3
+-#define UVC_DT_SELECTOR_UNIT 4
+-#define UVC_DT_PROCESSING_UNIT 5
+-#define UVC_DT_EXTENSION_UNIT 6
+-
+-#define UVC_DT_HEADER_SIZE(n) (12+(n))
+-#define UVC_DT_INPUT_TERMINAL_SIZE 8
+-#define UVC_DT_OUTPUT_TERMINAL_SIZE 9
+-#define UVC_DT_CAMERA_TERMINAL_SIZE(n) (15+(n))
+-#define UVC_DT_SELECTOR_UNIT_SIZE(n) (6+(n))
+-#define UVC_DT_PROCESSING_UNIT_SIZE(n) (9+(n))
+-#define UVC_DT_EXTENSION_UNIT_SIZE(p,n) (24+(p)+(n))
+-#define UVC_DT_CONTROL_ENDPOINT_SIZE 5
+-
+-struct uvc_input_header_descriptor {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u8 bNumFormats;
+- __u16 wTotalLength;
+- __u8 bEndpointAddress;
+- __u8 bmInfo;
+- __u8 bTerminalLink;
+- __u8 bStillCaptureMethod;
+- __u8 bTriggerSupport;
+- __u8 bTriggerUsage;
+- __u8 bControlSize;
+- __u8 bmaControls[];
+-} __attribute__((__packed__));
+-
+-#define UVC_INPUT_HEADER_DESCRIPTOR(n, p) \
+- uvc_input_header_descriptor_##n_##p
+-
+-#define DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(n, p) \
+-struct UVC_INPUT_HEADER_DESCRIPTOR(n, p) { \
+- __u8 bLength; \
+- __u8 bDescriptorType; \
+- __u8 bDescriptorSubType; \
+- __u8 bNumFormats; \
+- __u16 wTotalLength; \
+- __u8 bEndpointAddress; \
+- __u8 bmInfo; \
+- __u8 bTerminalLink; \
+- __u8 bStillCaptureMethod; \
+- __u8 bTriggerSupport; \
+- __u8 bTriggerUsage; \
+- __u8 bControlSize; \
+- __u8 bmaControls[p][n]; \
+-} __attribute__ ((packed))
+-
+-struct uvc_output_header_descriptor {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u8 bNumFormats;
+- __u16 wTotalLength;
+- __u8 bEndpointAddress;
+- __u8 bTerminalLink;
+- __u8 bControlSize;
+- __u8 bmaControls[];
+-} __attribute__((__packed__));
+-
+-#define UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) \
+- uvc_output_header_descriptor_##n_##p
+-
+-#define DECLARE_UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) \
+-struct UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) { \
+- __u8 bLength; \
+- __u8 bDescriptorType; \
+- __u8 bDescriptorSubType; \
+- __u8 bNumFormats; \
+- __u16 wTotalLength; \
+- __u8 bEndpointAddress; \
+- __u8 bTerminalLink; \
+- __u8 bControlSize; \
+- __u8 bmaControls[p][n]; \
+-} __attribute__ ((packed))
+-
+-struct uvc_format_uncompressed {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u8 bFormatIndex;
+- __u8 bNumFrameDescriptors;
+- __u8 guidFormat[16];
+- __u8 bBitsPerPixel;
+- __u8 bDefaultFrameIndex;
+- __u8 bAspectRatioX;
+- __u8 bAspectRatioY;
+- __u8 bmInterfaceFlags;
+- __u8 bCopyProtect;
+-} __attribute__((__packed__));
+-
+-struct uvc_frame_uncompressed {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u8 bFrameIndex;
+- __u8 bmCapabilities;
+- __u16 wWidth;
+- __u16 wHeight;
+- __u32 dwMinBitRate;
+- __u32 dwMaxBitRate;
+- __u32 dwMaxVideoFrameBufferSize;
+- __u32 dwDefaultFrameInterval;
+- __u8 bFrameIntervalType;
+- __u32 dwFrameInterval[];
+-} __attribute__((__packed__));
+-
+-#define UVC_FRAME_UNCOMPRESSED(n) \
+- uvc_frame_uncompressed_##n
+-
+-#define DECLARE_UVC_FRAME_UNCOMPRESSED(n) \
+-struct UVC_FRAME_UNCOMPRESSED(n) { \
+- __u8 bLength; \
+- __u8 bDescriptorType; \
+- __u8 bDescriptorSubType; \
+- __u8 bFrameIndex; \
+- __u8 bmCapabilities; \
+- __u16 wWidth; \
+- __u16 wHeight; \
+- __u32 dwMinBitRate; \
+- __u32 dwMaxBitRate; \
+- __u32 dwMaxVideoFrameBufferSize; \
+- __u32 dwDefaultFrameInterval; \
+- __u8 bFrameIntervalType; \
+- __u32 dwFrameInterval[n]; \
+-} __attribute__ ((packed))
+-
+-struct uvc_format_mjpeg {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u8 bFormatIndex;
+- __u8 bNumFrameDescriptors;
+- __u8 bmFlags;
+- __u8 bDefaultFrameIndex;
+- __u8 bAspectRatioX;
+- __u8 bAspectRatioY;
+- __u8 bmInterfaceFlags;
+- __u8 bCopyProtect;
+-} __attribute__((__packed__));
+-
+-struct uvc_frame_mjpeg {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u8 bFrameIndex;
+- __u8 bmCapabilities;
+- __u16 wWidth;
+- __u16 wHeight;
+- __u32 dwMinBitRate;
+- __u32 dwMaxBitRate;
+- __u32 dwMaxVideoFrameBufferSize;
+- __u32 dwDefaultFrameInterval;
+- __u8 bFrameIntervalType;
+- __u32 dwFrameInterval[];
+-} __attribute__((__packed__));
+-
+-#define UVC_FRAME_MJPEG(n) \
+- uvc_frame_mjpeg_##n
+-
+-#define DECLARE_UVC_FRAME_MJPEG(n) \
+-struct UVC_FRAME_MJPEG(n) { \
+- __u8 bLength; \
+- __u8 bDescriptorType; \
+- __u8 bDescriptorSubType; \
+- __u8 bFrameIndex; \
+- __u8 bmCapabilities; \
+- __u16 wWidth; \
+- __u16 wHeight; \
+- __u32 dwMinBitRate; \
+- __u32 dwMaxBitRate; \
+- __u32 dwMaxVideoFrameBufferSize; \
+- __u32 dwDefaultFrameInterval; \
+- __u8 bFrameIntervalType; \
+- __u32 dwFrameInterval[n]; \
+-} __attribute__ ((packed))
+-
+-struct uvc_color_matching_descriptor {
+- __u8 bLength;
+- __u8 bDescriptorType;
+- __u8 bDescriptorSubType;
+- __u8 bColorPrimaries;
+- __u8 bTransferCharacteristics;
+- __u8 bMatrixCoefficients;
+-} __attribute__((__packed__));
+-
+-#define UVC_DT_INPUT_HEADER 1
+-#define UVC_DT_OUTPUT_HEADER 2
+-#define UVC_DT_FORMAT_UNCOMPRESSED 4
+-#define UVC_DT_FRAME_UNCOMPRESSED 5
+-#define UVC_DT_FORMAT_MJPEG 6
+-#define UVC_DT_FRAME_MJPEG 7
+-#define UVC_DT_COLOR_MATCHING 13
+-
+-#define UVC_DT_INPUT_HEADER_SIZE(n, p) (13+(n*p))
+-#define UVC_DT_OUTPUT_HEADER_SIZE(n, p) (9+(n*p))
+-#define UVC_DT_FORMAT_UNCOMPRESSED_SIZE 27
+-#define UVC_DT_FRAME_UNCOMPRESSED_SIZE(n) (26+4*(n))
+-#define UVC_DT_FORMAT_MJPEG_SIZE 11
+-#define UVC_DT_FRAME_MJPEG_SIZE(n) (26+4*(n))
+-#define UVC_DT_COLOR_MATCHING_SIZE 6
++#include <linux/usb/video.h>
+
+ extern int uvc_bind_config(struct usb_configuration *c,
+ const struct uvc_descriptor_header * const *control,
+--- a/drivers/usb/gadget/uvc.h
++++ b/drivers/usb/gadget/uvc.h
+@@ -48,39 +48,6 @@ struct uvc_event
+ #define UVC_INTF_STREAMING 1
+
+ /* ------------------------------------------------------------------------
+- * UVC constants & structures
+- */
+-
+-/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
+-#define UVC_STREAM_EOH (1 << 7)
+-#define UVC_STREAM_ERR (1 << 6)
+-#define UVC_STREAM_STI (1 << 5)
+-#define UVC_STREAM_RES (1 << 4)
+-#define UVC_STREAM_SCR (1 << 3)
+-#define UVC_STREAM_PTS (1 << 2)
+-#define UVC_STREAM_EOF (1 << 1)
+-#define UVC_STREAM_FID (1 << 0)
+-
+-struct uvc_streaming_control {
+- __u16 bmHint;
+- __u8 bFormatIndex;
+- __u8 bFrameIndex;
+- __u32 dwFrameInterval;
+- __u16 wKeyFrameRate;
+- __u16 wPFrameRate;
+- __u16 wCompQuality;
+- __u16 wCompWindowSize;
+- __u16 wDelay;
+- __u32 dwMaxVideoFrameSize;
+- __u32 dwMaxPayloadTransferSize;
+- __u32 dwClockFrequency;
+- __u8 bmFramingInfo;
+- __u8 bPreferedVersion;
+- __u8 bMinVersion;
+- __u8 bMaxVersion;
+-} __attribute__((__packed__));
+-
+-/* ------------------------------------------------------------------------
+ * Debugging, printing and logging
+ */
+
+@@ -137,9 +104,6 @@ extern unsigned int uvc_trace_param;
+ #define UVC_MAX_REQUEST_SIZE 64
+ #define UVC_MAX_EVENTS 4
+
+-#define USB_DT_INTERFACE_ASSOCIATION_SIZE 8
+-#define USB_CLASS_MISC 0xef
+-
+ /* ------------------------------------------------------------------------
+ * Structures
+ */
+--- a/drivers/usb/gadget/webcam.c
++++ b/drivers/usb/gadget/webcam.c
+@@ -90,7 +90,7 @@ DECLARE_UVC_HEADER_DESCRIPTOR(1);
+ static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = {
+ .bLength = UVC_DT_HEADER_SIZE(1),
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = UVC_DT_HEADER,
++ .bDescriptorSubType = UVC_VC_HEADER,
+ .bcdUVC = cpu_to_le16(0x0100),
+ .wTotalLength = 0, /* dynamic */
+ .dwClockFrequency = cpu_to_le32(48000000),
+@@ -101,7 +101,7 @@ static const struct UVC_HEADER_DESCRIPTO
+ static const struct uvc_camera_terminal_descriptor uvc_camera_terminal = {
+ .bLength = UVC_DT_CAMERA_TERMINAL_SIZE(3),
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = UVC_DT_INPUT_TERMINAL,
++ .bDescriptorSubType = UVC_VC_INPUT_TERMINAL,
+ .bTerminalID = 1,
+ .wTerminalType = cpu_to_le16(0x0201),
+ .bAssocTerminal = 0,
+@@ -118,7 +118,7 @@ static const struct uvc_camera_terminal_
+ static const struct uvc_processing_unit_descriptor uvc_processing = {
+ .bLength = UVC_DT_PROCESSING_UNIT_SIZE(2),
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = UVC_DT_PROCESSING_UNIT,
++ .bDescriptorSubType = UVC_VC_PROCESSING_UNIT,
+ .bUnitID = 2,
+ .bSourceID = 1,
+ .wMaxMultiplier = cpu_to_le16(16*1024),
+@@ -131,7 +131,7 @@ static const struct uvc_processing_unit_
+ static const struct uvc_output_terminal_descriptor uvc_output_terminal = {
+ .bLength = UVC_DT_OUTPUT_TERMINAL_SIZE,
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = UVC_DT_OUTPUT_TERMINAL,
++ .bDescriptorSubType = UVC_VC_OUTPUT_TERMINAL,
+ .bTerminalID = 3,
+ .wTerminalType = cpu_to_le16(0x0101),
+ .bAssocTerminal = 0,
+@@ -144,7 +144,7 @@ DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(1, 2
+ static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 2) uvc_input_header = {
+ .bLength = UVC_DT_INPUT_HEADER_SIZE(1, 2),
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = UVC_DT_INPUT_HEADER,
++ .bDescriptorSubType = UVC_VS_INPUT_HEADER,
+ .bNumFormats = 2,
+ .wTotalLength = 0, /* dynamic */
+ .bEndpointAddress = 0, /* dynamic */
+@@ -161,7 +161,7 @@ static const struct UVC_INPUT_HEADER_DES
+ static const struct uvc_format_uncompressed uvc_format_yuv = {
+ .bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE,
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = UVC_DT_FORMAT_UNCOMPRESSED,
++ .bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED,
+ .bFormatIndex = 1,
+ .bNumFrameDescriptors = 2,
+ .guidFormat =
+@@ -181,7 +181,7 @@ DECLARE_UVC_FRAME_UNCOMPRESSED(3);
+ static const struct UVC_FRAME_UNCOMPRESSED(3) uvc_frame_yuv_360p = {
+ .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(3),
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = UVC_DT_FRAME_UNCOMPRESSED,
++ .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED,
+ .bFrameIndex = 1,
+ .bmCapabilities = 0,
+ .wWidth = cpu_to_le16(640),
+@@ -199,7 +199,7 @@ static const struct UVC_FRAME_UNCOMPRESS
+ static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = {
+ .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1),
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = UVC_DT_FRAME_UNCOMPRESSED,
++ .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED,
+ .bFrameIndex = 2,
+ .bmCapabilities = 0,
+ .wWidth = cpu_to_le16(1280),
+@@ -215,7 +215,7 @@ static const struct UVC_FRAME_UNCOMPRESS
+ static const struct uvc_format_mjpeg uvc_format_mjpg = {
+ .bLength = UVC_DT_FORMAT_MJPEG_SIZE,
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = UVC_DT_FORMAT_MJPEG,
++ .bDescriptorSubType = UVC_VS_FORMAT_MJPEG,
+ .bFormatIndex = 2,
+ .bNumFrameDescriptors = 2,
+ .bmFlags = 0,
+@@ -232,7 +232,7 @@ DECLARE_UVC_FRAME_MJPEG(3);
+ static const struct UVC_FRAME_MJPEG(3) uvc_frame_mjpg_360p = {
+ .bLength = UVC_DT_FRAME_MJPEG_SIZE(3),
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = UVC_DT_FRAME_MJPEG,
++ .bDescriptorSubType = UVC_VS_FRAME_MJPEG,
+ .bFrameIndex = 1,
+ .bmCapabilities = 0,
+ .wWidth = cpu_to_le16(640),
+@@ -250,7 +250,7 @@ static const struct UVC_FRAME_MJPEG(3) u
+ static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = {
+ .bLength = UVC_DT_FRAME_MJPEG_SIZE(1),
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = UVC_DT_FRAME_MJPEG,
++ .bDescriptorSubType = UVC_VS_FRAME_MJPEG,
+ .bFrameIndex = 2,
+ .bmCapabilities = 0,
+ .wWidth = cpu_to_le16(1280),
+@@ -266,7 +266,7 @@ static const struct UVC_FRAME_MJPEG(1) u
+ static const struct uvc_color_matching_descriptor uvc_color_matching = {
+ .bLength = UVC_DT_COLOR_MATCHING_SIZE,
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = UVC_DT_COLOR_MATCHING,
++ .bDescriptorSubType = UVC_VS_COLORFORMAT,
+ .bColorPrimaries = 1,
+ .bTransferCharacteristics = 1,
+ .bMatrixCoefficients = 4,
+--- a/include/linux/usb/video.h
++++ b/include/linux/usb/video.h
+@@ -160,5 +160,402 @@
+ #define UVC_STATUS_TYPE_CONTROL 1
+ #define UVC_STATUS_TYPE_STREAMING 2
+
++/* 2.4.3.3. Payload Header Information */
++#define UVC_STREAM_EOH (1 << 7)
++#define UVC_STREAM_ERR (1 << 6)
++#define UVC_STREAM_STI (1 << 5)
++#define UVC_STREAM_RES (1 << 4)
++#define UVC_STREAM_SCR (1 << 3)
++#define UVC_STREAM_PTS (1 << 2)
++#define UVC_STREAM_EOF (1 << 1)
++#define UVC_STREAM_FID (1 << 0)
++
++/* ------------------------------------------------------------------------
++ * UVC structures
++ */
++
++/* All UVC descriptors have these 3 fields at the beginning */
++struct uvc_descriptor_header {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++} __attribute__((packed));
++
++/* 3.7.2. Video Control Interface Header Descriptor */
++struct uvc_header_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u16 bcdUVC;
++ __u16 wTotalLength;
++ __u32 dwClockFrequency;
++ __u8 bInCollection;
++ __u8 baInterfaceNr[];
++} __attribute__((__packed__));
++
++#define UVC_DT_HEADER_SIZE(n) (12+(n))
++
++#define UVC_HEADER_DESCRIPTOR(n) \
++ uvc_header_descriptor_##n
++
++#define DECLARE_UVC_HEADER_DESCRIPTOR(n) \
++struct UVC_HEADER_DESCRIPTOR(n) { \
++ __u8 bLength; \
++ __u8 bDescriptorType; \
++ __u8 bDescriptorSubType; \
++ __u16 bcdUVC; \
++ __u16 wTotalLength; \
++ __u32 dwClockFrequency; \
++ __u8 bInCollection; \
++ __u8 baInterfaceNr[n]; \
++} __attribute__ ((packed))
++
++/* 3.7.2.1. Input Terminal Descriptor */
++struct uvc_input_terminal_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u8 bTerminalID;
++ __u16 wTerminalType;
++ __u8 bAssocTerminal;
++ __u8 iTerminal;
++} __attribute__((__packed__));
++
++#define UVC_DT_INPUT_TERMINAL_SIZE 8
++
++/* 3.7.2.2. Output Terminal Descriptor */
++struct uvc_output_terminal_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u8 bTerminalID;
++ __u16 wTerminalType;
++ __u8 bAssocTerminal;
++ __u8 bSourceID;
++ __u8 iTerminal;
++} __attribute__((__packed__));
++
++#define UVC_DT_OUTPUT_TERMINAL_SIZE 9
++
++/* 3.7.2.3. Camera Terminal Descriptor */
++struct uvc_camera_terminal_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u8 bTerminalID;
++ __u16 wTerminalType;
++ __u8 bAssocTerminal;
++ __u8 iTerminal;
++ __u16 wObjectiveFocalLengthMin;
++ __u16 wObjectiveFocalLengthMax;
++ __u16 wOcularFocalLength;
++ __u8 bControlSize;
++ __u8 bmControls[3];
++} __attribute__((__packed__));
++
++#define UVC_DT_CAMERA_TERMINAL_SIZE(n) (15+(n))
++
++/* 3.7.2.4. Selector Unit Descriptor */
++struct uvc_selector_unit_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u8 bUnitID;
++ __u8 bNrInPins;
++ __u8 baSourceID[0];
++ __u8 iSelector;
++} __attribute__((__packed__));
++
++#define UVC_DT_SELECTOR_UNIT_SIZE(n) (6+(n))
++
++#define UVC_SELECTOR_UNIT_DESCRIPTOR(n) \
++ uvc_selector_unit_descriptor_##n
++
++#define DECLARE_UVC_SELECTOR_UNIT_DESCRIPTOR(n) \
++struct UVC_SELECTOR_UNIT_DESCRIPTOR(n) { \
++ __u8 bLength; \
++ __u8 bDescriptorType; \
++ __u8 bDescriptorSubType; \
++ __u8 bUnitID; \
++ __u8 bNrInPins; \
++ __u8 baSourceID[n]; \
++ __u8 iSelector; \
++} __attribute__ ((packed))
++
++/* 3.7.2.5. Processing Unit Descriptor */
++struct uvc_processing_unit_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u8 bUnitID;
++ __u8 bSourceID;
++ __u16 wMaxMultiplier;
++ __u8 bControlSize;
++ __u8 bmControls[2];
++ __u8 iProcessing;
++} __attribute__((__packed__));
++
++#define UVC_DT_PROCESSING_UNIT_SIZE(n) (9+(n))
++
++/* 3.7.2.6. Extension Unit Descriptor */
++struct uvc_extension_unit_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u8 bUnitID;
++ __u8 guidExtensionCode[16];
++ __u8 bNumControls;
++ __u8 bNrInPins;
++ __u8 baSourceID[0];
++ __u8 bControlSize;
++ __u8 bmControls[0];
++ __u8 iExtension;
++} __attribute__((__packed__));
++
++#define UVC_DT_EXTENSION_UNIT_SIZE(p, n) (24+(p)+(n))
++
++#define UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) \
++ uvc_extension_unit_descriptor_##p_##n
++
++#define DECLARE_UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) \
++struct UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) { \
++ __u8 bLength; \
++ __u8 bDescriptorType; \
++ __u8 bDescriptorSubType; \
++ __u8 bUnitID; \
++ __u8 guidExtensionCode[16]; \
++ __u8 bNumControls; \
++ __u8 bNrInPins; \
++ __u8 baSourceID[p]; \
++ __u8 bControlSize; \
++ __u8 bmControls[n]; \
++ __u8 iExtension; \
++} __attribute__ ((packed))
++
++/* 3.8.2.2. Video Control Interrupt Endpoint Descriptor */
++struct uvc_control_endpoint_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u16 wMaxTransferSize;
++} __attribute__((__packed__));
++
++#define UVC_DT_CONTROL_ENDPOINT_SIZE 5
++
++/* 3.9.2.1. Input Header Descriptor */
++struct uvc_input_header_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u8 bNumFormats;
++ __u16 wTotalLength;
++ __u8 bEndpointAddress;
++ __u8 bmInfo;
++ __u8 bTerminalLink;
++ __u8 bStillCaptureMethod;
++ __u8 bTriggerSupport;
++ __u8 bTriggerUsage;
++ __u8 bControlSize;
++ __u8 bmaControls[];
++} __attribute__((__packed__));
++
++#define UVC_DT_INPUT_HEADER_SIZE(n, p) (13+(n*p))
++
++#define UVC_INPUT_HEADER_DESCRIPTOR(n, p) \
++ uvc_input_header_descriptor_##n_##p
++
++#define DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(n, p) \
++struct UVC_INPUT_HEADER_DESCRIPTOR(n, p) { \
++ __u8 bLength; \
++ __u8 bDescriptorType; \
++ __u8 bDescriptorSubType; \
++ __u8 bNumFormats; \
++ __u16 wTotalLength; \
++ __u8 bEndpointAddress; \
++ __u8 bmInfo; \
++ __u8 bTerminalLink; \
++ __u8 bStillCaptureMethod; \
++ __u8 bTriggerSupport; \
++ __u8 bTriggerUsage; \
++ __u8 bControlSize; \
++ __u8 bmaControls[p][n]; \
++} __attribute__ ((packed))
++
++/* 3.9.2.2. Output Header Descriptor */
++struct uvc_output_header_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u8 bNumFormats;
++ __u16 wTotalLength;
++ __u8 bEndpointAddress;
++ __u8 bTerminalLink;
++ __u8 bControlSize;
++ __u8 bmaControls[];
++} __attribute__((__packed__));
++
++#define UVC_DT_OUTPUT_HEADER_SIZE(n, p) (9+(n*p))
++
++#define UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) \
++ uvc_output_header_descriptor_##n_##p
++
++#define DECLARE_UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) \
++struct UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) { \
++ __u8 bLength; \
++ __u8 bDescriptorType; \
++ __u8 bDescriptorSubType; \
++ __u8 bNumFormats; \
++ __u16 wTotalLength; \
++ __u8 bEndpointAddress; \
++ __u8 bTerminalLink; \
++ __u8 bControlSize; \
++ __u8 bmaControls[p][n]; \
++} __attribute__ ((packed))
++
++/* 3.9.2.6. Color matching descriptor */
++struct uvc_color_matching_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u8 bColorPrimaries;
++ __u8 bTransferCharacteristics;
++ __u8 bMatrixCoefficients;
++} __attribute__((__packed__));
++
++#define UVC_DT_COLOR_MATCHING_SIZE 6
++
++/* 4.3.1.1. Video Probe and Commit Controls */
++struct uvc_streaming_control {
++ __u16 bmHint;
++ __u8 bFormatIndex;
++ __u8 bFrameIndex;
++ __u32 dwFrameInterval;
++ __u16 wKeyFrameRate;
++ __u16 wPFrameRate;
++ __u16 wCompQuality;
++ __u16 wCompWindowSize;
++ __u16 wDelay;
++ __u32 dwMaxVideoFrameSize;
++ __u32 dwMaxPayloadTransferSize;
++ __u32 dwClockFrequency;
++ __u8 bmFramingInfo;
++ __u8 bPreferedVersion;
++ __u8 bMinVersion;
++ __u8 bMaxVersion;
++} __attribute__((__packed__));
++
++/* Uncompressed Payload - 3.1.1. Uncompressed Video Format Descriptor */
++struct uvc_format_uncompressed {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u8 bFormatIndex;
++ __u8 bNumFrameDescriptors;
++ __u8 guidFormat[16];
++ __u8 bBitsPerPixel;
++ __u8 bDefaultFrameIndex;
++ __u8 bAspectRatioX;
++ __u8 bAspectRatioY;
++ __u8 bmInterfaceFlags;
++ __u8 bCopyProtect;
++} __attribute__((__packed__));
++
++#define UVC_DT_FORMAT_UNCOMPRESSED_SIZE 27
++
++/* Uncompressed Payload - 3.1.2. Uncompressed Video Frame Descriptor */
++struct uvc_frame_uncompressed {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u8 bFrameIndex;
++ __u8 bmCapabilities;
++ __u16 wWidth;
++ __u16 wHeight;
++ __u32 dwMinBitRate;
++ __u32 dwMaxBitRate;
++ __u32 dwMaxVideoFrameBufferSize;
++ __u32 dwDefaultFrameInterval;
++ __u8 bFrameIntervalType;
++ __u32 dwFrameInterval[];
++} __attribute__((__packed__));
++
++#define UVC_DT_FRAME_UNCOMPRESSED_SIZE(n) (26+4*(n))
++
++#define UVC_FRAME_UNCOMPRESSED(n) \
++ uvc_frame_uncompressed_##n
++
++#define DECLARE_UVC_FRAME_UNCOMPRESSED(n) \
++struct UVC_FRAME_UNCOMPRESSED(n) { \
++ __u8 bLength; \
++ __u8 bDescriptorType; \
++ __u8 bDescriptorSubType; \
++ __u8 bFrameIndex; \
++ __u8 bmCapabilities; \
++ __u16 wWidth; \
++ __u16 wHeight; \
++ __u32 dwMinBitRate; \
++ __u32 dwMaxBitRate; \
++ __u32 dwMaxVideoFrameBufferSize; \
++ __u32 dwDefaultFrameInterval; \
++ __u8 bFrameIntervalType; \
++ __u32 dwFrameInterval[n]; \
++} __attribute__ ((packed))
++
++/* MJPEG Payload - 3.1.1. MJPEG Video Format Descriptor */
++struct uvc_format_mjpeg {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u8 bFormatIndex;
++ __u8 bNumFrameDescriptors;
++ __u8 bmFlags;
++ __u8 bDefaultFrameIndex;
++ __u8 bAspectRatioX;
++ __u8 bAspectRatioY;
++ __u8 bmInterfaceFlags;
++ __u8 bCopyProtect;
++} __attribute__((__packed__));
++
++#define UVC_DT_FORMAT_MJPEG_SIZE 11
++
++/* MJPEG Payload - 3.1.2. MJPEG Video Frame Descriptor */
++struct uvc_frame_mjpeg {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++ __u8 bFrameIndex;
++ __u8 bmCapabilities;
++ __u16 wWidth;
++ __u16 wHeight;
++ __u32 dwMinBitRate;
++ __u32 dwMaxBitRate;
++ __u32 dwMaxVideoFrameBufferSize;
++ __u32 dwDefaultFrameInterval;
++ __u8 bFrameIntervalType;
++ __u32 dwFrameInterval[];
++} __attribute__((__packed__));
++
++#define UVC_DT_FRAME_MJPEG_SIZE(n) (26+4*(n))
++
++#define UVC_FRAME_MJPEG(n) \
++ uvc_frame_mjpeg_##n
++
++#define DECLARE_UVC_FRAME_MJPEG(n) \
++struct UVC_FRAME_MJPEG(n) { \
++ __u8 bLength; \
++ __u8 bDescriptorType; \
++ __u8 bDescriptorSubType; \
++ __u8 bFrameIndex; \
++ __u8 bmCapabilities; \
++ __u16 wWidth; \
++ __u16 wHeight; \
++ __u32 dwMinBitRate; \
++ __u32 dwMaxBitRate; \
++ __u32 dwMaxVideoFrameBufferSize; \
++ __u32 dwDefaultFrameInterval; \
++ __u8 bFrameIntervalType; \
++ __u32 dwFrameInterval[n]; \
++} __attribute__ ((packed))
++
+ #endif /* __LINUX_USB_VIDEO_H */
+