diff options
Diffstat (limited to 'usb')
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 */ + |
