aboutsummaryrefslogtreecommitdiffstats
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2010-04-29 16:21:01 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-04-29 16:21:01 -0700
commit6a262e12cd91119840767d1724f50b96d013551b (patch)
tree9ada8a9eea32d8548d1491b98cd0e18f48c344e6
parentc87f20e270b8b799d5e7fa2941117b4e0d6b1ab7 (diff)
downloadpatches-6a262e12cd91119840767d1724f50b96d013551b.tar.gz
usb fun
-rw-r--r--series16
-rw-r--r--usb/devices-fix-coding-styles.patch6
-rw-r--r--usb/usb-add-a-new-quirk-usb_quirk_honor_bnuminterfaces.patch9
-rw-r--r--usb/usb-cdc-ncm-constants-and-structures-added.patch144
-rw-r--r--usb/usb-clean-up-some-host-controller-sparse-warnings.patch204
-rw-r--r--usb/usb-composite-framework-add-suspended-sysfs-entry.patch117
-rw-r--r--usb/usb-core-config.c-usb_get_configuration-simplified.patch60
-rw-r--r--usb/usb-don-t-enable-remote-wakeup-by-default.patch2
-rw-r--r--usb/usb-fix-usbmon-and-dma-mapping-for-scatter-gather-urbs.patch12
-rw-r--r--usb/usb-improve-runtime-remote-wakeup-settings.patch8
-rw-r--r--usb/usb-make-hcd.h-public-drivers-dependency.patch1838
-rw-r--r--usb/usb-make-hub.h-public-drivers-dependency.patch451
-rw-r--r--usb/usb-mass-storage-gadget-handle-eject-request.patch88
-rw-r--r--usb/usb-ncm-added-ncm.h-with-auxiliary-definitions.patch132
-rw-r--r--usb/usb-remove-bogus-usb_port_feat_-_speed-symbols.patch56
-rw-r--r--usb/usb-split-hub.h-into-ch11.h-and-merge-in-hcd.h.patch452
-rw-r--r--usb/usb-straighten-out-port-feature-vs.-port-status-usage.patch12
-rw-r--r--usb/usb-support-for-allocating-usb-3.0-streams.patch42
-rw-r--r--usb/usb-usbserial-mos7720-add-support-for-parallel-port-on-moschip-7715.patch1078
-rw-r--r--usb/usb-usbserial-mos7720-cleanup-consolidation-replace-send_mos_cmd-with-read-write-_mos_reg.patch747
-rw-r--r--usb/usb-use-pm-core-routines-to-enable-disable-autosuspend.patch6
21 files changed, 5403 insertions, 77 deletions
diff --git a/series b/series
index 05e7fd0ce18704..3a48d21b88f010 100644
--- a/series
+++ b/series
@@ -152,6 +152,9 @@ tty/serial-uartlite-move-from-byte-accesses-to-word-accesses.patch
###################################
# USB stuff for after 2.6.34 is out
###################################
+usb/usb-make-hcd.h-public-drivers-dependency.patch
+usb/usb-make-hub.h-public-drivers-dependency.patch
+usb/usb-split-hub.h-into-ch11.h-and-merge-in-hcd.h.patch
usb/usb-sisusbvga-remove-the-bkl-from-ioctl.patch
usb/usb-cdc-acm-make-bitfields-unsigned.patch
usb/usb-remove-large-struct-from-the-stack-in-usb-storage-isd200-driver.patch
@@ -241,6 +244,18 @@ usb/short-new-graph-for-usb-serial.txt.patch
usb/usb-rename-usb_buffer_alloc-and-usb_buffer_free-users.patch
usb/usb-staging-fix-up-usb_buffer_alloc-calls-in-the-staging-tree.patch
+
+usb/usb-usbserial-mos7720-add-support-for-parallel-port-on-moschip-7715.patch
+usb/usb-usbserial-mos7720-cleanup-consolidation-replace-send_mos_cmd-with-read-write-_mos_reg.patch
+usb/usb-cdc-ncm-constants-and-structures-added.patch
+usb/usb-ncm-added-ncm.h-with-auxiliary-definitions.patch
+usb/usb-core-config.c-usb_get_configuration-simplified.patch
+usb/usb-clean-up-some-host-controller-sparse-warnings.patch
+usb/usb-composite-framework-add-suspended-sysfs-entry.patch
+usb/usb-mass-storage-gadget-handle-eject-request.patch
+
+
+# this goes in last.
usb/usb-remove-unused-usb_buffer_alloc-and-usb_buffer_free-macros.patch
#######################################
@@ -251,4 +266,3 @@ usb/usb-remove-unused-usb_buffer_alloc-and-usb_buffer_free-macros.patch
# new stuff is in the staging-next git tree on git.kernel.org
-
diff --git a/usb/devices-fix-coding-styles.patch b/usb/devices-fix-coding-styles.patch
index 195090f8104c6a..a7adf40af73ad1 100644
--- a/usb/devices-fix-coding-styles.patch
+++ b/usb/devices-fix-coding-styles.patch
@@ -28,15 +28,15 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
* (C) Copyright 1999 Deti Fliegl (new USB architecture)
*
* This program is free software; you can redistribute it and/or modify
-@@ -56,7 +57,7 @@
- #include <linux/smp_lock.h>
+@@ -57,7 +58,7 @@
#include <linux/usbdevice_fs.h>
+ #include <linux/usb/hcd.h>
#include <linux/mutex.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include "usb.h"
- #include "hcd.h"
+
@@ -138,8 +139,8 @@ struct class_info {
char *class_name;
};
diff --git a/usb/usb-add-a-new-quirk-usb_quirk_honor_bnuminterfaces.patch b/usb/usb-add-a-new-quirk-usb_quirk_honor_bnuminterfaces.patch
index a9133f2235e6f7..440af4ebfeed71 100644
--- a/usb/usb-add-a-new-quirk-usb_quirk_honor_bnuminterfaces.patch
+++ b/usb/usb-add-a-new-quirk-usb_quirk_honor_bnuminterfaces.patch
@@ -29,14 +29,15 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
-@@ -1,5 +1,6 @@
+@@ -1,6 +1,7 @@
#include <linux/usb.h>
#include <linux/usb/ch9.h>
+ #include <linux/usb/hcd.h>
+#include <linux/usb/quirks.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
-@@ -478,9 +479,10 @@ skip_to_next_interface_descriptor:
+@@ -479,9 +480,10 @@ skip_to_next_interface_descriptor:
return buffer - buffer0 + i;
}
@@ -48,7 +49,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
unsigned char *buffer0 = buffer;
int cfgno;
int nintf, nintf_orig;
-@@ -549,6 +551,16 @@ static int usb_parse_configuration(struc
+@@ -550,6 +552,16 @@ static int usb_parse_configuration(struc
}
inum = d->bInterfaceNumber;
@@ -65,7 +66,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
if (inum >= nintf_orig)
dev_warn(ddev, "config %d has an invalid "
"interface number: %d but max is %d\n",
-@@ -800,7 +812,7 @@ int usb_get_configuration(struct usb_dev
+@@ -801,7 +813,7 @@ int usb_get_configuration(struct usb_dev
dev->rawdescriptors[cfgno] = bigbuffer;
diff --git a/usb/usb-cdc-ncm-constants-and-structures-added.patch b/usb/usb-cdc-ncm-constants-and-structures-added.patch
new file mode 100644
index 00000000000000..70973fb2cd9d64
--- /dev/null
+++ b/usb/usb-cdc-ncm-constants-and-structures-added.patch
@@ -0,0 +1,144 @@
+From yauheni.kaliuta@nokia.com Thu Apr 29 16:02:05 2010
+From: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
+Date: Fri, 16 Apr 2010 16:13:34 +0300
+Subject: usb: cdc: ncm constants and structures added
+To: linux-usb@vger.kernel.org
+Message-ID: <1271423621-26361-2-git-send-email-yauheni.kaliuta@nokia.com>
+
+
+Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/usb/cdc.h | 94 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 94 insertions(+)
+
+--- a/include/linux/usb/cdc.h
++++ b/include/linux/usb/cdc.h
+@@ -18,6 +18,7 @@
+ #define USB_CDC_SUBCLASS_MDLM 0x0a
+ #define USB_CDC_SUBCLASS_OBEX 0x0b
+ #define USB_CDC_SUBCLASS_EEM 0x0c
++#define USB_CDC_SUBCLASS_NCM 0x0d
+
+ #define USB_CDC_PROTO_NONE 0
+
+@@ -49,6 +50,7 @@
+ #define USB_CDC_MDLM_DETAIL_TYPE 0x13 /* mdlm_detail_desc */
+ #define USB_CDC_DMM_TYPE 0x14
+ #define USB_CDC_OBEX_TYPE 0x15
++#define USB_CDC_NCM_TYPE 0x1a
+
+ /* "Header Functional Descriptor" from CDC spec 5.2.3.1 */
+ struct usb_cdc_header_desc {
+@@ -174,6 +176,15 @@ struct usb_cdc_obex_desc {
+ __le16 bcdVersion;
+ } __attribute__ ((packed));
+
++/* "NCM Control Model Functional Descriptor" */
++struct usb_cdc_ncm_desc {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDescriptorSubType;
++
++ __le16 bcdNcmVersion;
++ __u8 bmNetworkCapabilities;
++} __attribute__ ((packed));
+ /*-------------------------------------------------------------------------*/
+
+ /*
+@@ -197,6 +208,17 @@ struct usb_cdc_obex_desc {
+ #define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42
+ #define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43
+ #define USB_CDC_GET_ETHERNET_STATISTIC 0x44
++#define USB_CDC_GET_NTB_PARAMETERS 0x80
++#define USB_CDC_GET_NET_ADDRESS 0x81
++#define USB_CDC_SET_NET_ADDRESS 0x82
++#define USB_CDC_GET_NTB_FORMAT 0x83
++#define USB_CDC_SET_NTB_FORMAT 0x84
++#define USB_CDC_GET_NTB_INPUT_SIZE 0x85
++#define USB_CDC_SET_NTB_INPUT_SIZE 0x86
++#define USB_CDC_GET_MAX_DATAGRAM_SIZE 0x87
++#define USB_CDC_SET_MAX_DATAGRAM_SIZE 0x88
++#define USB_CDC_GET_CRC_MODE 0x89
++#define USB_CDC_SET_CRC_MODE 0x8a
+
+ /* Line Coding Structure from CDC spec 6.2.13 */
+ struct usb_cdc_line_coding {
+@@ -247,4 +269,76 @@ struct usb_cdc_notification {
+ __le16 wLength;
+ } __attribute__ ((packed));
+
++/*-------------------------------------------------------------------------*/
++
++/*
++ * Class Specific structures and constants
++ *
++ * CDC NCM parameter structure, CDC NCM subclass 6.2.1
++ *
++ */
++
++struct usb_cdc_ncm_ntb_parameter {
++ __le16 wLength;
++ __le16 bmNtbFormatSupported;
++ __le32 dwNtbInMaxSize;
++ __le16 wNdpInDivisor;
++ __le16 wNdpInPayloadRemainder;
++ __le16 wNdpInAlignment;
++ __le16 wPadding1;
++ __le32 dwNtbOutMaxSize;
++ __le16 wNdpOutDivisor;
++ __le16 wNdpOutPayloadRemainder;
++ __le16 wNdpOutAlignment;
++ __le16 wPadding2;
++} __attribute__ ((packed));
++
++/*
++ * CDC NCM transfer headers, CDC NCM subclass 3.2
++ */
++
++#define NCM_NTH16_SIGN 0x484D434E /* NCMH */
++#define NCM_NTH32_SIGN 0x686D636E /* ncmh */
++
++struct usb_cdc_ncm_nth16 {
++ __le32 dwSignature;
++ __le16 wHeaderLength;
++ __le16 wSequence;
++ __le16 wBlockLength;
++ __le16 wFpIndex;
++} __attribute__ ((packed));
++
++struct usb_cdc_ncm_nth32 {
++ __le32 dwSignature;
++ __le16 wHeaderLength;
++ __le16 wSequence;
++ __le32 dwBlockLength;
++ __le32 dwFpIndex;
++} __attribute__ ((packed));
++
++/*
++ * CDC NCM datagram pointers, CDC NCM subclass 3.3
++ */
++
++#define NCM_NDP16_CRC_SIGN 0x314D434E /* NCM1 */
++#define NCM_NDP16_NOCRC_SIGN 0x304D434E /* NCM0 */
++#define NCM_NDP32_CRC_SIGN 0x316D636E /* ncm1 */
++#define NCM_NDP32_NOCRC_SIGN 0x306D636E /* ncm0 */
++
++struct usb_cdc_ncm_ndp16 {
++ __le32 dwSignature;
++ __le16 wLength;
++ __le16 wNextFpIndex;
++ __u8 data[0];
++} __attribute__ ((packed));
++
++struct usb_cdc_ncm_ndp32 {
++ __le32 dwSignature;
++ __le16 wLength;
++ __le16 wReserved6;
++ __le32 dwNextFpIndex;
++ __le32 dwReserved12;
++ __u8 data[0];
++} __attribute__ ((packed));
++
+ #endif /* __LINUX_USB_CDC_H */
diff --git a/usb/usb-clean-up-some-host-controller-sparse-warnings.patch b/usb/usb-clean-up-some-host-controller-sparse-warnings.patch
new file mode 100644
index 00000000000000..488b5310a930a3
--- /dev/null
+++ b/usb/usb-clean-up-some-host-controller-sparse-warnings.patch
@@ -0,0 +1,204 @@
+From randy.dunlap@oracle.com Thu Apr 29 16:06:16 2010
+From: Randy Dunlap <randy.dunlap@oracle.com>
+Date: Mon, 19 Apr 2010 08:53:50 -0700
+Subject: USB: clean up some host controller sparse warnings
+Cc: gregkh@suse.de, Lothar Wassmann <LW@KARO-electronics.de>, Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Message-ID: <20100419085350.94470004.randy.dunlap@oracle.com>
+
+
+From: Randy Dunlap <randy.dunlap@oracle.com>
+
+Fix usb sparse warnings:
+
+drivers/usb/host/isp1362-hcd.c:2220:50: warning: Using plain integer as NULL pointer
+drivers/usb/host/xhci-mem.c:43:24: warning: Using plain integer as NULL pointer
+drivers/usb/host/xhci-mem.c:49:24: warning: Using plain integer as NULL pointer
+drivers/usb/host/xhci-mem.c:161:24: warning: Using plain integer as NULL pointer
+drivers/usb/host/xhci-mem.c:198:16: warning: Using plain integer as NULL pointer
+drivers/usb/host/xhci-mem.c:319:31: warning: Using plain integer as NULL pointer
+drivers/usb/host/xhci-mem.c:1231:33: warning: Using plain integer as NULL pointer
+drivers/usb/host/xhci-pci.c:177:23: warning: non-ANSI function declaration of function 'xhci_register_pci'
+drivers/usb/host/xhci-pci.c:182:26: warning: non-ANSI function declaration of function 'xhci_unregister_pci'
+drivers/usb/host/xhci-ring.c:342:32: warning: Using plain integer as NULL pointer
+drivers/usb/host/xhci-ring.c:525:34: warning: Using plain integer as NULL pointer
+drivers/usb/host/xhci-ring.c:1009:32: warning: Using plain integer as NULL pointer
+drivers/usb/host/xhci-ring.c:1031:32: warning: Using plain integer as NULL pointer
+drivers/usb/host/xhci-ring.c:1041:16: warning: Using plain integer as NULL pointer
+drivers/usb/host/xhci-ring.c:1096:30: warning: Using plain integer as NULL pointer
+drivers/usb/host/xhci-ring.c:1100:27: warning: Using plain integer as NULL pointer
+drivers/usb/host/xhci-mem.c:224:27: warning: symbol 'xhci_alloc_container_ctx' was not declared. Should it be static?
+drivers/usb/host/xhci-mem.c:242:6: warning: symbol 'xhci_free_container_ctx' was not declared. Should it be static?
+
+Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
+Cc: Lothar Wassmann <LW@KARO-electronics.de>
+Signed-off By: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/isp1362-hcd.c | 2 +-
+ drivers/usb/host/xhci-mem.c | 16 ++++++++--------
+ drivers/usb/host/xhci-pci.c | 4 ++--
+ drivers/usb/host/xhci-ring.c | 14 +++++++-------
+ 4 files changed, 18 insertions(+), 18 deletions(-)
+
+--- a/drivers/usb/host/isp1362-hcd.c
++++ b/drivers/usb/host/isp1362-hcd.c
+@@ -2217,7 +2217,7 @@ static void create_debug_file(struct isp
+ static void remove_debug_file(struct isp1362_hcd *isp1362_hcd)
+ {
+ if (isp1362_hcd->pde)
+- remove_proc_entry(proc_filename, 0);
++ remove_proc_entry(proc_filename, NULL);
+ }
+
+ #endif
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -41,13 +41,13 @@ static struct xhci_segment *xhci_segment
+
+ seg = kzalloc(sizeof *seg, flags);
+ if (!seg)
+- return 0;
++ return NULL;
+ xhci_dbg(xhci, "Allocating priv segment structure at %p\n", seg);
+
+ seg->trbs = dma_pool_alloc(xhci->segment_pool, flags, &dma);
+ if (!seg->trbs) {
+ kfree(seg);
+- return 0;
++ return NULL;
+ }
+ xhci_dbg(xhci, "// Allocating segment at %p (virtual) 0x%llx (DMA)\n",
+ seg->trbs, (unsigned long long)dma);
+@@ -159,7 +159,7 @@ static struct xhci_ring *xhci_ring_alloc
+ ring = kzalloc(sizeof *(ring), flags);
+ xhci_dbg(xhci, "Allocating ring at %p\n", ring);
+ if (!ring)
+- return 0;
++ return NULL;
+
+ INIT_LIST_HEAD(&ring->td_list);
+ if (num_segs == 0)
+@@ -196,7 +196,7 @@ static struct xhci_ring *xhci_ring_alloc
+
+ fail:
+ xhci_ring_free(xhci, ring);
+- return 0;
++ return NULL;
+ }
+
+ void xhci_free_or_cache_endpoint_ring(struct xhci_hcd *xhci,
+@@ -247,7 +247,7 @@ static void xhci_reinit_cached_ring(stru
+
+ #define CTX_SIZE(_hcc) (HCC_64BYTE_CONTEXT(_hcc) ? 64 : 32)
+
+-struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci,
++static struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci,
+ int type, gfp_t flags)
+ {
+ struct xhci_container_ctx *ctx = kzalloc(sizeof(*ctx), flags);
+@@ -265,7 +265,7 @@ struct xhci_container_ctx *xhci_alloc_co
+ return ctx;
+ }
+
+-void xhci_free_container_ctx(struct xhci_hcd *xhci,
++static void xhci_free_container_ctx(struct xhci_hcd *xhci,
+ struct xhci_container_ctx *ctx)
+ {
+ if (!ctx)
+@@ -764,7 +764,7 @@ void xhci_free_virt_device(struct xhci_h
+ xhci_free_container_ctx(xhci, dev->out_ctx);
+
+ kfree(xhci->devs[slot_id]);
+- xhci->devs[slot_id] = 0;
++ xhci->devs[slot_id] = NULL;
+ }
+
+ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
+@@ -1779,7 +1779,7 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+ */
+ init_completion(&xhci->addr_dev);
+ for (i = 0; i < MAX_HC_SLOTS; ++i)
+- xhci->devs[i] = 0;
++ xhci->devs[i] = NULL;
+
+ if (scratchpad_alloc(xhci, flags))
+ goto fail;
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -177,12 +177,12 @@ static struct pci_driver xhci_pci_driver
+ .shutdown = usb_hcd_pci_shutdown,
+ };
+
+-int xhci_register_pci()
++int xhci_register_pci(void)
+ {
+ return pci_register_driver(&xhci_pci_driver);
+ }
+
+-void xhci_unregister_pci()
++void xhci_unregister_pci(void)
+ {
+ pci_unregister_driver(&xhci_pci_driver);
+ }
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -371,7 +371,7 @@ static struct xhci_segment *find_trb_seg
+ cur_seg = cur_seg->next;
+ if (cur_seg == start_seg)
+ /* Looped over the entire list. Oops! */
+- return 0;
++ return NULL;
+ }
+ return cur_seg;
+ }
+@@ -565,7 +565,7 @@ static void handle_stopped_endpoint(stru
+ struct xhci_ring *ep_ring;
+ struct xhci_virt_ep *ep;
+ struct list_head *entry;
+- struct xhci_td *cur_td = 0;
++ struct xhci_td *cur_td = NULL;
+ struct xhci_td *last_unlinked_td;
+
+ struct xhci_dequeue_state deq_state;
+@@ -1096,7 +1096,7 @@ struct xhci_segment *trb_in_td(struct xh
+
+ do {
+ if (start_dma == 0)
+- return 0;
++ return NULL;
+ /* We may get an event for a Link TRB in the middle of a TD */
+ end_seg_dma = xhci_trb_virt_to_dma(cur_seg,
+ &cur_seg->trbs[TRBS_PER_SEGMENT - 1]);
+@@ -1118,7 +1118,7 @@ struct xhci_segment *trb_in_td(struct xh
+ suspect_dma <= end_trb_dma))
+ return cur_seg;
+ }
+- return 0;
++ return NULL;
+ } else {
+ /* Might still be somewhere in this segment */
+ if (suspect_dma >= start_dma && suspect_dma <= end_seg_dma)
+@@ -1128,7 +1128,7 @@ struct xhci_segment *trb_in_td(struct xh
+ start_dma = xhci_trb_virt_to_dma(cur_seg, &cur_seg->trbs[0]);
+ } while (cur_seg != start_seg);
+
+- return 0;
++ return NULL;
+ }
+
+ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
+@@ -1199,11 +1199,11 @@ static int handle_tx_event(struct xhci_h
+ struct xhci_ring *ep_ring;
+ unsigned int slot_id;
+ int ep_index;
+- struct xhci_td *td = 0;
++ struct xhci_td *td = NULL;
+ dma_addr_t event_dma;
+ struct xhci_segment *event_seg;
+ union xhci_trb *event_trb;
+- struct urb *urb = 0;
++ struct urb *urb = NULL;
+ int status = -EINPROGRESS;
+ struct xhci_ep_ctx *ep_ctx;
+ u32 trb_comp_code;
diff --git a/usb/usb-composite-framework-add-suspended-sysfs-entry.patch b/usb/usb-composite-framework-add-suspended-sysfs-entry.patch
new file mode 100644
index 00000000000000..68eff031b40872
--- /dev/null
+++ b/usb/usb-composite-framework-add-suspended-sysfs-entry.patch
@@ -0,0 +1,117 @@
+From fabien.chouteau@gmail.com Thu Apr 29 16:07:20 2010
+From: Fabien Chouteau <fabien.chouteau@barco.com>
+Date: Fri, 23 Apr 2010 14:21:26 +0200
+Subject: USB: Composite framework: Add suspended sysfs entry
+To: linux-usb@vger.kernel.org
+Cc: Fabien Chouteau <fabien.chouteau@barco.com>, Randy Dunlap <rdunlap@xenotime.net>, David Brownell <dbrownell@users.sourceforge.net>, Greg Kroah-Hartman <gregkh@suse.de>, Andrew Morton <akpm@linux-foundation.org>, Laurent Pinchart <laurent.pinchart@ideasonboard.com>, Michal Nazarewicz <m.nazarewicz@samsung.com>, Roel Kluin <roel.kluin@gmail.com>, Tejun Heo <tj@kernel.org>, Christoph Lameter <cl@linux-foundation.org>, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org
+Message-ID: <1272025288-32555-1-git-send-email-fabien.chouteau@gmail.com>
+
+
+From: Fabien Chouteau <fabien.chouteau@barco.com>
+
+This patch adds a sysfs entry (/sys/devices/platform/_UDC_/gadget/suspended) to
+show the suspend state of an USB composite gadget.
+
+Signed-off-by: Fabien Chouteau <fabien.chouteau@barco.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/ABI/testing/sysfs-devices-platform-_UDC_-gadget | 9 ++++
+ drivers/usb/gadget/composite.c | 21 ++++++++++
+ include/linux/usb/composite.h | 1
+ include/linux/usb/gadget.h | 4 +
+ 4 files changed, 35 insertions(+)
+
+--- /dev/null
++++ b/Documentation/ABI/testing/sysfs-devices-platform-_UDC_-gadget
+@@ -0,0 +1,9 @@
++What: /sys/devices/platform/_UDC_/gadget/suspended
++Date: April 2010
++Contact: Fabien Chouteau <fabien.chouteau@barco.com>
++Description:
++ Show the suspend state of an USB composite gadget.
++ 1 -> suspended
++ 0 -> resumed
++
++ (_UDC_ is the name of the USB Device Controller driver)
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -898,6 +898,18 @@ static void composite_disconnect(struct
+
+ /*-------------------------------------------------------------------------*/
+
++static ssize_t composite_show_suspended(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct usb_gadget *gadget = dev_to_usb_gadget(dev);
++ struct usb_composite_dev *cdev = get_gadget_data(gadget);
++
++ return sprintf(buf, "%d\n", cdev->suspended);
++}
++
++static DEVICE_ATTR(suspended, 0444, composite_show_suspended, NULL);
++
+ static void /* __init_or_exit */
+ composite_unbind(struct usb_gadget *gadget)
+ {
+@@ -944,6 +956,7 @@ composite_unbind(struct usb_gadget *gadg
+ }
+ kfree(cdev);
+ set_gadget_data(gadget, NULL);
++ device_remove_file(&gadget->dev, &dev_attr_suspended);
+ composite = NULL;
+ }
+
+@@ -1036,6 +1049,10 @@ static int __init composite_bind(struct
+ string_override(composite->strings,
+ cdev->desc.iSerialNumber, iSerialNumber);
+
++ status = device_create_file(&gadget->dev, &dev_attr_suspended);
++ if (status)
++ goto fail;
++
+ INFO(cdev, "%s ready\n", composite->name);
+ return 0;
+
+@@ -1064,6 +1081,8 @@ composite_suspend(struct usb_gadget *gad
+ }
+ if (composite->suspend)
+ composite->suspend(cdev);
++
++ cdev->suspended = 1;
+ }
+
+ static void
+@@ -1084,6 +1103,8 @@ composite_resume(struct usb_gadget *gadg
+ f->resume(f);
+ }
+ }
++
++ cdev->suspended = 0;
+ }
+
+ /*-------------------------------------------------------------------------*/
+--- a/include/linux/usb/composite.h
++++ b/include/linux/usb/composite.h
+@@ -326,6 +326,7 @@ struct usb_composite_dev {
+
+ /* private: */
+ /* internals */
++ unsigned int suspended:1;
+ struct usb_device_descriptor desc;
+ struct list_head configs;
+ struct usb_composite_driver *driver;
+--- a/include/linux/usb/gadget.h
++++ b/include/linux/usb/gadget.h
+@@ -494,6 +494,10 @@ static inline void set_gadget_data(struc
+ { dev_set_drvdata(&gadget->dev, data); }
+ static inline void *get_gadget_data(struct usb_gadget *gadget)
+ { return dev_get_drvdata(&gadget->dev); }
++static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev)
++{
++ return container_of(dev, struct usb_gadget, dev);
++}
+
+ /* iterates the non-control endpoints; 'tmp' is a struct usb_ep pointer */
+ #define gadget_for_each_ep(tmp,gadget) \
diff --git a/usb/usb-core-config.c-usb_get_configuration-simplified.patch b/usb/usb-core-config.c-usb_get_configuration-simplified.patch
new file mode 100644
index 00000000000000..9359a5ebf715f0
--- /dev/null
+++ b/usb/usb-core-config.c-usb_get_configuration-simplified.patch
@@ -0,0 +1,60 @@
+From mina86@mina86.com Thu Apr 29 16:05:40 2010
+From: Michal Nazarewicz <mina86@mina86.com>
+Date: Sat, 17 Apr 2010 17:12:58 +0200
+Subject: USB: core: config.c: usb_get_configuration() simplified
+To: Alan Stern <stern@rowland.harvard.edu>
+Cc: linux-usb@vger.kernel.org, <Linux-kernel@vger.kernel.org>, Greg Kroah-Hartman <gregkh@suse.de>
+Message-ID: <87sk6uaz9h.fsf@erwin.mina86.com>
+
+
+usb_gat_configuratio() used two pointers to point to the same
+memory. Code simplified, by removing one of them.
+
+Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/config.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -735,7 +735,6 @@ int usb_get_configuration(struct usb_dev
+ int ncfg = dev->descriptor.bNumConfigurations;
+ int result = 0;
+ unsigned int cfgno, length;
+- unsigned char *buffer;
+ unsigned char *bigbuffer;
+ struct usb_config_descriptor *desc;
+
+@@ -764,17 +763,16 @@ int usb_get_configuration(struct usb_dev
+ if (!dev->rawdescriptors)
+ goto err2;
+
+- buffer = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL);
+- if (!buffer)
++ desc = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL);
++ if (!desc)
+ goto err2;
+- desc = (struct usb_config_descriptor *)buffer;
+
+ result = 0;
+ for (; cfgno < ncfg; cfgno++) {
+ /* We grab just the first descriptor so we know how long
+ * the whole configuration is */
+ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
+- buffer, USB_DT_CONFIG_SIZE);
++ desc, USB_DT_CONFIG_SIZE);
+ if (result < 0) {
+ dev_err(ddev, "unable to read config index %d "
+ "descriptor/%s: %d\n", cfgno, "start", result);
+@@ -823,7 +821,7 @@ int usb_get_configuration(struct usb_dev
+ result = 0;
+
+ err:
+- kfree(buffer);
++ kfree(desc);
+ out_not_authorized:
+ dev->descriptor.bNumConfigurations = cfgno;
+ err2:
diff --git a/usb/usb-don-t-enable-remote-wakeup-by-default.patch b/usb/usb-don-t-enable-remote-wakeup-by-default.patch
index 0eef17f4964813..3e9effc0951c10 100644
--- a/usb/usb-don-t-enable-remote-wakeup-by-default.patch
+++ b/usb/usb-don-t-enable-remote-wakeup-by-default.patch
@@ -26,7 +26,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
-@@ -1784,7 +1784,6 @@ int usb_new_device(struct usb_device *ud
+@@ -1783,7 +1783,6 @@ int usb_new_device(struct usb_device *ud
* sysfs power/wakeup controls wakeup enabled/disabled
*/
device_init_wakeup(&udev->dev, 0);
diff --git a/usb/usb-fix-usbmon-and-dma-mapping-for-scatter-gather-urbs.patch b/usb/usb-fix-usbmon-and-dma-mapping-for-scatter-gather-urbs.patch
index 1bd7002f0875ba..2d08d07470a369 100644
--- a/usb/usb-fix-usbmon-and-dma-mapping-for-scatter-gather-urbs.patch
+++ b/usb/usb-fix-usbmon-and-dma-mapping-for-scatter-gather-urbs.patch
@@ -51,7 +51,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
-@@ -1260,6 +1260,51 @@ static void hcd_free_coherent(struct usb
+@@ -1259,6 +1259,51 @@ static void hcd_free_coherent(struct usb
*dma_handle = 0;
}
@@ -103,7 +103,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
gfp_t mem_flags)
{
-@@ -1271,8 +1316,6 @@ static int map_urb_for_dma(struct usb_hc
+@@ -1270,8 +1315,6 @@ static int map_urb_for_dma(struct usb_hc
* unless it uses pio or talks to another transport,
* or uses the provided scatter gather list for bulk.
*/
@@ -112,7 +112,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
if (usb_endpoint_xfer_control(&urb->ep->desc)
&& !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) {
-@@ -1285,6 +1328,7 @@ static int map_urb_for_dma(struct usb_hc
+@@ -1284,6 +1327,7 @@ static int map_urb_for_dma(struct usb_hc
if (dma_mapping_error(hcd->self.controller,
urb->setup_dma))
return -EAGAIN;
@@ -120,7 +120,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
} else if (hcd->driver->flags & HCD_LOCAL_MEM)
ret = hcd_alloc_coherent(
urb->dev->bus, mem_flags,
-@@ -1292,20 +1336,57 @@ static int map_urb_for_dma(struct usb_hc
+@@ -1291,20 +1335,57 @@ static int map_urb_for_dma(struct usb_hc
(void **)&urb->setup_packet,
sizeof(struct usb_ctrlrequest),
DMA_TO_DEVICE);
@@ -186,7 +186,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
} else if (hcd->driver->flags & HCD_LOCAL_MEM) {
ret = hcd_alloc_coherent(
urb->dev->bus, mem_flags,
-@@ -1313,55 +1394,16 @@ static int map_urb_for_dma(struct usb_hc
+@@ -1312,55 +1393,16 @@ static int map_urb_for_dma(struct usb_hc
&urb->transfer_buffer,
urb->transfer_buffer_length,
dir);
@@ -247,7 +247,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
/*-------------------------------------------------------------------------*/
/* may be called in any context with a valid urb->dev usecount
-@@ -1390,21 +1432,20 @@ int usb_hcd_submit_urb (struct urb *urb,
+@@ -1389,21 +1431,20 @@ int usb_hcd_submit_urb (struct urb *urb,
* URBs must be submitted in process context with interrupts
* enabled.
*/
diff --git a/usb/usb-improve-runtime-remote-wakeup-settings.patch b/usb/usb-improve-runtime-remote-wakeup-settings.patch
index d716bd5357879c..61b4ac53f24b5f 100644
--- a/usb/usb-improve-runtime-remote-wakeup-settings.patch
+++ b/usb/usb-improve-runtime-remote-wakeup-settings.patch
@@ -22,7 +22,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
-@@ -1485,9 +1485,6 @@ int usb_autoresume_device(struct usb_dev
+@@ -1486,9 +1486,6 @@ int usb_autoresume_device(struct usb_dev
* 0, a delayed autosuspend request for @intf's device is attempted. The
* attempt may fail (see autosuspend_check()).
*
@@ -32,7 +32,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
* This routine can run only in process context.
*/
void usb_autopm_put_interface(struct usb_interface *intf)
-@@ -1672,14 +1669,14 @@ EXPORT_SYMBOL_GPL(usb_autopm_get_interfa
+@@ -1673,14 +1670,14 @@ EXPORT_SYMBOL_GPL(usb_autopm_get_interfa
/* Internal routine to check whether we may autosuspend a device. */
static int autosuspend_check(struct usb_device *udev)
{
@@ -49,7 +49,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
if (udev->actconfig) {
for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
intf = udev->actconfig->interface[i];
-@@ -1693,12 +1690,7 @@ static int autosuspend_check(struct usb_
+@@ -1694,12 +1691,7 @@ static int autosuspend_check(struct usb_
continue;
if (atomic_read(&intf->dev.power.usage_count) > 0)
return -EBUSY;
@@ -63,7 +63,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
/* Don't allow autosuspend if the device will need
* a reset-resume and any of its interface drivers
-@@ -1714,6 +1706,11 @@ static int autosuspend_check(struct usb_
+@@ -1715,6 +1707,11 @@ static int autosuspend_check(struct usb_
}
}
}
diff --git a/usb/usb-make-hcd.h-public-drivers-dependency.patch b/usb/usb-make-hcd.h-public-drivers-dependency.patch
new file mode 100644
index 00000000000000..f6a640422331ef
--- /dev/null
+++ b/usb/usb-make-hcd.h-public-drivers-dependency.patch
@@ -0,0 +1,1838 @@
+From Eric.Lescouet@virtuallogix.com Thu Apr 29 16:09:14 2010
+From: Eric Lescouet <Eric.Lescouet@virtuallogix.com>
+Date: Sat, 24 Apr 2010 23:21:52 +0200
+Subject: USB: make hcd.h public (drivers dependency)
+To: Greg KH <greg@kroah.com>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Message-ID: <1272144112.2307.4.camel@localhost>
+
+
+The usbcore headers: hcd.h and hub.h are shared between usbcore,
+HCDs and a couple of other drivers (e.g. USBIP modules).
+So, it makes sense to move them into a more public location and
+to cleanup dependency of those modules on kernel internal headers.
+This patch moves hcd.h from drivers/usb/core into include/linux/usb/
+
+Signed-of-by: Eric Lescouet <eric@lescouet.org>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/usbip/stub_rx.c | 2
+ drivers/staging/usbip/vhci.h | 2
+ drivers/usb/c67x00/c67x00-hcd.h | 2
+ drivers/usb/core/buffer.c | 2
+ drivers/usb/core/config.c | 3
+ drivers/usb/core/devices.c | 2
+ drivers/usb/core/devio.c | 3
+ drivers/usb/core/driver.c | 3
+ drivers/usb/core/generic.c | 2
+ drivers/usb/core/hcd-pci.c | 2
+ drivers/usb/core/hcd.c | 3
+ drivers/usb/core/hcd.h | 578 ----------------------------------------
+ drivers/usb/core/hub.c | 3
+ drivers/usb/core/inode.c | 2
+ drivers/usb/core/message.c | 2
+ drivers/usb/core/urb.c | 2
+ drivers/usb/core/usb.c | 2
+ drivers/usb/gadget/dummy_hcd.c | 4
+ drivers/usb/host/ehci-hcd.c | 3
+ drivers/usb/host/fhci-dbg.c | 2
+ drivers/usb/host/fhci-hcd.c | 2
+ drivers/usb/host/fhci-hub.c | 2
+ drivers/usb/host/fhci-mem.c | 2
+ drivers/usb/host/fhci-q.c | 2
+ drivers/usb/host/fhci-sched.c | 2
+ drivers/usb/host/fhci-tds.c | 2
+ drivers/usb/host/fhci.h | 2
+ drivers/usb/host/imx21-hcd.c | 2
+ drivers/usb/host/isp116x-hcd.c | 2
+ drivers/usb/host/isp1362-hcd.c | 2
+ drivers/usb/host/isp1760-hcd.c | 2
+ drivers/usb/host/isp1760-if.c | 2
+ drivers/usb/host/ohci-hcd.c | 2
+ drivers/usb/host/oxu210hp-hcd.c | 3
+ drivers/usb/host/r8a66597-hcd.c | 2
+ drivers/usb/host/sl811-hcd.c | 2
+ drivers/usb/host/u132-hcd.c | 2
+ drivers/usb/host/uhci-hcd.c | 2
+ drivers/usb/host/xhci.h | 2
+ drivers/usb/misc/ftdi-elan.c | 2
+ drivers/usb/mon/mon_main.c | 3
+ drivers/usb/musb/musb_core.h | 2
+ drivers/usb/wusbcore/wusbhc.h | 4
+ include/linux/usb/hcd.h | 578 ++++++++++++++++++++++++++++++++++++++++
+ 44 files changed, 623 insertions(+), 629 deletions(-)
+
+--- a/drivers/staging/usbip/stub_rx.c
++++ b/drivers/staging/usbip/stub_rx.c
+@@ -21,7 +21,7 @@
+
+ #include "usbip_common.h"
+ #include "stub.h"
+-#include "../../usb/core/hcd.h"
++#include <linux/usb/hcd.h>
+
+
+ static int is_clear_halt_cmd(struct urb *urb)
+--- a/drivers/staging/usbip/vhci.h
++++ b/drivers/staging/usbip/vhci.h
+@@ -18,7 +18,7 @@
+ */
+
+ #include <linux/platform_device.h>
+-#include "../../usb/core/hcd.h"
++#include <linux/usb/hcd.h>
+
+
+ struct vhci_device {
+--- a/drivers/usb/c67x00/c67x00-hcd.h
++++ b/drivers/usb/c67x00/c67x00-hcd.h
+@@ -28,7 +28,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/list.h>
+ #include <linux/usb.h>
+-#include "../core/hcd.h"
++#include <linux/usb/hcd.h>
+ #include "c67x00.h"
+
+ /*
+--- a/drivers/usb/core/buffer.c
++++ b/drivers/usb/core/buffer.c
+@@ -14,7 +14,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/dmapool.h>
+ #include <linux/usb.h>
+-#include "hcd.h"
++#include <linux/usb/hcd.h>
+
+
+ /*
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -1,12 +1,13 @@
+ #include <linux/usb.h>
+ #include <linux/usb/ch9.h>
++#include <linux/usb/hcd.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/slab.h>
+ #include <linux/device.h>
+ #include <asm/byteorder.h>
+ #include "usb.h"
+-#include "hcd.h"
++
+
+ #define USB_MAXALTSETTING 128 /* Hard limit */
+ #define USB_MAXENDPOINTS 30 /* Hard limit */
+--- a/drivers/usb/core/devices.c
++++ b/drivers/usb/core/devices.c
+@@ -55,11 +55,11 @@
+ #include <linux/usb.h>
+ #include <linux/smp_lock.h>
+ #include <linux/usbdevice_fs.h>
++#include <linux/usb/hcd.h>
+ #include <linux/mutex.h>
+ #include <asm/uaccess.h>
+
+ #include "usb.h"
+-#include "hcd.h"
+
+ /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */
+ #define ALLOW_SERIAL_NUMBER
+--- a/drivers/usb/core/devio.c
++++ b/drivers/usb/core/devio.c
+@@ -43,6 +43,7 @@
+ #include <linux/module.h>
+ #include <linux/usb.h>
+ #include <linux/usbdevice_fs.h>
++#include <linux/usb/hcd.h> /* for usbcore internals */
+ #include <linux/cdev.h>
+ #include <linux/notifier.h>
+ #include <linux/security.h>
+@@ -50,9 +51,7 @@
+ #include <asm/byteorder.h>
+ #include <linux/moduleparam.h>
+
+-#include "hcd.h" /* for usbcore internals */
+ #include "usb.h"
+-#include "hub.h"
+
+ #define USB_MAXBUS 64
+ #define USB_DEVICE_MAX USB_MAXBUS * 128
+--- a/drivers/usb/core/driver.c
++++ b/drivers/usb/core/driver.c
+@@ -26,8 +26,9 @@
+ #include <linux/slab.h>
+ #include <linux/usb.h>
+ #include <linux/usb/quirks.h>
++#include <linux/usb/hcd.h>
+ #include <linux/pm_runtime.h>
+-#include "hcd.h"
++
+ #include "usb.h"
+
+
+--- a/drivers/usb/core/generic.c
++++ b/drivers/usb/core/generic.c
+@@ -18,8 +18,8 @@
+ */
+
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #include "usb.h"
+-#include "hcd.h"
+
+ static inline const char *plural(int n)
+ {
+--- a/drivers/usb/core/hcd-pci.c
++++ b/drivers/usb/core/hcd-pci.c
+@@ -21,6 +21,7 @@
+ #include <linux/pci.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+
+ #include <asm/io.h>
+ #include <asm/irq.h>
+@@ -33,7 +34,6 @@
+ #endif
+
+ #include "usb.h"
+-#include "hcd.h"
+
+
+ /* PCI-based HCs are common, but plenty of non-PCI HCs are used too */
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -42,10 +42,9 @@
+ #include <linux/pm_runtime.h>
+
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+
+ #include "usb.h"
+-#include "hcd.h"
+-#include "hub.h"
+
+
+ /*-------------------------------------------------------------------------*/
+--- a/drivers/usb/core/hcd.h
++++ /dev/null
+@@ -1,578 +0,0 @@
+-/*
+- * Copyright (c) 2001-2002 by David Brownell
+- *
+- * This program is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License as published by the
+- * Free Software Foundation; either version 2 of the License, or (at your
+- * option) any later version.
+- *
+- * 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.
+- */
+-
+-#ifndef __USB_CORE_HCD_H
+-#define __USB_CORE_HCD_H
+-
+-#ifdef __KERNEL__
+-
+-#include <linux/rwsem.h>
+-
+-#define MAX_TOPO_LEVEL 6
+-
+-/* This file contains declarations of usbcore internals that are mostly
+- * used or exposed by Host Controller Drivers.
+- */
+-
+-/*
+- * USB Packet IDs (PIDs)
+- */
+-#define USB_PID_EXT 0xf0 /* USB 2.0 LPM ECN */
+-#define USB_PID_OUT 0xe1
+-#define USB_PID_ACK 0xd2
+-#define USB_PID_DATA0 0xc3
+-#define USB_PID_PING 0xb4 /* USB 2.0 */
+-#define USB_PID_SOF 0xa5
+-#define USB_PID_NYET 0x96 /* USB 2.0 */
+-#define USB_PID_DATA2 0x87 /* USB 2.0 */
+-#define USB_PID_SPLIT 0x78 /* USB 2.0 */
+-#define USB_PID_IN 0x69
+-#define USB_PID_NAK 0x5a
+-#define USB_PID_DATA1 0x4b
+-#define USB_PID_PREAMBLE 0x3c /* Token mode */
+-#define USB_PID_ERR 0x3c /* USB 2.0: handshake mode */
+-#define USB_PID_SETUP 0x2d
+-#define USB_PID_STALL 0x1e
+-#define USB_PID_MDATA 0x0f /* USB 2.0 */
+-
+-/*-------------------------------------------------------------------------*/
+-
+-/*
+- * USB Host Controller Driver (usb_hcd) framework
+- *
+- * Since "struct usb_bus" is so thin, you can't share much code in it.
+- * This framework is a layer over that, and should be more sharable.
+- *
+- * @authorized_default: Specifies if new devices are authorized to
+- * connect by default or they require explicit
+- * user space authorization; this bit is settable
+- * through /sys/class/usb_host/X/authorized_default.
+- * For the rest is RO, so we don't lock to r/w it.
+- */
+-
+-/*-------------------------------------------------------------------------*/
+-
+-struct usb_hcd {
+-
+- /*
+- * housekeeping
+- */
+- struct usb_bus self; /* hcd is-a bus */
+- struct kref kref; /* reference counter */
+-
+- const char *product_desc; /* product/vendor string */
+- char irq_descr[24]; /* driver + bus # */
+-
+- struct timer_list rh_timer; /* drives root-hub polling */
+- struct urb *status_urb; /* the current status urb */
+-#ifdef CONFIG_USB_SUSPEND
+- struct work_struct wakeup_work; /* for remote wakeup */
+-#endif
+-
+- /*
+- * hardware info/state
+- */
+- const struct hc_driver *driver; /* hw-specific hooks */
+-
+- /* Flags that need to be manipulated atomically */
+- unsigned long flags;
+-#define HCD_FLAG_HW_ACCESSIBLE 0x00000001
+-#define HCD_FLAG_SAW_IRQ 0x00000002
+-
+- unsigned rh_registered:1;/* is root hub registered? */
+-
+- /* The next flag is a stopgap, to be removed when all the HCDs
+- * support the new root-hub polling mechanism. */
+- unsigned uses_new_polling:1;
+- unsigned poll_rh:1; /* poll for rh status? */
+- unsigned poll_pending:1; /* status has changed? */
+- unsigned wireless:1; /* Wireless USB HCD */
+- unsigned authorized_default:1;
+- unsigned has_tt:1; /* Integrated TT in root hub */
+-
+- int irq; /* irq allocated */
+- void __iomem *regs; /* device memory/io */
+- u64 rsrc_start; /* memory/io resource start */
+- u64 rsrc_len; /* memory/io resource length */
+- unsigned power_budget; /* in mA, 0 = no limit */
+-
+- /* bandwidth_mutex should be taken before adding or removing
+- * any new bus bandwidth constraints:
+- * 1. Before adding a configuration for a new device.
+- * 2. Before removing the configuration to put the device into
+- * the addressed state.
+- * 3. Before selecting a different configuration.
+- * 4. Before selecting an alternate interface setting.
+- *
+- * bandwidth_mutex should be dropped after a successful control message
+- * to the device, or resetting the bandwidth after a failed attempt.
+- */
+- struct mutex bandwidth_mutex;
+-
+-
+-#define HCD_BUFFER_POOLS 4
+- struct dma_pool *pool [HCD_BUFFER_POOLS];
+-
+- int state;
+-# define __ACTIVE 0x01
+-# define __SUSPEND 0x04
+-# define __TRANSIENT 0x80
+-
+-# define HC_STATE_HALT 0
+-# define HC_STATE_RUNNING (__ACTIVE)
+-# define HC_STATE_QUIESCING (__SUSPEND|__TRANSIENT|__ACTIVE)
+-# define HC_STATE_RESUMING (__SUSPEND|__TRANSIENT)
+-# define HC_STATE_SUSPENDED (__SUSPEND)
+-
+-#define HC_IS_RUNNING(state) ((state) & __ACTIVE)
+-#define HC_IS_SUSPENDED(state) ((state) & __SUSPEND)
+-
+- /* more shared queuing code would be good; it should support
+- * smarter scheduling, handle transaction translators, etc;
+- * input size of periodic table to an interrupt scheduler.
+- * (ohci 32, uhci 1024, ehci 256/512/1024).
+- */
+-
+- /* The HC driver's private data is stored at the end of
+- * this structure.
+- */
+- unsigned long hcd_priv[0]
+- __attribute__ ((aligned(sizeof(unsigned long))));
+-};
+-
+-/* 2.4 does this a bit differently ... */
+-static inline struct usb_bus *hcd_to_bus(struct usb_hcd *hcd)
+-{
+- return &hcd->self;
+-}
+-
+-static inline struct usb_hcd *bus_to_hcd(struct usb_bus *bus)
+-{
+- return container_of(bus, struct usb_hcd, self);
+-}
+-
+-struct hcd_timeout { /* timeouts we allocate */
+- struct list_head timeout_list;
+- struct timer_list timer;
+-};
+-
+-/*-------------------------------------------------------------------------*/
+-
+-
+-struct hc_driver {
+- const char *description; /* "ehci-hcd" etc */
+- const char *product_desc; /* product/vendor string */
+- size_t hcd_priv_size; /* size of private data */
+-
+- /* irq handler */
+- irqreturn_t (*irq) (struct usb_hcd *hcd);
+-
+- int flags;
+-#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
+-#define HCD_LOCAL_MEM 0x0002 /* HC needs local memory */
+-#define HCD_USB11 0x0010 /* USB 1.1 */
+-#define HCD_USB2 0x0020 /* USB 2.0 */
+-#define HCD_USB3 0x0040 /* USB 3.0 */
+-#define HCD_MASK 0x0070
+-
+- /* called to init HCD and root hub */
+- int (*reset) (struct usb_hcd *hcd);
+- int (*start) (struct usb_hcd *hcd);
+-
+- /* NOTE: these suspend/resume calls relate to the HC as
+- * a whole, not just the root hub; they're for PCI bus glue.
+- */
+- /* called after suspending the hub, before entering D3 etc */
+- int (*pci_suspend)(struct usb_hcd *hcd);
+-
+- /* called after entering D0 (etc), before resuming the hub */
+- int (*pci_resume)(struct usb_hcd *hcd, bool hibernated);
+-
+- /* cleanly make HCD stop writing memory and doing I/O */
+- void (*stop) (struct usb_hcd *hcd);
+-
+- /* shutdown HCD */
+- void (*shutdown) (struct usb_hcd *hcd);
+-
+- /* return current frame number */
+- int (*get_frame_number) (struct usb_hcd *hcd);
+-
+- /* manage i/o requests, device state */
+- int (*urb_enqueue)(struct usb_hcd *hcd,
+- struct urb *urb, gfp_t mem_flags);
+- int (*urb_dequeue)(struct usb_hcd *hcd,
+- struct urb *urb, int status);
+-
+- /* hw synch, freeing endpoint resources that urb_dequeue can't */
+- void (*endpoint_disable)(struct usb_hcd *hcd,
+- struct usb_host_endpoint *ep);
+-
+- /* (optional) reset any endpoint state such as sequence number
+- and current window */
+- void (*endpoint_reset)(struct usb_hcd *hcd,
+- struct usb_host_endpoint *ep);
+-
+- /* root hub support */
+- int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
+- int (*hub_control) (struct usb_hcd *hcd,
+- u16 typeReq, u16 wValue, u16 wIndex,
+- char *buf, u16 wLength);
+- int (*bus_suspend)(struct usb_hcd *);
+- int (*bus_resume)(struct usb_hcd *);
+- int (*start_port_reset)(struct usb_hcd *, unsigned port_num);
+-
+- /* force handover of high-speed port to full-speed companion */
+- void (*relinquish_port)(struct usb_hcd *, int);
+- /* has a port been handed over to a companion? */
+- int (*port_handed_over)(struct usb_hcd *, int);
+-
+- /* CLEAR_TT_BUFFER completion callback */
+- void (*clear_tt_buffer_complete)(struct usb_hcd *,
+- struct usb_host_endpoint *);
+-
+- /* xHCI specific functions */
+- /* Called by usb_alloc_dev to alloc HC device structures */
+- int (*alloc_dev)(struct usb_hcd *, struct usb_device *);
+- /* Called by usb_disconnect to free HC device structures */
+- void (*free_dev)(struct usb_hcd *, struct usb_device *);
+-
+- /* Bandwidth computation functions */
+- /* Note that add_endpoint() can only be called once per endpoint before
+- * check_bandwidth() or reset_bandwidth() must be called.
+- * drop_endpoint() can only be called once per endpoint also.
+- * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will
+- * add the endpoint to the schedule with possibly new parameters denoted by a
+- * different endpoint descriptor in usb_host_endpoint.
+- * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is
+- * not allowed.
+- */
+- /* Allocate endpoint resources and add them to a new schedule */
+- int (*add_endpoint)(struct usb_hcd *, struct usb_device *, struct usb_host_endpoint *);
+- /* Drop an endpoint from a new schedule */
+- int (*drop_endpoint)(struct usb_hcd *, struct usb_device *, struct usb_host_endpoint *);
+- /* Check that a new hardware configuration, set using
+- * endpoint_enable and endpoint_disable, does not exceed bus
+- * bandwidth. This must be called before any set configuration
+- * or set interface requests are sent to the device.
+- */
+- int (*check_bandwidth)(struct usb_hcd *, struct usb_device *);
+- /* Reset the device schedule to the last known good schedule,
+- * which was set from a previous successful call to
+- * check_bandwidth(). This reverts any add_endpoint() and
+- * drop_endpoint() calls since that last successful call.
+- * Used for when a check_bandwidth() call fails due to resource
+- * or bandwidth constraints.
+- */
+- void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *);
+- /* Returns the hardware-chosen device address */
+- int (*address_device)(struct usb_hcd *, struct usb_device *udev);
+- /* Notifies the HCD after a hub descriptor is fetched.
+- * Will block.
+- */
+- 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 *);
+-};
+-
+-extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
+-extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,
+- int status);
+-extern void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb);
+-
+-extern int usb_hcd_submit_urb(struct urb *urb, gfp_t mem_flags);
+-extern int usb_hcd_unlink_urb(struct urb *urb, int status);
+-extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb,
+- int status);
+-extern void usb_hcd_flush_endpoint(struct usb_device *udev,
+- struct usb_host_endpoint *ep);
+-extern void usb_hcd_disable_endpoint(struct usb_device *udev,
+- struct usb_host_endpoint *ep);
+-extern void usb_hcd_reset_endpoint(struct usb_device *udev,
+- struct usb_host_endpoint *ep);
+-extern void usb_hcd_synchronize_unlinks(struct usb_device *udev);
+-extern int usb_hcd_alloc_bandwidth(struct usb_device *udev,
+- struct usb_host_config *new_config,
+- struct usb_host_interface *old_alt,
+- struct usb_host_interface *new_alt);
+-extern int usb_hcd_get_frame_number(struct usb_device *udev);
+-
+-extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
+- struct device *dev, const char *bus_name);
+-extern struct usb_hcd *usb_get_hcd(struct usb_hcd *hcd);
+-extern void usb_put_hcd(struct usb_hcd *hcd);
+-extern int usb_add_hcd(struct usb_hcd *hcd,
+- unsigned int irqnum, unsigned long irqflags);
+-extern void usb_remove_hcd(struct usb_hcd *hcd);
+-
+-struct platform_device;
+-extern void usb_hcd_platform_shutdown(struct platform_device *dev);
+-
+-#ifdef CONFIG_PCI
+-struct pci_dev;
+-struct pci_device_id;
+-extern int usb_hcd_pci_probe(struct pci_dev *dev,
+- const struct pci_device_id *id);
+-extern void usb_hcd_pci_remove(struct pci_dev *dev);
+-extern void usb_hcd_pci_shutdown(struct pci_dev *dev);
+-
+-#ifdef CONFIG_PM_SLEEP
+-extern const struct dev_pm_ops usb_hcd_pci_pm_ops;
+-#endif
+-#endif /* CONFIG_PCI */
+-
+-/* pci-ish (pdev null is ok) buffer alloc/mapping support */
+-int hcd_buffer_create(struct usb_hcd *hcd);
+-void hcd_buffer_destroy(struct usb_hcd *hcd);
+-
+-void *hcd_buffer_alloc(struct usb_bus *bus, size_t size,
+- gfp_t mem_flags, dma_addr_t *dma);
+-void hcd_buffer_free(struct usb_bus *bus, size_t size,
+- void *addr, dma_addr_t dma);
+-
+-/* generic bus glue, needed for host controllers that don't use PCI */
+-extern irqreturn_t usb_hcd_irq(int irq, void *__hcd);
+-
+-extern void usb_hc_died(struct usb_hcd *hcd);
+-extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
+-
+-/* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */
+-#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1)
+-#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep)))
+-#define usb_settoggle(dev, ep, out, bit) \
+- ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \
+- ((bit) << (ep)))
+-
+-/* -------------------------------------------------------------------------- */
+-
+-/* Enumeration is only for the hub driver, or HCD virtual root hubs */
+-extern struct usb_device *usb_alloc_dev(struct usb_device *parent,
+- struct usb_bus *, unsigned port);
+-extern int usb_new_device(struct usb_device *dev);
+-extern void usb_disconnect(struct usb_device **);
+-
+-extern int usb_get_configuration(struct usb_device *dev);
+-extern void usb_destroy_configuration(struct usb_device *dev);
+-
+-/*-------------------------------------------------------------------------*/
+-
+-/*
+- * HCD Root Hub support
+- */
+-
+-#include "hub.h"
+-
+-/* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */
+-#define DeviceRequest \
+- ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
+-#define DeviceOutRequest \
+- ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
+-
+-#define InterfaceRequest \
+- ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
+-
+-#define EndpointRequest \
+- ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
+-#define EndpointOutRequest \
+- ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
+-
+-/* class requests from the USB 2.0 hub spec, table 11-15 */
+-/* GetBusState and SetHubDescriptor are optional, omitted */
+-#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE)
+-#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE)
+-#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR)
+-#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS)
+-#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS)
+-#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE)
+-#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
+-
+-
+-/*-------------------------------------------------------------------------*/
+-
+-/*
+- * Generic bandwidth allocation constants/support
+- */
+-#define FRAME_TIME_USECS 1000L
+-#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */
+- /* Trying not to use worst-case bit-stuffing
+- * of (7/6 * 8 * bytecount) = 9.33 * bytecount */
+- /* bytecount = data payload byte count */
+-
+-#define NS_TO_US(ns) ((ns + 500L) / 1000L)
+- /* convert & round nanoseconds to microseconds */
+-
+-
+-/*
+- * Full/low speed bandwidth allocation constants/support.
+- */
+-#define BW_HOST_DELAY 1000L /* nanoseconds */
+-#define BW_HUB_LS_SETUP 333L /* nanoseconds */
+- /* 4 full-speed bit times (est.) */
+-
+-#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */
+-#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L)
+-#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L)
+-
+-/*
+- * Ceiling [nano/micro]seconds (typical) for that many bytes at high speed
+- * ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed
+- * to preallocate bandwidth)
+- */
+-#define USB2_HOST_DELAY 5 /* nsec, guess */
+-#define HS_NSECS(bytes) (((55 * 8 * 2083) \
+- + (2083UL * (3 + BitTime(bytes))))/1000 \
+- + USB2_HOST_DELAY)
+-#define HS_NSECS_ISO(bytes) (((38 * 8 * 2083) \
+- + (2083UL * (3 + BitTime(bytes))))/1000 \
+- + USB2_HOST_DELAY)
+-#define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes))
+-#define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes))
+-
+-extern long usb_calc_bus_time(int speed, int is_input,
+- int isoc, int bytecount);
+-
+-/*-------------------------------------------------------------------------*/
+-
+-extern void usb_set_device_state(struct usb_device *udev,
+- enum usb_device_state new_state);
+-
+-/*-------------------------------------------------------------------------*/
+-
+-/* exported only within usbcore */
+-
+-extern struct list_head usb_bus_list;
+-extern struct mutex usb_bus_list_lock;
+-extern wait_queue_head_t usb_kill_urb_queue;
+-
+-extern int usb_find_interface_driver(struct usb_device *dev,
+- struct usb_interface *interface);
+-
+-#define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN))
+-
+-#ifdef CONFIG_PM
+-extern void usb_root_hub_lost_power(struct usb_device *rhdev);
+-extern int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg);
+-extern int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg);
+-#endif /* CONFIG_PM */
+-
+-#ifdef CONFIG_USB_SUSPEND
+-extern void usb_hcd_resume_root_hub(struct usb_hcd *hcd);
+-#else
+-static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd)
+-{
+- return;
+-}
+-#endif /* CONFIG_USB_SUSPEND */
+-
+-
+-/*
+- * USB device fs stuff
+- */
+-
+-#ifdef CONFIG_USB_DEVICEFS
+-
+-/*
+- * these are expected to be called from the USB core/hub thread
+- * with the kernel lock held
+- */
+-extern void usbfs_update_special(void);
+-extern int usbfs_init(void);
+-extern void usbfs_cleanup(void);
+-
+-#else /* CONFIG_USB_DEVICEFS */
+-
+-static inline void usbfs_update_special(void) {}
+-static inline int usbfs_init(void) { return 0; }
+-static inline void usbfs_cleanup(void) { }
+-
+-#endif /* CONFIG_USB_DEVICEFS */
+-
+-/*-------------------------------------------------------------------------*/
+-
+-#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
+-
+-struct usb_mon_operations {
+- void (*urb_submit)(struct usb_bus *bus, struct urb *urb);
+- void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err);
+- void (*urb_complete)(struct usb_bus *bus, struct urb *urb, int status);
+- /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */
+-};
+-
+-extern struct usb_mon_operations *mon_ops;
+-
+-static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb)
+-{
+- if (bus->monitored)
+- (*mon_ops->urb_submit)(bus, urb);
+-}
+-
+-static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb,
+- int error)
+-{
+- if (bus->monitored)
+- (*mon_ops->urb_submit_error)(bus, urb, error);
+-}
+-
+-static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb,
+- int status)
+-{
+- if (bus->monitored)
+- (*mon_ops->urb_complete)(bus, urb, status);
+-}
+-
+-int usb_mon_register(struct usb_mon_operations *ops);
+-void usb_mon_deregister(void);
+-
+-#else
+-
+-static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) {}
+-static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb,
+- int error) {}
+-static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb,
+- int status) {}
+-
+-#endif /* CONFIG_USB_MON || CONFIG_USB_MON_MODULE */
+-
+-/*-------------------------------------------------------------------------*/
+-
+-/* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */
+-/* bleech -- resurfaced in 2.4.11 or 2.4.12 */
+-#define bitmap DeviceRemovable
+-
+-
+-/*-------------------------------------------------------------------------*/
+-
+-/* random stuff */
+-
+-#define RUN_CONTEXT (in_irq() ? "in_irq" \
+- : (in_interrupt() ? "in_interrupt" : "can sleep"))
+-
+-
+-/* This rwsem is for use only by the hub driver and ehci-hcd.
+- * Nobody else should touch it.
+- */
+-extern struct rw_semaphore ehci_cf_port_reset_rwsem;
+-
+-/* Keep track of which host controller drivers are loaded */
+-#define USB_UHCI_LOADED 0
+-#define USB_OHCI_LOADED 1
+-#define USB_EHCI_LOADED 2
+-extern unsigned long usb_hcds_loaded;
+-
+-#endif /* __KERNEL__ */
+-
+-#endif /* __USB_CORE_HCD_H */
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -19,6 +19,7 @@
+ #include <linux/ioctl.h>
+ #include <linux/usb.h>
+ #include <linux/usbdevice_fs.h>
++#include <linux/usb/hcd.h>
+ #include <linux/kthread.h>
+ #include <linux/mutex.h>
+ #include <linux/freezer.h>
+@@ -28,8 +29,6 @@
+ #include <asm/byteorder.h>
+
+ #include "usb.h"
+-#include "hcd.h"
+-#include "hub.h"
+
+ /* if we are in debug mode, always announce new devices */
+ #ifdef DEBUG
+--- a/drivers/usb/core/inode.c
++++ b/drivers/usb/core/inode.c
+@@ -40,9 +40,9 @@
+ #include <linux/notifier.h>
+ #include <linux/seq_file.h>
+ #include <linux/smp_lock.h>
++#include <linux/usb/hcd.h>
+ #include <asm/byteorder.h>
+ #include "usb.h"
+-#include "hcd.h"
+
+ #define USBFS_DEFAULT_DEVMODE (S_IWUSR | S_IRUGO)
+ #define USBFS_DEFAULT_BUSMODE (S_IXUGO | S_IRUGO)
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -14,9 +14,9 @@
+ #include <linux/device.h>
+ #include <linux/scatterlist.h>
+ #include <linux/usb/quirks.h>
++#include <linux/usb/hcd.h> /* for usbcore internals */
+ #include <asm/byteorder.h>
+
+-#include "hcd.h" /* for usbcore internals */
+ #include "usb.h"
+
+ static void cancel_async_set_config(struct usb_device *udev);
+--- a/drivers/usb/core/urb.c
++++ b/drivers/usb/core/urb.c
+@@ -6,7 +6,7 @@
+ #include <linux/log2.h>
+ #include <linux/usb.h>
+ #include <linux/wait.h>
+-#include "hcd.h"
++#include <linux/usb/hcd.h>
+
+ #define to_urb(d) container_of(d, struct urb, kref)
+
+--- a/drivers/usb/core/usb.c
++++ b/drivers/usb/core/usb.c
+@@ -32,6 +32,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/errno.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #include <linux/mutex.h>
+ #include <linux/workqueue.h>
+ #include <linux/debugfs.h>
+@@ -41,7 +42,6 @@
+ #include <linux/mm.h>
+ #include <linux/dma-mapping.h>
+
+-#include "hcd.h"
+ #include "usb.h"
+
+
+--- a/drivers/usb/gadget/dummy_hcd.c
++++ b/drivers/usb/gadget/dummy_hcd.c
+@@ -47,6 +47,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/usb.h>
+ #include <linux/usb/gadget.h>
++#include <linux/usb/hcd.h>
+
+ #include <asm/byteorder.h>
+ #include <asm/io.h>
+@@ -55,9 +56,6 @@
+ #include <asm/unaligned.h>
+
+
+-#include "../core/hcd.h"
+-
+-
+ #define DRIVER_DESC "USB Host+Gadget Emulator"
+ #define DRIVER_VERSION "02 May 2005"
+
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -31,13 +31,12 @@
+ #include <linux/list.h>
+ #include <linux/interrupt.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #include <linux/moduleparam.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/debugfs.h>
+ #include <linux/slab.h>
+
+-#include "../core/hcd.h"
+-
+ #include <asm/byteorder.h>
+ #include <asm/io.h>
+ #include <asm/irq.h>
+--- a/drivers/usb/host/fhci-dbg.c
++++ b/drivers/usb/host/fhci-dbg.c
+@@ -20,7 +20,7 @@
+ #include <linux/debugfs.h>
+ #include <linux/seq_file.h>
+ #include <linux/usb.h>
+-#include "../core/hcd.h"
++#include <linux/usb/hcd.h>
+ #include "fhci.h"
+
+ void fhci_dbg_isr(struct fhci_hcd *fhci, int usb_er)
+--- a/drivers/usb/host/fhci-hcd.c
++++ b/drivers/usb/host/fhci-hcd.c
+@@ -25,12 +25,12 @@
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #include <linux/of_platform.h>
+ #include <linux/of_gpio.h>
+ #include <linux/slab.h>
+ #include <asm/qe.h>
+ #include <asm/fsl_gtm.h>
+-#include "../core/hcd.h"
+ #include "fhci.h"
+
+ void fhci_start_sof_timer(struct fhci_hcd *fhci)
+--- a/drivers/usb/host/fhci-hub.c
++++ b/drivers/usb/host/fhci-hub.c
+@@ -22,9 +22,9 @@
+ #include <linux/errno.h>
+ #include <linux/io.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #include <linux/gpio.h>
+ #include <asm/qe.h>
+-#include "../core/hcd.h"
+ #include "fhci.h"
+
+ /* virtual root hub specific descriptor */
+--- a/drivers/usb/host/fhci-mem.c
++++ b/drivers/usb/host/fhci-mem.c
+@@ -21,7 +21,7 @@
+ #include <linux/slab.h>
+ #include <linux/list.h>
+ #include <linux/usb.h>
+-#include "../core/hcd.h"
++#include <linux/usb/hcd.h>
+ #include "fhci.h"
+
+ static void init_td(struct td *td)
+--- a/drivers/usb/host/fhci-q.c
++++ b/drivers/usb/host/fhci-q.c
+@@ -22,7 +22,7 @@
+ #include <linux/slab.h>
+ #include <linux/list.h>
+ #include <linux/usb.h>
+-#include "../core/hcd.h"
++#include <linux/usb/hcd.h>
+ #include "fhci.h"
+
+ /* maps the hardware error code to the USB error code */
+--- a/drivers/usb/host/fhci-sched.c
++++ b/drivers/usb/host/fhci-sched.c
+@@ -24,9 +24,9 @@
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #include <asm/qe.h>
+ #include <asm/fsl_gtm.h>
+-#include "../core/hcd.h"
+ #include "fhci.h"
+
+ static void recycle_frame(struct fhci_usb *usb, struct packet *pkt)
+--- a/drivers/usb/host/fhci-tds.c
++++ b/drivers/usb/host/fhci-tds.c
+@@ -22,7 +22,7 @@
+ #include <linux/list.h>
+ #include <linux/io.h>
+ #include <linux/usb.h>
+-#include "../core/hcd.h"
++#include <linux/usb/hcd.h>
+ #include "fhci.h"
+
+ #define DUMMY_BD_BUFFER 0xdeadbeef
+--- a/drivers/usb/host/fhci.h
++++ b/drivers/usb/host/fhci.h
+@@ -25,8 +25,8 @@
+ #include <linux/kfifo.h>
+ #include <linux/io.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #include <asm/qe.h>
+-#include "../core/hcd.h"
+
+ #define USB_CLOCK 48000000
+
+--- a/drivers/usb/host/imx21-hcd.c
++++ b/drivers/usb/host/imx21-hcd.c
+@@ -56,8 +56,8 @@
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+
+-#include "../core/hcd.h"
+ #include "imx21-hcd.h"
+
+ #ifdef DEBUG
+--- a/drivers/usb/host/isp116x-hcd.c
++++ b/drivers/usb/host/isp116x-hcd.c
+@@ -65,6 +65,7 @@
+ #include <linux/slab.h>
+ #include <linux/usb.h>
+ #include <linux/usb/isp116x.h>
++#include <linux/usb/hcd.h>
+ #include <linux/platform_device.h>
+
+ #include <asm/io.h>
+@@ -72,7 +73,6 @@
+ #include <asm/system.h>
+ #include <asm/byteorder.h>
+
+-#include "../core/hcd.h"
+ #include "isp116x.h"
+
+ #define DRIVER_VERSION "03 Nov 2005"
+--- a/drivers/usb/host/isp1362-hcd.c
++++ b/drivers/usb/host/isp1362-hcd.c
+@@ -77,6 +77,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/usb.h>
+ #include <linux/usb/isp1362.h>
++#include <linux/usb/hcd.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm.h>
+ #include <linux/io.h>
+@@ -95,7 +96,6 @@ module_param(dbg_level, int, 0);
+ #define STUB_DEBUG_FILE
+ #endif
+
+-#include "../core/hcd.h"
+ #include "../core/usb.h"
+ #include "isp1362.h"
+
+--- a/drivers/usb/host/isp1760-hcd.c
++++ b/drivers/usb/host/isp1760-hcd.c
+@@ -14,6 +14,7 @@
+ #include <linux/slab.h>
+ #include <linux/list.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #include <linux/debugfs.h>
+ #include <linux/uaccess.h>
+ #include <linux/io.h>
+@@ -21,7 +22,6 @@
+ #include <asm/unaligned.h>
+ #include <asm/cacheflush.h>
+
+-#include "../core/hcd.h"
+ #include "isp1760-hcd.h"
+
+ static struct kmem_cache *qtd_cachep;
+--- a/drivers/usb/host/isp1760-if.c
++++ b/drivers/usb/host/isp1760-if.c
+@@ -13,8 +13,8 @@
+ #include <linux/io.h>
+ #include <linux/platform_device.h>
+ #include <linux/usb/isp1760.h>
++#include <linux/usb/hcd.h>
+
+-#include "../core/hcd.h"
+ #include "isp1760-hcd.h"
+
+ #ifdef CONFIG_PPC_OF
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -32,6 +32,7 @@
+ #include <linux/list.h>
+ #include <linux/usb.h>
+ #include <linux/usb/otg.h>
++#include <linux/usb/hcd.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/dmapool.h>
+ #include <linux/workqueue.h>
+@@ -43,7 +44,6 @@
+ #include <asm/unaligned.h>
+ #include <asm/byteorder.h>
+
+-#include "../core/hcd.h"
+
+ #define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
+ #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
+--- a/drivers/usb/host/oxu210hp-hcd.c
++++ b/drivers/usb/host/oxu210hp-hcd.c
+@@ -34,12 +34,11 @@
+ #include <linux/list.h>
+ #include <linux/interrupt.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #include <linux/moduleparam.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/io.h>
+
+-#include "../core/hcd.h"
+-
+ #include <asm/irq.h>
+ #include <asm/system.h>
+ #include <asm/unaligned.h>
+--- a/drivers/usb/host/r8a66597-hcd.c
++++ b/drivers/usb/host/r8a66597-hcd.c
+@@ -33,6 +33,7 @@
+ #include <linux/list.h>
+ #include <linux/interrupt.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #include <linux/platform_device.h>
+ #include <linux/io.h>
+ #include <linux/mm.h>
+@@ -40,7 +41,6 @@
+ #include <linux/slab.h>
+ #include <asm/cacheflush.h>
+
+-#include "../core/hcd.h"
+ #include "r8a66597.h"
+
+ MODULE_DESCRIPTION("R8A66597 USB Host Controller Driver");
+--- a/drivers/usb/host/sl811-hcd.c
++++ b/drivers/usb/host/sl811-hcd.c
+@@ -45,6 +45,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/usb.h>
+ #include <linux/usb/sl811.h>
++#include <linux/usb/hcd.h>
+ #include <linux/platform_device.h>
+
+ #include <asm/io.h>
+@@ -53,7 +54,6 @@
+ #include <asm/byteorder.h>
+ #include <asm/unaligned.h>
+
+-#include "../core/hcd.h"
+ #include "sl811.h"
+
+
+--- a/drivers/usb/host/u132-hcd.c
++++ b/drivers/usb/host/u132-hcd.c
+@@ -49,6 +49,7 @@
+ #include <linux/list.h>
+ #include <linux/interrupt.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #include <linux/workqueue.h>
+ #include <linux/platform_device.h>
+ #include <linux/mutex.h>
+@@ -56,7 +57,6 @@
+ #include <asm/irq.h>
+ #include <asm/system.h>
+ #include <asm/byteorder.h>
+-#include "../core/hcd.h"
+
+ /* FIXME ohci.h is ONLY for internal use by the OHCI driver.
+ * If you're going to try stuff like this, you need to split
+--- a/drivers/usb/host/uhci-hcd.c
++++ b/drivers/usb/host/uhci-hcd.c
+@@ -38,6 +38,7 @@
+ #include <linux/dmapool.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #include <linux/bitops.h>
+ #include <linux/dmi.h>
+
+@@ -46,7 +47,6 @@
+ #include <asm/irq.h>
+ #include <asm/system.h>
+
+-#include "../core/hcd.h"
+ #include "uhci-hcd.h"
+ #include "pci-quirks.h"
+
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -26,8 +26,8 @@
+ #include <linux/usb.h>
+ #include <linux/timer.h>
+ #include <linux/kernel.h>
++#include <linux/usb/hcd.h>
+
+-#include "../core/hcd.h"
+ /* Code sharing between pci-quirks and xhci hcd */
+ #include "xhci-ext-caps.h"
+
+--- a/drivers/usb/misc/ftdi-elan.c
++++ b/drivers/usb/misc/ftdi-elan.c
+@@ -73,7 +73,7 @@ static struct list_head ftdi_static_list
+ */
+ #include "usb_u132.h"
+ #include <asm/io.h>
+-#include "../core/hcd.h"
++#include <linux/usb/hcd.h>
+
+ /* FIXME ohci.h is ONLY for internal use by the OHCI driver.
+ * If you're going to try stuff like this, you need to split
+--- a/drivers/usb/mon/mon_main.c
++++ b/drivers/usb/mon/mon_main.c
+@@ -9,12 +9,13 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #include <linux/slab.h>
+ #include <linux/notifier.h>
+ #include <linux/mutex.h>
+
+ #include "usb_mon.h"
+-#include "../core/hcd.h"
++
+
+ static void mon_stop(struct mon_bus *mbus);
+ static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus);
+--- a/drivers/usb/musb/musb_core.h
++++ b/drivers/usb/musb/musb_core.h
+@@ -69,7 +69,7 @@ struct musb_ep;
+ #include "musb_regs.h"
+
+ #include "musb_gadget.h"
+-#include "../core/hcd.h"
++#include <linux/usb/hcd.h>
+ #include "musb_host.h"
+
+
+--- a/drivers/usb/wusbcore/wusbhc.h
++++ b/drivers/usb/wusbcore/wusbhc.h
+@@ -58,9 +58,7 @@
+ #include <linux/mutex.h>
+ #include <linux/kref.h>
+ #include <linux/workqueue.h>
+-/* FIXME: Yes, I know: BAD--it's not my fault the USB HC iface is not
+- * public */
+-#include <linux/../../drivers/usb/core/hcd.h>
++#include <linux/usb/hcd.h>
+ #include <linux/uwb.h>
+ #include <linux/usb/wusb.h>
+
+--- /dev/null
++++ b/include/linux/usb/hcd.h
+@@ -0,0 +1,578 @@
++/*
++ * Copyright (c) 2001-2002 by David Brownell
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ * 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.
++ */
++
++#ifndef __USB_CORE_HCD_H
++#define __USB_CORE_HCD_H
++
++#ifdef __KERNEL__
++
++#include <linux/rwsem.h>
++
++#define MAX_TOPO_LEVEL 6
++
++/* This file contains declarations of usbcore internals that are mostly
++ * used or exposed by Host Controller Drivers.
++ */
++
++/*
++ * USB Packet IDs (PIDs)
++ */
++#define USB_PID_EXT 0xf0 /* USB 2.0 LPM ECN */
++#define USB_PID_OUT 0xe1
++#define USB_PID_ACK 0xd2
++#define USB_PID_DATA0 0xc3
++#define USB_PID_PING 0xb4 /* USB 2.0 */
++#define USB_PID_SOF 0xa5
++#define USB_PID_NYET 0x96 /* USB 2.0 */
++#define USB_PID_DATA2 0x87 /* USB 2.0 */
++#define USB_PID_SPLIT 0x78 /* USB 2.0 */
++#define USB_PID_IN 0x69
++#define USB_PID_NAK 0x5a
++#define USB_PID_DATA1 0x4b
++#define USB_PID_PREAMBLE 0x3c /* Token mode */
++#define USB_PID_ERR 0x3c /* USB 2.0: handshake mode */
++#define USB_PID_SETUP 0x2d
++#define USB_PID_STALL 0x1e
++#define USB_PID_MDATA 0x0f /* USB 2.0 */
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * USB Host Controller Driver (usb_hcd) framework
++ *
++ * Since "struct usb_bus" is so thin, you can't share much code in it.
++ * This framework is a layer over that, and should be more sharable.
++ *
++ * @authorized_default: Specifies if new devices are authorized to
++ * connect by default or they require explicit
++ * user space authorization; this bit is settable
++ * through /sys/class/usb_host/X/authorized_default.
++ * For the rest is RO, so we don't lock to r/w it.
++ */
++
++/*-------------------------------------------------------------------------*/
++
++struct usb_hcd {
++
++ /*
++ * housekeeping
++ */
++ struct usb_bus self; /* hcd is-a bus */
++ struct kref kref; /* reference counter */
++
++ const char *product_desc; /* product/vendor string */
++ char irq_descr[24]; /* driver + bus # */
++
++ struct timer_list rh_timer; /* drives root-hub polling */
++ struct urb *status_urb; /* the current status urb */
++#ifdef CONFIG_USB_SUSPEND
++ struct work_struct wakeup_work; /* for remote wakeup */
++#endif
++
++ /*
++ * hardware info/state
++ */
++ const struct hc_driver *driver; /* hw-specific hooks */
++
++ /* Flags that need to be manipulated atomically */
++ unsigned long flags;
++#define HCD_FLAG_HW_ACCESSIBLE 0x00000001
++#define HCD_FLAG_SAW_IRQ 0x00000002
++
++ unsigned rh_registered:1;/* is root hub registered? */
++
++ /* The next flag is a stopgap, to be removed when all the HCDs
++ * support the new root-hub polling mechanism. */
++ unsigned uses_new_polling:1;
++ unsigned poll_rh:1; /* poll for rh status? */
++ unsigned poll_pending:1; /* status has changed? */
++ unsigned wireless:1; /* Wireless USB HCD */
++ unsigned authorized_default:1;
++ unsigned has_tt:1; /* Integrated TT in root hub */
++
++ int irq; /* irq allocated */
++ void __iomem *regs; /* device memory/io */
++ u64 rsrc_start; /* memory/io resource start */
++ u64 rsrc_len; /* memory/io resource length */
++ unsigned power_budget; /* in mA, 0 = no limit */
++
++ /* bandwidth_mutex should be taken before adding or removing
++ * any new bus bandwidth constraints:
++ * 1. Before adding a configuration for a new device.
++ * 2. Before removing the configuration to put the device into
++ * the addressed state.
++ * 3. Before selecting a different configuration.
++ * 4. Before selecting an alternate interface setting.
++ *
++ * bandwidth_mutex should be dropped after a successful control message
++ * to the device, or resetting the bandwidth after a failed attempt.
++ */
++ struct mutex bandwidth_mutex;
++
++
++#define HCD_BUFFER_POOLS 4
++ struct dma_pool *pool [HCD_BUFFER_POOLS];
++
++ int state;
++# define __ACTIVE 0x01
++# define __SUSPEND 0x04
++# define __TRANSIENT 0x80
++
++# define HC_STATE_HALT 0
++# define HC_STATE_RUNNING (__ACTIVE)
++# define HC_STATE_QUIESCING (__SUSPEND|__TRANSIENT|__ACTIVE)
++# define HC_STATE_RESUMING (__SUSPEND|__TRANSIENT)
++# define HC_STATE_SUSPENDED (__SUSPEND)
++
++#define HC_IS_RUNNING(state) ((state) & __ACTIVE)
++#define HC_IS_SUSPENDED(state) ((state) & __SUSPEND)
++
++ /* more shared queuing code would be good; it should support
++ * smarter scheduling, handle transaction translators, etc;
++ * input size of periodic table to an interrupt scheduler.
++ * (ohci 32, uhci 1024, ehci 256/512/1024).
++ */
++
++ /* The HC driver's private data is stored at the end of
++ * this structure.
++ */
++ unsigned long hcd_priv[0]
++ __attribute__ ((aligned(sizeof(unsigned long))));
++};
++
++/* 2.4 does this a bit differently ... */
++static inline struct usb_bus *hcd_to_bus(struct usb_hcd *hcd)
++{
++ return &hcd->self;
++}
++
++static inline struct usb_hcd *bus_to_hcd(struct usb_bus *bus)
++{
++ return container_of(bus, struct usb_hcd, self);
++}
++
++struct hcd_timeout { /* timeouts we allocate */
++ struct list_head timeout_list;
++ struct timer_list timer;
++};
++
++/*-------------------------------------------------------------------------*/
++
++
++struct hc_driver {
++ const char *description; /* "ehci-hcd" etc */
++ const char *product_desc; /* product/vendor string */
++ size_t hcd_priv_size; /* size of private data */
++
++ /* irq handler */
++ irqreturn_t (*irq) (struct usb_hcd *hcd);
++
++ int flags;
++#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
++#define HCD_LOCAL_MEM 0x0002 /* HC needs local memory */
++#define HCD_USB11 0x0010 /* USB 1.1 */
++#define HCD_USB2 0x0020 /* USB 2.0 */
++#define HCD_USB3 0x0040 /* USB 3.0 */
++#define HCD_MASK 0x0070
++
++ /* called to init HCD and root hub */
++ int (*reset) (struct usb_hcd *hcd);
++ int (*start) (struct usb_hcd *hcd);
++
++ /* NOTE: these suspend/resume calls relate to the HC as
++ * a whole, not just the root hub; they're for PCI bus glue.
++ */
++ /* called after suspending the hub, before entering D3 etc */
++ int (*pci_suspend)(struct usb_hcd *hcd);
++
++ /* called after entering D0 (etc), before resuming the hub */
++ int (*pci_resume)(struct usb_hcd *hcd, bool hibernated);
++
++ /* cleanly make HCD stop writing memory and doing I/O */
++ void (*stop) (struct usb_hcd *hcd);
++
++ /* shutdown HCD */
++ void (*shutdown) (struct usb_hcd *hcd);
++
++ /* return current frame number */
++ int (*get_frame_number) (struct usb_hcd *hcd);
++
++ /* manage i/o requests, device state */
++ int (*urb_enqueue)(struct usb_hcd *hcd,
++ struct urb *urb, gfp_t mem_flags);
++ int (*urb_dequeue)(struct usb_hcd *hcd,
++ struct urb *urb, int status);
++
++ /* hw synch, freeing endpoint resources that urb_dequeue can't */
++ void (*endpoint_disable)(struct usb_hcd *hcd,
++ struct usb_host_endpoint *ep);
++
++ /* (optional) reset any endpoint state such as sequence number
++ and current window */
++ void (*endpoint_reset)(struct usb_hcd *hcd,
++ struct usb_host_endpoint *ep);
++
++ /* root hub support */
++ int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
++ int (*hub_control) (struct usb_hcd *hcd,
++ u16 typeReq, u16 wValue, u16 wIndex,
++ char *buf, u16 wLength);
++ int (*bus_suspend)(struct usb_hcd *);
++ int (*bus_resume)(struct usb_hcd *);
++ int (*start_port_reset)(struct usb_hcd *, unsigned port_num);
++
++ /* force handover of high-speed port to full-speed companion */
++ void (*relinquish_port)(struct usb_hcd *, int);
++ /* has a port been handed over to a companion? */
++ int (*port_handed_over)(struct usb_hcd *, int);
++
++ /* CLEAR_TT_BUFFER completion callback */
++ void (*clear_tt_buffer_complete)(struct usb_hcd *,
++ struct usb_host_endpoint *);
++
++ /* xHCI specific functions */
++ /* Called by usb_alloc_dev to alloc HC device structures */
++ int (*alloc_dev)(struct usb_hcd *, struct usb_device *);
++ /* Called by usb_disconnect to free HC device structures */
++ void (*free_dev)(struct usb_hcd *, struct usb_device *);
++
++ /* Bandwidth computation functions */
++ /* Note that add_endpoint() can only be called once per endpoint before
++ * check_bandwidth() or reset_bandwidth() must be called.
++ * drop_endpoint() can only be called once per endpoint also.
++ * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will
++ * add the endpoint to the schedule with possibly new parameters denoted by a
++ * different endpoint descriptor in usb_host_endpoint.
++ * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is
++ * not allowed.
++ */
++ /* Allocate endpoint resources and add them to a new schedule */
++ int (*add_endpoint)(struct usb_hcd *, struct usb_device *, struct usb_host_endpoint *);
++ /* Drop an endpoint from a new schedule */
++ int (*drop_endpoint)(struct usb_hcd *, struct usb_device *, struct usb_host_endpoint *);
++ /* Check that a new hardware configuration, set using
++ * endpoint_enable and endpoint_disable, does not exceed bus
++ * bandwidth. This must be called before any set configuration
++ * or set interface requests are sent to the device.
++ */
++ int (*check_bandwidth)(struct usb_hcd *, struct usb_device *);
++ /* Reset the device schedule to the last known good schedule,
++ * which was set from a previous successful call to
++ * check_bandwidth(). This reverts any add_endpoint() and
++ * drop_endpoint() calls since that last successful call.
++ * Used for when a check_bandwidth() call fails due to resource
++ * or bandwidth constraints.
++ */
++ void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *);
++ /* Returns the hardware-chosen device address */
++ int (*address_device)(struct usb_hcd *, struct usb_device *udev);
++ /* Notifies the HCD after a hub descriptor is fetched.
++ * Will block.
++ */
++ 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 *);
++};
++
++extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
++extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,
++ int status);
++extern void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb);
++
++extern int usb_hcd_submit_urb(struct urb *urb, gfp_t mem_flags);
++extern int usb_hcd_unlink_urb(struct urb *urb, int status);
++extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb,
++ int status);
++extern void usb_hcd_flush_endpoint(struct usb_device *udev,
++ struct usb_host_endpoint *ep);
++extern void usb_hcd_disable_endpoint(struct usb_device *udev,
++ struct usb_host_endpoint *ep);
++extern void usb_hcd_reset_endpoint(struct usb_device *udev,
++ struct usb_host_endpoint *ep);
++extern void usb_hcd_synchronize_unlinks(struct usb_device *udev);
++extern int usb_hcd_alloc_bandwidth(struct usb_device *udev,
++ struct usb_host_config *new_config,
++ struct usb_host_interface *old_alt,
++ struct usb_host_interface *new_alt);
++extern int usb_hcd_get_frame_number(struct usb_device *udev);
++
++extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
++ struct device *dev, const char *bus_name);
++extern struct usb_hcd *usb_get_hcd(struct usb_hcd *hcd);
++extern void usb_put_hcd(struct usb_hcd *hcd);
++extern int usb_add_hcd(struct usb_hcd *hcd,
++ unsigned int irqnum, unsigned long irqflags);
++extern void usb_remove_hcd(struct usb_hcd *hcd);
++
++struct platform_device;
++extern void usb_hcd_platform_shutdown(struct platform_device *dev);
++
++#ifdef CONFIG_PCI
++struct pci_dev;
++struct pci_device_id;
++extern int usb_hcd_pci_probe(struct pci_dev *dev,
++ const struct pci_device_id *id);
++extern void usb_hcd_pci_remove(struct pci_dev *dev);
++extern void usb_hcd_pci_shutdown(struct pci_dev *dev);
++
++#ifdef CONFIG_PM_SLEEP
++extern const struct dev_pm_ops usb_hcd_pci_pm_ops;
++#endif
++#endif /* CONFIG_PCI */
++
++/* pci-ish (pdev null is ok) buffer alloc/mapping support */
++int hcd_buffer_create(struct usb_hcd *hcd);
++void hcd_buffer_destroy(struct usb_hcd *hcd);
++
++void *hcd_buffer_alloc(struct usb_bus *bus, size_t size,
++ gfp_t mem_flags, dma_addr_t *dma);
++void hcd_buffer_free(struct usb_bus *bus, size_t size,
++ void *addr, dma_addr_t dma);
++
++/* generic bus glue, needed for host controllers that don't use PCI */
++extern irqreturn_t usb_hcd_irq(int irq, void *__hcd);
++
++extern void usb_hc_died(struct usb_hcd *hcd);
++extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
++
++/* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */
++#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1)
++#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep)))
++#define usb_settoggle(dev, ep, out, bit) \
++ ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \
++ ((bit) << (ep)))
++
++/* -------------------------------------------------------------------------- */
++
++/* Enumeration is only for the hub driver, or HCD virtual root hubs */
++extern struct usb_device *usb_alloc_dev(struct usb_device *parent,
++ struct usb_bus *, unsigned port);
++extern int usb_new_device(struct usb_device *dev);
++extern void usb_disconnect(struct usb_device **);
++
++extern int usb_get_configuration(struct usb_device *dev);
++extern void usb_destroy_configuration(struct usb_device *dev);
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * HCD Root Hub support
++ */
++
++#include <linux/../../drivers/usb/core/hub.h>
++
++/* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */
++#define DeviceRequest \
++ ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
++#define DeviceOutRequest \
++ ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
++
++#define InterfaceRequest \
++ ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
++
++#define EndpointRequest \
++ ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
++#define EndpointOutRequest \
++ ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
++
++/* class requests from the USB 2.0 hub spec, table 11-15 */
++/* GetBusState and SetHubDescriptor are optional, omitted */
++#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE)
++#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE)
++#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR)
++#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS)
++#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS)
++#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE)
++#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
++
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * Generic bandwidth allocation constants/support
++ */
++#define FRAME_TIME_USECS 1000L
++#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */
++ /* Trying not to use worst-case bit-stuffing
++ * of (7/6 * 8 * bytecount) = 9.33 * bytecount */
++ /* bytecount = data payload byte count */
++
++#define NS_TO_US(ns) ((ns + 500L) / 1000L)
++ /* convert & round nanoseconds to microseconds */
++
++
++/*
++ * Full/low speed bandwidth allocation constants/support.
++ */
++#define BW_HOST_DELAY 1000L /* nanoseconds */
++#define BW_HUB_LS_SETUP 333L /* nanoseconds */
++ /* 4 full-speed bit times (est.) */
++
++#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */
++#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L)
++#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L)
++
++/*
++ * Ceiling [nano/micro]seconds (typical) for that many bytes at high speed
++ * ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed
++ * to preallocate bandwidth)
++ */
++#define USB2_HOST_DELAY 5 /* nsec, guess */
++#define HS_NSECS(bytes) (((55 * 8 * 2083) \
++ + (2083UL * (3 + BitTime(bytes))))/1000 \
++ + USB2_HOST_DELAY)
++#define HS_NSECS_ISO(bytes) (((38 * 8 * 2083) \
++ + (2083UL * (3 + BitTime(bytes))))/1000 \
++ + USB2_HOST_DELAY)
++#define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes))
++#define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes))
++
++extern long usb_calc_bus_time(int speed, int is_input,
++ int isoc, int bytecount);
++
++/*-------------------------------------------------------------------------*/
++
++extern void usb_set_device_state(struct usb_device *udev,
++ enum usb_device_state new_state);
++
++/*-------------------------------------------------------------------------*/
++
++/* exported only within usbcore */
++
++extern struct list_head usb_bus_list;
++extern struct mutex usb_bus_list_lock;
++extern wait_queue_head_t usb_kill_urb_queue;
++
++extern int usb_find_interface_driver(struct usb_device *dev,
++ struct usb_interface *interface);
++
++#define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN))
++
++#ifdef CONFIG_PM
++extern void usb_root_hub_lost_power(struct usb_device *rhdev);
++extern int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg);
++extern int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg);
++#endif /* CONFIG_PM */
++
++#ifdef CONFIG_USB_SUSPEND
++extern void usb_hcd_resume_root_hub(struct usb_hcd *hcd);
++#else
++static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd)
++{
++ return;
++}
++#endif /* CONFIG_USB_SUSPEND */
++
++
++/*
++ * USB device fs stuff
++ */
++
++#ifdef CONFIG_USB_DEVICEFS
++
++/*
++ * these are expected to be called from the USB core/hub thread
++ * with the kernel lock held
++ */
++extern void usbfs_update_special(void);
++extern int usbfs_init(void);
++extern void usbfs_cleanup(void);
++
++#else /* CONFIG_USB_DEVICEFS */
++
++static inline void usbfs_update_special(void) {}
++static inline int usbfs_init(void) { return 0; }
++static inline void usbfs_cleanup(void) { }
++
++#endif /* CONFIG_USB_DEVICEFS */
++
++/*-------------------------------------------------------------------------*/
++
++#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
++
++struct usb_mon_operations {
++ void (*urb_submit)(struct usb_bus *bus, struct urb *urb);
++ void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err);
++ void (*urb_complete)(struct usb_bus *bus, struct urb *urb, int status);
++ /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */
++};
++
++extern struct usb_mon_operations *mon_ops;
++
++static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb)
++{
++ if (bus->monitored)
++ (*mon_ops->urb_submit)(bus, urb);
++}
++
++static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb,
++ int error)
++{
++ if (bus->monitored)
++ (*mon_ops->urb_submit_error)(bus, urb, error);
++}
++
++static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb,
++ int status)
++{
++ if (bus->monitored)
++ (*mon_ops->urb_complete)(bus, urb, status);
++}
++
++int usb_mon_register(struct usb_mon_operations *ops);
++void usb_mon_deregister(void);
++
++#else
++
++static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) {}
++static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb,
++ int error) {}
++static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb,
++ int status) {}
++
++#endif /* CONFIG_USB_MON || CONFIG_USB_MON_MODULE */
++
++/*-------------------------------------------------------------------------*/
++
++/* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */
++/* bleech -- resurfaced in 2.4.11 or 2.4.12 */
++#define bitmap DeviceRemovable
++
++
++/*-------------------------------------------------------------------------*/
++
++/* random stuff */
++
++#define RUN_CONTEXT (in_irq() ? "in_irq" \
++ : (in_interrupt() ? "in_interrupt" : "can sleep"))
++
++
++/* This rwsem is for use only by the hub driver and ehci-hcd.
++ * Nobody else should touch it.
++ */
++extern struct rw_semaphore ehci_cf_port_reset_rwsem;
++
++/* Keep track of which host controller drivers are loaded */
++#define USB_UHCI_LOADED 0
++#define USB_OHCI_LOADED 1
++#define USB_EHCI_LOADED 2
++extern unsigned long usb_hcds_loaded;
++
++#endif /* __KERNEL__ */
++
++#endif /* __USB_CORE_HCD_H */
diff --git a/usb/usb-make-hub.h-public-drivers-dependency.patch b/usb/usb-make-hub.h-public-drivers-dependency.patch
new file mode 100644
index 00000000000000..c6eaa9cd37a4f6
--- /dev/null
+++ b/usb/usb-make-hub.h-public-drivers-dependency.patch
@@ -0,0 +1,451 @@
+From Eric.Lescouet@virtuallogix.com Thu Apr 29 16:13:33 2010
+From: Eric Lescouet <Eric.Lescouet@virtuallogix.com>
+Date: Sat, 24 Apr 2010 23:34:27 +0200
+Subject: USB: make hub.h public (drivers dependency)
+To: Greg KH <greg@kroah.com>
+Message-ID: <1272144867.2517.1.camel@localhost>
+
+
+The usbcore headers: hcd.h and hub.h are shared between usbcore,
+HCDs and a couple of other drivers (e.g. USBIP modules).
+So, it makes sense to move them into a more public location and
+to cleanup dependency of those modules on kernel internal headers.
+This patch moves hub.h from drivers/usb/core into include/linux/usb/
+
+Signed-of-by: Eric Lescouet <eric@lescouet.org>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/hub.h | 205 ------------------------------------------------
+ include/linux/usb/hcd.h | 2
+ include/linux/usb/hub.h | 205 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 206 insertions(+), 206 deletions(-)
+
+--- a/drivers/usb/core/hub.h
++++ /dev/null
+@@ -1,205 +0,0 @@
+-#ifndef __LINUX_HUB_H
+-#define __LINUX_HUB_H
+-
+-/*
+- * Hub protocol and driver data structures.
+- *
+- * Some of these are known to the "virtual root hub" code
+- * in host controller drivers.
+- */
+-
+-#include <linux/list.h>
+-#include <linux/workqueue.h>
+-#include <linux/compiler.h> /* likely()/unlikely() */
+-
+-/*
+- * Hub request types
+- */
+-
+-#define USB_RT_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE)
+-#define USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
+-
+-/*
+- * Hub class requests
+- * See USB 2.0 spec Table 11-16
+- */
+-#define HUB_CLEAR_TT_BUFFER 8
+-#define HUB_RESET_TT 9
+-#define HUB_GET_TT_STATE 10
+-#define HUB_STOP_TT 11
+-
+-/*
+- * Hub Class feature numbers
+- * See USB 2.0 spec Table 11-17
+- */
+-#define C_HUB_LOCAL_POWER 0
+-#define C_HUB_OVER_CURRENT 1
+-
+-/*
+- * Port feature numbers
+- * See USB 2.0 spec Table 11-17
+- */
+-#define USB_PORT_FEAT_CONNECTION 0
+-#define USB_PORT_FEAT_ENABLE 1
+-#define USB_PORT_FEAT_SUSPEND 2 /* L2 suspend */
+-#define USB_PORT_FEAT_OVER_CURRENT 3
+-#define USB_PORT_FEAT_RESET 4
+-#define USB_PORT_FEAT_L1 5 /* L1 suspend */
+-#define USB_PORT_FEAT_POWER 8
+-#define USB_PORT_FEAT_LOWSPEED 9
+-/* This value was never in Table 11-17 */
+-#define USB_PORT_FEAT_HIGHSPEED 10
+-/* This value is also fake */
+-#define USB_PORT_FEAT_SUPERSPEED 11
+-#define USB_PORT_FEAT_C_CONNECTION 16
+-#define USB_PORT_FEAT_C_ENABLE 17
+-#define USB_PORT_FEAT_C_SUSPEND 18
+-#define USB_PORT_FEAT_C_OVER_CURRENT 19
+-#define USB_PORT_FEAT_C_RESET 20
+-#define USB_PORT_FEAT_TEST 21
+-#define USB_PORT_FEAT_INDICATOR 22
+-#define USB_PORT_FEAT_C_PORT_L1 23
+-
+-/*
+- * Hub Status and Hub Change results
+- * See USB 2.0 spec Table 11-19 and Table 11-20
+- */
+-struct usb_port_status {
+- __le16 wPortStatus;
+- __le16 wPortChange;
+-} __attribute__ ((packed));
+-
+-/*
+- * wPortStatus bit field
+- * See USB 2.0 spec Table 11-21
+- */
+-#define USB_PORT_STAT_CONNECTION 0x0001
+-#define USB_PORT_STAT_ENABLE 0x0002
+-#define USB_PORT_STAT_SUSPEND 0x0004
+-#define USB_PORT_STAT_OVERCURRENT 0x0008
+-#define USB_PORT_STAT_RESET 0x0010
+-#define USB_PORT_STAT_L1 0x0020
+-/* bits 6 to 7 are reserved */
+-#define USB_PORT_STAT_POWER 0x0100
+-#define USB_PORT_STAT_LOW_SPEED 0x0200
+-#define USB_PORT_STAT_HIGH_SPEED 0x0400
+-#define USB_PORT_STAT_TEST 0x0800
+-#define USB_PORT_STAT_INDICATOR 0x1000
+-/* bits 13 to 15 are reserved */
+-
+-/*
+- * wPortChange bit field
+- * See USB 2.0 spec Table 11-22
+- * Bits 0 to 4 shown, bits 5 to 15 are reserved
+- */
+-#define USB_PORT_STAT_C_CONNECTION 0x0001
+-#define USB_PORT_STAT_C_ENABLE 0x0002
+-#define USB_PORT_STAT_C_SUSPEND 0x0004
+-#define USB_PORT_STAT_C_OVERCURRENT 0x0008
+-#define USB_PORT_STAT_C_RESET 0x0010
+-#define USB_PORT_STAT_C_L1 0x0020
+-
+-/*
+- * wHubCharacteristics (masks)
+- * See USB 2.0 spec Table 11-13, offset 3
+- */
+-#define HUB_CHAR_LPSM 0x0003 /* D1 .. D0 */
+-#define HUB_CHAR_COMPOUND 0x0004 /* D2 */
+-#define HUB_CHAR_OCPM 0x0018 /* D4 .. D3 */
+-#define HUB_CHAR_TTTT 0x0060 /* D6 .. D5 */
+-#define HUB_CHAR_PORTIND 0x0080 /* D7 */
+-
+-struct usb_hub_status {
+- __le16 wHubStatus;
+- __le16 wHubChange;
+-} __attribute__ ((packed));
+-
+-/*
+- * Hub Status & Hub Change bit masks
+- * See USB 2.0 spec Table 11-19 and Table 11-20
+- * Bits 0 and 1 for wHubStatus and wHubChange
+- * Bits 2 to 15 are reserved for both
+- */
+-#define HUB_STATUS_LOCAL_POWER 0x0001
+-#define HUB_STATUS_OVERCURRENT 0x0002
+-#define HUB_CHANGE_LOCAL_POWER 0x0001
+-#define HUB_CHANGE_OVERCURRENT 0x0002
+-
+-
+-/*
+- * Hub descriptor
+- * See USB 2.0 spec Table 11-13
+- */
+-
+-#define USB_DT_HUB (USB_TYPE_CLASS | 0x09)
+-#define USB_DT_HUB_NONVAR_SIZE 7
+-
+-struct usb_hub_descriptor {
+- __u8 bDescLength;
+- __u8 bDescriptorType;
+- __u8 bNbrPorts;
+- __le16 wHubCharacteristics;
+- __u8 bPwrOn2PwrGood;
+- __u8 bHubContrCurrent;
+- /* add 1 bit for hub status change; round to bytes */
+- __u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
+- __u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
+-} __attribute__ ((packed));
+-
+-
+-/* port indicator status selectors, tables 11-7 and 11-25 */
+-#define HUB_LED_AUTO 0
+-#define HUB_LED_AMBER 1
+-#define HUB_LED_GREEN 2
+-#define HUB_LED_OFF 3
+-
+-enum hub_led_mode {
+- INDICATOR_AUTO = 0,
+- INDICATOR_CYCLE,
+- /* software blinks for attention: software, hardware, reserved */
+- INDICATOR_GREEN_BLINK, INDICATOR_GREEN_BLINK_OFF,
+- INDICATOR_AMBER_BLINK, INDICATOR_AMBER_BLINK_OFF,
+- INDICATOR_ALT_BLINK, INDICATOR_ALT_BLINK_OFF
+-} __attribute__ ((packed));
+-
+-struct usb_device;
+-
+-/* Transaction Translator Think Times, in bits */
+-#define HUB_TTTT_8_BITS 0x00
+-#define HUB_TTTT_16_BITS 0x20
+-#define HUB_TTTT_24_BITS 0x40
+-#define HUB_TTTT_32_BITS 0x60
+-
+-/*
+- * As of USB 2.0, full/low speed devices are segregated into trees.
+- * One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
+- * The other type grows from high speed hubs when they connect to
+- * full/low speed devices using "Transaction Translators" (TTs).
+- *
+- * TTs should only be known to the hub driver, and high speed bus
+- * drivers (only EHCI for now). They affect periodic scheduling and
+- * sometimes control/bulk error recovery.
+- */
+-struct usb_tt {
+- struct usb_device *hub; /* upstream highspeed hub */
+- int multi; /* true means one TT per port */
+- unsigned think_time; /* think time in ns */
+-
+- /* for control/bulk error recovery (CLEAR_TT_BUFFER) */
+- spinlock_t lock;
+- struct list_head clear_list; /* of usb_tt_clear */
+- struct work_struct clear_work;
+-};
+-
+-struct usb_tt_clear {
+- struct list_head clear_list;
+- unsigned tt;
+- u16 devinfo;
+- struct usb_hcd *hcd;
+- struct usb_host_endpoint *ep;
+-};
+-
+-extern int usb_hub_clear_tt_buffer(struct urb *urb);
+-extern void usb_ep0_reinit(struct usb_device *);
+-
+-#endif /* __LINUX_HUB_H */
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -374,7 +374,7 @@ extern void usb_destroy_configuration(st
+ * HCD Root Hub support
+ */
+
+-#include <linux/../../drivers/usb/core/hub.h>
++#include <linux/usb/hub.h>
+
+ /* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */
+ #define DeviceRequest \
+--- /dev/null
++++ b/include/linux/usb/hub.h
+@@ -0,0 +1,205 @@
++#ifndef __LINUX_HUB_H
++#define __LINUX_HUB_H
++
++/*
++ * Hub protocol and driver data structures.
++ *
++ * Some of these are known to the "virtual root hub" code
++ * in host controller drivers.
++ */
++
++#include <linux/list.h>
++#include <linux/workqueue.h>
++#include <linux/compiler.h> /* likely()/unlikely() */
++
++/*
++ * Hub request types
++ */
++
++#define USB_RT_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE)
++#define USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
++
++/*
++ * Hub class requests
++ * See USB 2.0 spec Table 11-16
++ */
++#define HUB_CLEAR_TT_BUFFER 8
++#define HUB_RESET_TT 9
++#define HUB_GET_TT_STATE 10
++#define HUB_STOP_TT 11
++
++/*
++ * Hub Class feature numbers
++ * See USB 2.0 spec Table 11-17
++ */
++#define C_HUB_LOCAL_POWER 0
++#define C_HUB_OVER_CURRENT 1
++
++/*
++ * Port feature numbers
++ * See USB 2.0 spec Table 11-17
++ */
++#define USB_PORT_FEAT_CONNECTION 0
++#define USB_PORT_FEAT_ENABLE 1
++#define USB_PORT_FEAT_SUSPEND 2 /* L2 suspend */
++#define USB_PORT_FEAT_OVER_CURRENT 3
++#define USB_PORT_FEAT_RESET 4
++#define USB_PORT_FEAT_L1 5 /* L1 suspend */
++#define USB_PORT_FEAT_POWER 8
++#define USB_PORT_FEAT_LOWSPEED 9
++/* This value was never in Table 11-17 */
++#define USB_PORT_FEAT_HIGHSPEED 10
++/* This value is also fake */
++#define USB_PORT_FEAT_SUPERSPEED 11
++#define USB_PORT_FEAT_C_CONNECTION 16
++#define USB_PORT_FEAT_C_ENABLE 17
++#define USB_PORT_FEAT_C_SUSPEND 18
++#define USB_PORT_FEAT_C_OVER_CURRENT 19
++#define USB_PORT_FEAT_C_RESET 20
++#define USB_PORT_FEAT_TEST 21
++#define USB_PORT_FEAT_INDICATOR 22
++#define USB_PORT_FEAT_C_PORT_L1 23
++
++/*
++ * Hub Status and Hub Change results
++ * See USB 2.0 spec Table 11-19 and Table 11-20
++ */
++struct usb_port_status {
++ __le16 wPortStatus;
++ __le16 wPortChange;
++} __attribute__ ((packed));
++
++/*
++ * wPortStatus bit field
++ * See USB 2.0 spec Table 11-21
++ */
++#define USB_PORT_STAT_CONNECTION 0x0001
++#define USB_PORT_STAT_ENABLE 0x0002
++#define USB_PORT_STAT_SUSPEND 0x0004
++#define USB_PORT_STAT_OVERCURRENT 0x0008
++#define USB_PORT_STAT_RESET 0x0010
++#define USB_PORT_STAT_L1 0x0020
++/* bits 6 to 7 are reserved */
++#define USB_PORT_STAT_POWER 0x0100
++#define USB_PORT_STAT_LOW_SPEED 0x0200
++#define USB_PORT_STAT_HIGH_SPEED 0x0400
++#define USB_PORT_STAT_TEST 0x0800
++#define USB_PORT_STAT_INDICATOR 0x1000
++/* bits 13 to 15 are reserved */
++
++/*
++ * wPortChange bit field
++ * See USB 2.0 spec Table 11-22
++ * Bits 0 to 4 shown, bits 5 to 15 are reserved
++ */
++#define USB_PORT_STAT_C_CONNECTION 0x0001
++#define USB_PORT_STAT_C_ENABLE 0x0002
++#define USB_PORT_STAT_C_SUSPEND 0x0004
++#define USB_PORT_STAT_C_OVERCURRENT 0x0008
++#define USB_PORT_STAT_C_RESET 0x0010
++#define USB_PORT_STAT_C_L1 0x0020
++
++/*
++ * wHubCharacteristics (masks)
++ * See USB 2.0 spec Table 11-13, offset 3
++ */
++#define HUB_CHAR_LPSM 0x0003 /* D1 .. D0 */
++#define HUB_CHAR_COMPOUND 0x0004 /* D2 */
++#define HUB_CHAR_OCPM 0x0018 /* D4 .. D3 */
++#define HUB_CHAR_TTTT 0x0060 /* D6 .. D5 */
++#define HUB_CHAR_PORTIND 0x0080 /* D7 */
++
++struct usb_hub_status {
++ __le16 wHubStatus;
++ __le16 wHubChange;
++} __attribute__ ((packed));
++
++/*
++ * Hub Status & Hub Change bit masks
++ * See USB 2.0 spec Table 11-19 and Table 11-20
++ * Bits 0 and 1 for wHubStatus and wHubChange
++ * Bits 2 to 15 are reserved for both
++ */
++#define HUB_STATUS_LOCAL_POWER 0x0001
++#define HUB_STATUS_OVERCURRENT 0x0002
++#define HUB_CHANGE_LOCAL_POWER 0x0001
++#define HUB_CHANGE_OVERCURRENT 0x0002
++
++
++/*
++ * Hub descriptor
++ * See USB 2.0 spec Table 11-13
++ */
++
++#define USB_DT_HUB (USB_TYPE_CLASS | 0x09)
++#define USB_DT_HUB_NONVAR_SIZE 7
++
++struct usb_hub_descriptor {
++ __u8 bDescLength;
++ __u8 bDescriptorType;
++ __u8 bNbrPorts;
++ __le16 wHubCharacteristics;
++ __u8 bPwrOn2PwrGood;
++ __u8 bHubContrCurrent;
++ /* add 1 bit for hub status change; round to bytes */
++ __u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
++ __u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
++} __attribute__ ((packed));
++
++
++/* port indicator status selectors, tables 11-7 and 11-25 */
++#define HUB_LED_AUTO 0
++#define HUB_LED_AMBER 1
++#define HUB_LED_GREEN 2
++#define HUB_LED_OFF 3
++
++enum hub_led_mode {
++ INDICATOR_AUTO = 0,
++ INDICATOR_CYCLE,
++ /* software blinks for attention: software, hardware, reserved */
++ INDICATOR_GREEN_BLINK, INDICATOR_GREEN_BLINK_OFF,
++ INDICATOR_AMBER_BLINK, INDICATOR_AMBER_BLINK_OFF,
++ INDICATOR_ALT_BLINK, INDICATOR_ALT_BLINK_OFF
++} __attribute__ ((packed));
++
++struct usb_device;
++
++/* Transaction Translator Think Times, in bits */
++#define HUB_TTTT_8_BITS 0x00
++#define HUB_TTTT_16_BITS 0x20
++#define HUB_TTTT_24_BITS 0x40
++#define HUB_TTTT_32_BITS 0x60
++
++/*
++ * As of USB 2.0, full/low speed devices are segregated into trees.
++ * One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
++ * The other type grows from high speed hubs when they connect to
++ * full/low speed devices using "Transaction Translators" (TTs).
++ *
++ * TTs should only be known to the hub driver, and high speed bus
++ * drivers (only EHCI for now). They affect periodic scheduling and
++ * sometimes control/bulk error recovery.
++ */
++struct usb_tt {
++ struct usb_device *hub; /* upstream highspeed hub */
++ int multi; /* true means one TT per port */
++ unsigned think_time; /* think time in ns */
++
++ /* for control/bulk error recovery (CLEAR_TT_BUFFER) */
++ spinlock_t lock;
++ struct list_head clear_list; /* of usb_tt_clear */
++ struct work_struct clear_work;
++};
++
++struct usb_tt_clear {
++ struct list_head clear_list;
++ unsigned tt;
++ u16 devinfo;
++ struct usb_hcd *hcd;
++ struct usb_host_endpoint *ep;
++};
++
++extern int usb_hub_clear_tt_buffer(struct urb *urb);
++extern void usb_ep0_reinit(struct usb_device *);
++
++#endif /* __LINUX_HUB_H */
diff --git a/usb/usb-mass-storage-gadget-handle-eject-request.patch b/usb/usb-mass-storage-gadget-handle-eject-request.patch
new file mode 100644
index 00000000000000..974673319494f2
--- /dev/null
+++ b/usb/usb-mass-storage-gadget-handle-eject-request.patch
@@ -0,0 +1,88 @@
+From fabien.chouteau@gmail.com Thu Apr 29 16:07:55 2010
+From: Fabien Chouteau <fabien.chouteau@barco.com>
+Date: Mon, 26 Apr 2010 12:34:54 +0200
+Subject: USB: Mass storage gadget: Handle eject request
+To: linux-usb@vger.kernel.org
+Cc: Fabien Chouteau <fabien.chouteau@barco.com>, David Brownell <dbrownell@users.sourceforge.net>, Greg Kroah-Hartman <gregkh@suse.de>, Michal Nazarewicz <m.nazarewicz@samsung.com>, Peter Korsgaard <jacmet@sunsite.dk>, linux-kernel@vger.kernel.org
+Message-ID: <1272278094-25433-1-git-send-email-fabien.chouteau@gmail.com>
+
+
+From: Fabien Chouteau <fabien.chouteau@barco.com>
+
+This patch adds handling of the "Start/Stop Unit" SCSI request
+to simulate media ejection.
+
+Signed-off-by: Fabien Chouteau <fabien.chouteau@barco.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/f_mass_storage.c | 48 +++++++++++++++++++++++++++++++++---
+ 1 file changed, 45 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -163,6 +163,10 @@
+ * ro setting are not allowed when the medium is loaded or if CD-ROM
+ * emulation is being used.
+ *
++ * When a LUN receive an "eject" SCSI request (Start/Stop Unit),
++ * if the LUN is removable, the backing file is released to simulate
++ * ejection.
++ *
+ *
+ * This function is heavily based on "File-backed Storage Gadget" by
+ * Alan Stern which in turn is heavily based on "Gadget Zero" by David
+@@ -1384,12 +1388,50 @@ static int do_mode_sense(struct fsg_comm
+
+ static int do_start_stop(struct fsg_common *common)
+ {
+- if (!common->curlun) {
++ struct fsg_lun *curlun = common->curlun;
++ int loej, start;
++
++ if (!curlun) {
+ return -EINVAL;
+- } else if (!common->curlun->removable) {
+- common->curlun->sense_data = SS_INVALID_COMMAND;
++ } else if (!curlun->removable) {
++ curlun->sense_data = SS_INVALID_COMMAND;
++ return -EINVAL;
++ }
++
++ loej = common->cmnd[4] & 0x02;
++ start = common->cmnd[4] & 0x01;
++
++ /* eject code from file_storage.c:do_start_stop() */
++
++ if ((common->cmnd[1] & ~0x01) != 0 || /* Mask away Immed */
++ (common->cmnd[4] & ~0x03) != 0) { /* Mask LoEj, Start */
++ curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+ return -EINVAL;
+ }
++
++ if (!start) {
++ /* Are we allowed to unload the media? */
++ if (curlun->prevent_medium_removal) {
++ LDBG(curlun, "unload attempt prevented\n");
++ curlun->sense_data = SS_MEDIUM_REMOVAL_PREVENTED;
++ return -EINVAL;
++ }
++ if (loej) { /* Simulate an unload/eject */
++ up_read(&common->filesem);
++ down_write(&common->filesem);
++ fsg_lun_close(curlun);
++ up_write(&common->filesem);
++ down_read(&common->filesem);
++ }
++ } else {
++
++ /* Our emulation doesn't support mounting; the medium is
++ * available for use as soon as it is loaded. */
++ if (!fsg_lun_is_open(curlun)) {
++ curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
++ return -EINVAL;
++ }
++ }
+ return 0;
+ }
+
diff --git a/usb/usb-ncm-added-ncm.h-with-auxiliary-definitions.patch b/usb/usb-ncm-added-ncm.h-with-auxiliary-definitions.patch
new file mode 100644
index 00000000000000..28f179c7e2885b
--- /dev/null
+++ b/usb/usb-ncm-added-ncm.h-with-auxiliary-definitions.patch
@@ -0,0 +1,132 @@
+From yauheni.kaliuta@nokia.com Thu Apr 29 16:04:25 2010
+From: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
+Date: Fri, 16 Apr 2010 16:13:35 +0300
+Subject: USB: ncm: added ncm.h with auxiliary definitions
+To: linux-usb@vger.kernel.org
+Message-ID: <1271423621-26361-3-git-send-email-yauheni.kaliuta@nokia.com>
+
+
+Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/usb/ncm.h | 114 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 114 insertions(+)
+
+--- /dev/null
++++ b/include/linux/usb/ncm.h
+@@ -0,0 +1,114 @@
++/*
++ * USB CDC NCM auxiliary definitions
++ */
++
++#ifndef __LINUX_USB_NCM_H
++#define __LINUX_USB_NCM_H
++
++#include <linux/types.h>
++#include <linux/usb/cdc.h>
++#include <asm/unaligned.h>
++
++#define NCM_NTB_MIN_IN_SIZE 2048
++#define NCM_NTB_MIN_OUT_SIZE 2048
++
++#define NCM_CONTROL_TIMEOUT (5 * 1000)
++
++/* bmNetworkCapabilities */
++
++#define NCM_NCAP_ETH_FILTER (1 << 0)
++#define NCM_NCAP_NET_ADDRESS (1 << 1)
++#define NCM_NCAP_ENCAP_COMM (1 << 2)
++#define NCM_NCAP_MAX_DGRAM (1 << 3)
++#define NCM_NCAP_CRC_MODE (1 << 4)
++
++/*
++ * Here are options for NCM Datagram Pointer table (NDP) parser.
++ * There are 2 different formats: NDP16 and NDP32 in the spec (ch. 3),
++ * in NDP16 offsets and sizes fields are 1 16bit word wide,
++ * in NDP32 -- 2 16bit words wide. Also signatures are different.
++ * To make the parser code the same, put the differences in the structure,
++ * and switch pointers to the structures when the format is changed.
++ */
++
++struct ndp_parser_opts {
++ u32 nth_sign;
++ u32 ndp_sign;
++ unsigned nth_size;
++ unsigned ndp_size;
++ unsigned ndplen_align;
++ /* sizes in u16 units */
++ unsigned dgram_item_len; /* index or length */
++ unsigned block_length;
++ unsigned fp_index;
++ unsigned reserved1;
++ unsigned reserved2;
++ unsigned next_fp_index;
++};
++
++#define INIT_NDP16_OPTS { \
++ .nth_sign = NCM_NTH16_SIGN, \
++ .ndp_sign = NCM_NDP16_NOCRC_SIGN, \
++ .nth_size = sizeof(struct usb_cdc_ncm_nth16), \
++ .ndp_size = sizeof(struct usb_cdc_ncm_ndp16), \
++ .ndplen_align = 4, \
++ .dgram_item_len = 1, \
++ .block_length = 1, \
++ .fp_index = 1, \
++ .reserved1 = 0, \
++ .reserved2 = 0, \
++ .next_fp_index = 1, \
++ }
++
++
++#define INIT_NDP32_OPTS { \
++ .nth_sign = NCM_NTH32_SIGN, \
++ .ndp_sign = NCM_NDP32_NOCRC_SIGN, \
++ .nth_size = sizeof(struct usb_cdc_ncm_nth32), \
++ .ndp_size = sizeof(struct usb_cdc_ncm_ndp32), \
++ .ndplen_align = 8, \
++ .dgram_item_len = 2, \
++ .block_length = 2, \
++ .fp_index = 2, \
++ .reserved1 = 1, \
++ .reserved2 = 2, \
++ .next_fp_index = 2, \
++ }
++
++static inline void put_ncm(__le16 **p, unsigned size, unsigned val)
++{
++ switch (size) {
++ case 1:
++ put_unaligned_le16((u16)val, *p);
++ break;
++ case 2:
++ put_unaligned_le32((u32)val, *p);
++
++ break;
++ default:
++ BUG();
++ }
++
++ *p += size;
++}
++
++static inline unsigned get_ncm(__le16 **p, unsigned size)
++{
++ unsigned tmp;
++
++ switch (size) {
++ case 1:
++ tmp = get_unaligned_le16(*p);
++ break;
++ case 2:
++ tmp = get_unaligned_le32(*p);
++ break;
++ default:
++ BUG();
++ }
++
++ *p += size;
++ return tmp;
++}
++
++#endif /* __LINUX_USB_NCM_H */
diff --git a/usb/usb-remove-bogus-usb_port_feat_-_speed-symbols.patch b/usb/usb-remove-bogus-usb_port_feat_-_speed-symbols.patch
index c4a64cd5019cec..168280116808d6 100644
--- a/usb/usb-remove-bogus-usb_port_feat_-_speed-symbols.patch
+++ b/usb/usb-remove-bogus-usb_port_feat_-_speed-symbols.patch
@@ -7,7 +7,7 @@ Cc: Sarah Sharp <sarah.a.sharp@linux.intel.com>, Andiry Xu <andiry.xu@amd.com>,
Message-ID: <Pine.LNX.4.44L0.1003041130360.1657-100000@iolanthe.rowland.org>
This patch (as1348) removes the bogus
-USB_PORT_FEAT_{HIGHSPEED,SUPERSPEED} symbols from hub.h. No such
+USB_PORT_FEAT_{HIGHSPEED,SUPERSPEED} symbols from ch11.h. No such
features are defined by the USB spec. (There is a PORT_LOWSPEED
feature, but the spec doesn't mention it except to say that host
software should never use it.) The speed indicators are port
@@ -22,18 +22,18 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/usb/core/hub.c | 8 ++++----
- drivers/usb/core/hub.h | 7 ++-----
drivers/usb/host/ehci.h | 8 ++++----
drivers/usb/host/isp1760-hcd.c | 2 +-
drivers/usb/host/oxu210hp-hcd.c | 4 ++--
drivers/usb/host/r8a66597-hcd.c | 7 +++----
drivers/usb/host/sl811-hcd.c | 6 +++---
drivers/usb/host/xhci-hub.c | 8 ++++----
+ include/linux/usb/ch11.h | 7 ++-----
8 files changed, 23 insertions(+), 27 deletions(-)
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
-@@ -154,11 +154,11 @@ static int usb_reset_and_verify_device(s
+@@ -153,11 +153,11 @@ static int usb_reset_and_verify_device(s
static inline char *portspeed(int portstatus)
{
@@ -48,7 +48,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
return "5.0 Gb/s";
else
return "12 Mb/s";
-@@ -3076,7 +3076,7 @@ static void hub_port_connect_change(stru
+@@ -3075,7 +3075,7 @@ static void hub_port_connect_change(stru
if (!(hcd->driver->flags & HCD_USB3))
udev->speed = USB_SPEED_UNKNOWN;
else if ((hdev->parent == NULL) &&
@@ -57,29 +57,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
udev->speed = USB_SPEED_SUPER;
else
udev->speed = USB_SPEED_UNKNOWN;
---- a/drivers/usb/core/hub.h
-+++ b/drivers/usb/core/hub.h
-@@ -46,11 +46,7 @@
- #define USB_PORT_FEAT_RESET 4
- #define USB_PORT_FEAT_L1 5 /* L1 suspend */
- #define USB_PORT_FEAT_POWER 8
--#define USB_PORT_FEAT_LOWSPEED 9
--/* This value was never in Table 11-17 */
--#define USB_PORT_FEAT_HIGHSPEED 10
--/* This value is also fake */
--#define USB_PORT_FEAT_SUPERSPEED 11
-+#define USB_PORT_FEAT_LOWSPEED 9 /* Should never be used */
- #define USB_PORT_FEAT_C_CONNECTION 16
- #define USB_PORT_FEAT_C_ENABLE 17
- #define USB_PORT_FEAT_C_SUSPEND 18
-@@ -86,6 +82,7 @@ struct usb_port_status {
- #define USB_PORT_STAT_TEST 0x0800
- #define USB_PORT_STAT_INDICATOR 0x1000
- /* bits 13 to 15 are reserved */
-+#define USB_PORT_STAT_SUPER_SPEED 0x8000 /* Linux-internal */
-
- /*
- * wPortChange bit field
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -556,20 +556,20 @@ ehci_port_speed(struct ehci_hcd *ehci, u
@@ -120,7 +97,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
{
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
-@@ -3154,10 +3154,10 @@ static inline unsigned int oxu_port_spee
+@@ -3153,10 +3153,10 @@ static inline unsigned int oxu_port_spee
case 0:
return 0;
case 1:
@@ -202,3 +179,26 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
*/
return 0;
}
+--- a/include/linux/usb/ch11.h
++++ b/include/linux/usb/ch11.h
+@@ -47,11 +47,7 @@
+ #define USB_PORT_FEAT_RESET 4
+ #define USB_PORT_FEAT_L1 5 /* L1 suspend */
+ #define USB_PORT_FEAT_POWER 8
+-#define USB_PORT_FEAT_LOWSPEED 9
+-/* This value was never in Table 11-17 */
+-#define USB_PORT_FEAT_HIGHSPEED 10
+-/* This value is also fake */
+-#define USB_PORT_FEAT_SUPERSPEED 11
++#define USB_PORT_FEAT_LOWSPEED 9 /* Should never be used */
+ #define USB_PORT_FEAT_C_CONNECTION 16
+ #define USB_PORT_FEAT_C_ENABLE 17
+ #define USB_PORT_FEAT_C_SUSPEND 18
+@@ -87,6 +83,7 @@ struct usb_port_status {
+ #define USB_PORT_STAT_TEST 0x0800
+ #define USB_PORT_STAT_INDICATOR 0x1000
+ /* bits 13 to 15 are reserved */
++#define USB_PORT_STAT_SUPER_SPEED 0x8000 /* Linux-internal */
+
+ /*
+ * wPortChange bit field
diff --git a/usb/usb-split-hub.h-into-ch11.h-and-merge-in-hcd.h.patch b/usb/usb-split-hub.h-into-ch11.h-and-merge-in-hcd.h.patch
new file mode 100644
index 00000000000000..548e2f144fa60e
--- /dev/null
+++ b/usb/usb-split-hub.h-into-ch11.h-and-merge-in-hcd.h.patch
@@ -0,0 +1,452 @@
+From Eric.Lescouet@virtuallogix.com Thu Apr 29 16:14:09 2010
+From: Eric Lescouet <Eric.Lescouet@virtuallogix.com>
+Date: Sat, 24 Apr 2010 23:38:17 +0200
+Subject: USB: split hub.h into ch11.h and merge-in hcd.h
+To: Greg KH <greg@kroah.com>
+Message-ID: <1272145097.2517.5.camel@localhost>
+
+
+Base on inputs from Alan Stern, split the hub.h header into:
+- new ch11.h header (most of it) containing constants and
+ structures from chapter 11 of the USB 2.0 spec.
+- a small remaining part being merged into hcd.h.
+
+Signed-of-by: Eric Lescouet <eric@lescouet.org>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/usb/ch11.h | 172 +++++++++++++++++++++++++++++++++++++++
+ include/linux/usb/hcd.h | 37 ++++++++
+ include/linux/usb/hub.h | 205 -----------------------------------------------
+ 3 files changed, 208 insertions(+), 206 deletions(-)
+
+--- /dev/null
++++ b/include/linux/usb/ch11.h
+@@ -0,0 +1,172 @@
++/*
++ * This file holds Hub protocol constants and data structures that are
++ * defined in chapter 11 (Hub Specification) of the USB 2.0 specification.
++ *
++ * It is used/shared between the USB core, the HCDs and couple of other USB
++ * drivers.
++ */
++
++#ifndef __LINUX_HUB_H
++#define __LINUX_HUB_H
++
++#include <linux/list.h>
++#include <linux/workqueue.h>
++#include <linux/compiler.h> /* likely()/unlikely() */
++
++/*
++ * Hub request types
++ */
++
++#define USB_RT_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE)
++#define USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
++
++/*
++ * Hub class requests
++ * See USB 2.0 spec Table 11-16
++ */
++#define HUB_CLEAR_TT_BUFFER 8
++#define HUB_RESET_TT 9
++#define HUB_GET_TT_STATE 10
++#define HUB_STOP_TT 11
++
++/*
++ * Hub Class feature numbers
++ * See USB 2.0 spec Table 11-17
++ */
++#define C_HUB_LOCAL_POWER 0
++#define C_HUB_OVER_CURRENT 1
++
++/*
++ * Port feature numbers
++ * See USB 2.0 spec Table 11-17
++ */
++#define USB_PORT_FEAT_CONNECTION 0
++#define USB_PORT_FEAT_ENABLE 1
++#define USB_PORT_FEAT_SUSPEND 2 /* L2 suspend */
++#define USB_PORT_FEAT_OVER_CURRENT 3
++#define USB_PORT_FEAT_RESET 4
++#define USB_PORT_FEAT_L1 5 /* L1 suspend */
++#define USB_PORT_FEAT_POWER 8
++#define USB_PORT_FEAT_LOWSPEED 9
++/* This value was never in Table 11-17 */
++#define USB_PORT_FEAT_HIGHSPEED 10
++/* This value is also fake */
++#define USB_PORT_FEAT_SUPERSPEED 11
++#define USB_PORT_FEAT_C_CONNECTION 16
++#define USB_PORT_FEAT_C_ENABLE 17
++#define USB_PORT_FEAT_C_SUSPEND 18
++#define USB_PORT_FEAT_C_OVER_CURRENT 19
++#define USB_PORT_FEAT_C_RESET 20
++#define USB_PORT_FEAT_TEST 21
++#define USB_PORT_FEAT_INDICATOR 22
++#define USB_PORT_FEAT_C_PORT_L1 23
++
++/*
++ * Hub Status and Hub Change results
++ * See USB 2.0 spec Table 11-19 and Table 11-20
++ */
++struct usb_port_status {
++ __le16 wPortStatus;
++ __le16 wPortChange;
++} __attribute__ ((packed));
++
++/*
++ * wPortStatus bit field
++ * See USB 2.0 spec Table 11-21
++ */
++#define USB_PORT_STAT_CONNECTION 0x0001
++#define USB_PORT_STAT_ENABLE 0x0002
++#define USB_PORT_STAT_SUSPEND 0x0004
++#define USB_PORT_STAT_OVERCURRENT 0x0008
++#define USB_PORT_STAT_RESET 0x0010
++#define USB_PORT_STAT_L1 0x0020
++/* bits 6 to 7 are reserved */
++#define USB_PORT_STAT_POWER 0x0100
++#define USB_PORT_STAT_LOW_SPEED 0x0200
++#define USB_PORT_STAT_HIGH_SPEED 0x0400
++#define USB_PORT_STAT_TEST 0x0800
++#define USB_PORT_STAT_INDICATOR 0x1000
++/* bits 13 to 15 are reserved */
++
++/*
++ * wPortChange bit field
++ * See USB 2.0 spec Table 11-22
++ * Bits 0 to 4 shown, bits 5 to 15 are reserved
++ */
++#define USB_PORT_STAT_C_CONNECTION 0x0001
++#define USB_PORT_STAT_C_ENABLE 0x0002
++#define USB_PORT_STAT_C_SUSPEND 0x0004
++#define USB_PORT_STAT_C_OVERCURRENT 0x0008
++#define USB_PORT_STAT_C_RESET 0x0010
++#define USB_PORT_STAT_C_L1 0x0020
++
++/*
++ * wHubCharacteristics (masks)
++ * See USB 2.0 spec Table 11-13, offset 3
++ */
++#define HUB_CHAR_LPSM 0x0003 /* D1 .. D0 */
++#define HUB_CHAR_COMPOUND 0x0004 /* D2 */
++#define HUB_CHAR_OCPM 0x0018 /* D4 .. D3 */
++#define HUB_CHAR_TTTT 0x0060 /* D6 .. D5 */
++#define HUB_CHAR_PORTIND 0x0080 /* D7 */
++
++struct usb_hub_status {
++ __le16 wHubStatus;
++ __le16 wHubChange;
++} __attribute__ ((packed));
++
++/*
++ * Hub Status & Hub Change bit masks
++ * See USB 2.0 spec Table 11-19 and Table 11-20
++ * Bits 0 and 1 for wHubStatus and wHubChange
++ * Bits 2 to 15 are reserved for both
++ */
++#define HUB_STATUS_LOCAL_POWER 0x0001
++#define HUB_STATUS_OVERCURRENT 0x0002
++#define HUB_CHANGE_LOCAL_POWER 0x0001
++#define HUB_CHANGE_OVERCURRENT 0x0002
++
++
++/*
++ * Hub descriptor
++ * See USB 2.0 spec Table 11-13
++ */
++
++#define USB_DT_HUB (USB_TYPE_CLASS | 0x09)
++#define USB_DT_HUB_NONVAR_SIZE 7
++
++struct usb_hub_descriptor {
++ __u8 bDescLength;
++ __u8 bDescriptorType;
++ __u8 bNbrPorts;
++ __le16 wHubCharacteristics;
++ __u8 bPwrOn2PwrGood;
++ __u8 bHubContrCurrent;
++ /* add 1 bit for hub status change; round to bytes */
++ __u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
++ __u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
++} __attribute__ ((packed));
++
++
++/* port indicator status selectors, tables 11-7 and 11-25 */
++#define HUB_LED_AUTO 0
++#define HUB_LED_AMBER 1
++#define HUB_LED_GREEN 2
++#define HUB_LED_OFF 3
++
++enum hub_led_mode {
++ INDICATOR_AUTO = 0,
++ INDICATOR_CYCLE,
++ /* software blinks for attention: software, hardware, reserved */
++ INDICATOR_GREEN_BLINK, INDICATOR_GREEN_BLINK_OFF,
++ INDICATOR_AMBER_BLINK, INDICATOR_AMBER_BLINK_OFF,
++ INDICATOR_ALT_BLINK, INDICATOR_ALT_BLINK_OFF
++} __attribute__ ((packed));
++
++/* Transaction Translator Think Times, in bits */
++#define HUB_TTTT_8_BITS 0x00
++#define HUB_TTTT_16_BITS 0x20
++#define HUB_TTTT_24_BITS 0x40
++#define HUB_TTTT_32_BITS 0x60
++
++#endif /* __LINUX_HUB_H */
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -374,7 +374,42 @@ extern void usb_destroy_configuration(st
+ * HCD Root Hub support
+ */
+
+-#include <linux/usb/hub.h>
++#include <linux/usb/ch11.h>
++
++/*
++ * As of USB 2.0, full/low speed devices are segregated into trees.
++ * One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
++ * The other type grows from high speed hubs when they connect to
++ * full/low speed devices using "Transaction Translators" (TTs).
++ *
++ * TTs should only be known to the hub driver, and high speed bus
++ * drivers (only EHCI for now). They affect periodic scheduling and
++ * sometimes control/bulk error recovery.
++ */
++
++struct usb_device;
++
++struct usb_tt {
++ struct usb_device *hub; /* upstream highspeed hub */
++ int multi; /* true means one TT per port */
++ unsigned think_time; /* think time in ns */
++
++ /* for control/bulk error recovery (CLEAR_TT_BUFFER) */
++ spinlock_t lock;
++ struct list_head clear_list; /* of usb_tt_clear */
++ struct work_struct clear_work;
++};
++
++struct usb_tt_clear {
++ struct list_head clear_list;
++ unsigned tt;
++ u16 devinfo;
++ struct usb_hcd *hcd;
++ struct usb_host_endpoint *ep;
++};
++
++extern int usb_hub_clear_tt_buffer(struct urb *urb);
++extern void usb_ep0_reinit(struct usb_device *);
+
+ /* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */
+ #define DeviceRequest \
+--- a/include/linux/usb/hub.h
++++ /dev/null
+@@ -1,205 +0,0 @@
+-#ifndef __LINUX_HUB_H
+-#define __LINUX_HUB_H
+-
+-/*
+- * Hub protocol and driver data structures.
+- *
+- * Some of these are known to the "virtual root hub" code
+- * in host controller drivers.
+- */
+-
+-#include <linux/list.h>
+-#include <linux/workqueue.h>
+-#include <linux/compiler.h> /* likely()/unlikely() */
+-
+-/*
+- * Hub request types
+- */
+-
+-#define USB_RT_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE)
+-#define USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
+-
+-/*
+- * Hub class requests
+- * See USB 2.0 spec Table 11-16
+- */
+-#define HUB_CLEAR_TT_BUFFER 8
+-#define HUB_RESET_TT 9
+-#define HUB_GET_TT_STATE 10
+-#define HUB_STOP_TT 11
+-
+-/*
+- * Hub Class feature numbers
+- * See USB 2.0 spec Table 11-17
+- */
+-#define C_HUB_LOCAL_POWER 0
+-#define C_HUB_OVER_CURRENT 1
+-
+-/*
+- * Port feature numbers
+- * See USB 2.0 spec Table 11-17
+- */
+-#define USB_PORT_FEAT_CONNECTION 0
+-#define USB_PORT_FEAT_ENABLE 1
+-#define USB_PORT_FEAT_SUSPEND 2 /* L2 suspend */
+-#define USB_PORT_FEAT_OVER_CURRENT 3
+-#define USB_PORT_FEAT_RESET 4
+-#define USB_PORT_FEAT_L1 5 /* L1 suspend */
+-#define USB_PORT_FEAT_POWER 8
+-#define USB_PORT_FEAT_LOWSPEED 9
+-/* This value was never in Table 11-17 */
+-#define USB_PORT_FEAT_HIGHSPEED 10
+-/* This value is also fake */
+-#define USB_PORT_FEAT_SUPERSPEED 11
+-#define USB_PORT_FEAT_C_CONNECTION 16
+-#define USB_PORT_FEAT_C_ENABLE 17
+-#define USB_PORT_FEAT_C_SUSPEND 18
+-#define USB_PORT_FEAT_C_OVER_CURRENT 19
+-#define USB_PORT_FEAT_C_RESET 20
+-#define USB_PORT_FEAT_TEST 21
+-#define USB_PORT_FEAT_INDICATOR 22
+-#define USB_PORT_FEAT_C_PORT_L1 23
+-
+-/*
+- * Hub Status and Hub Change results
+- * See USB 2.0 spec Table 11-19 and Table 11-20
+- */
+-struct usb_port_status {
+- __le16 wPortStatus;
+- __le16 wPortChange;
+-} __attribute__ ((packed));
+-
+-/*
+- * wPortStatus bit field
+- * See USB 2.0 spec Table 11-21
+- */
+-#define USB_PORT_STAT_CONNECTION 0x0001
+-#define USB_PORT_STAT_ENABLE 0x0002
+-#define USB_PORT_STAT_SUSPEND 0x0004
+-#define USB_PORT_STAT_OVERCURRENT 0x0008
+-#define USB_PORT_STAT_RESET 0x0010
+-#define USB_PORT_STAT_L1 0x0020
+-/* bits 6 to 7 are reserved */
+-#define USB_PORT_STAT_POWER 0x0100
+-#define USB_PORT_STAT_LOW_SPEED 0x0200
+-#define USB_PORT_STAT_HIGH_SPEED 0x0400
+-#define USB_PORT_STAT_TEST 0x0800
+-#define USB_PORT_STAT_INDICATOR 0x1000
+-/* bits 13 to 15 are reserved */
+-
+-/*
+- * wPortChange bit field
+- * See USB 2.0 spec Table 11-22
+- * Bits 0 to 4 shown, bits 5 to 15 are reserved
+- */
+-#define USB_PORT_STAT_C_CONNECTION 0x0001
+-#define USB_PORT_STAT_C_ENABLE 0x0002
+-#define USB_PORT_STAT_C_SUSPEND 0x0004
+-#define USB_PORT_STAT_C_OVERCURRENT 0x0008
+-#define USB_PORT_STAT_C_RESET 0x0010
+-#define USB_PORT_STAT_C_L1 0x0020
+-
+-/*
+- * wHubCharacteristics (masks)
+- * See USB 2.0 spec Table 11-13, offset 3
+- */
+-#define HUB_CHAR_LPSM 0x0003 /* D1 .. D0 */
+-#define HUB_CHAR_COMPOUND 0x0004 /* D2 */
+-#define HUB_CHAR_OCPM 0x0018 /* D4 .. D3 */
+-#define HUB_CHAR_TTTT 0x0060 /* D6 .. D5 */
+-#define HUB_CHAR_PORTIND 0x0080 /* D7 */
+-
+-struct usb_hub_status {
+- __le16 wHubStatus;
+- __le16 wHubChange;
+-} __attribute__ ((packed));
+-
+-/*
+- * Hub Status & Hub Change bit masks
+- * See USB 2.0 spec Table 11-19 and Table 11-20
+- * Bits 0 and 1 for wHubStatus and wHubChange
+- * Bits 2 to 15 are reserved for both
+- */
+-#define HUB_STATUS_LOCAL_POWER 0x0001
+-#define HUB_STATUS_OVERCURRENT 0x0002
+-#define HUB_CHANGE_LOCAL_POWER 0x0001
+-#define HUB_CHANGE_OVERCURRENT 0x0002
+-
+-
+-/*
+- * Hub descriptor
+- * See USB 2.0 spec Table 11-13
+- */
+-
+-#define USB_DT_HUB (USB_TYPE_CLASS | 0x09)
+-#define USB_DT_HUB_NONVAR_SIZE 7
+-
+-struct usb_hub_descriptor {
+- __u8 bDescLength;
+- __u8 bDescriptorType;
+- __u8 bNbrPorts;
+- __le16 wHubCharacteristics;
+- __u8 bPwrOn2PwrGood;
+- __u8 bHubContrCurrent;
+- /* add 1 bit for hub status change; round to bytes */
+- __u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
+- __u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
+-} __attribute__ ((packed));
+-
+-
+-/* port indicator status selectors, tables 11-7 and 11-25 */
+-#define HUB_LED_AUTO 0
+-#define HUB_LED_AMBER 1
+-#define HUB_LED_GREEN 2
+-#define HUB_LED_OFF 3
+-
+-enum hub_led_mode {
+- INDICATOR_AUTO = 0,
+- INDICATOR_CYCLE,
+- /* software blinks for attention: software, hardware, reserved */
+- INDICATOR_GREEN_BLINK, INDICATOR_GREEN_BLINK_OFF,
+- INDICATOR_AMBER_BLINK, INDICATOR_AMBER_BLINK_OFF,
+- INDICATOR_ALT_BLINK, INDICATOR_ALT_BLINK_OFF
+-} __attribute__ ((packed));
+-
+-struct usb_device;
+-
+-/* Transaction Translator Think Times, in bits */
+-#define HUB_TTTT_8_BITS 0x00
+-#define HUB_TTTT_16_BITS 0x20
+-#define HUB_TTTT_24_BITS 0x40
+-#define HUB_TTTT_32_BITS 0x60
+-
+-/*
+- * As of USB 2.0, full/low speed devices are segregated into trees.
+- * One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
+- * The other type grows from high speed hubs when they connect to
+- * full/low speed devices using "Transaction Translators" (TTs).
+- *
+- * TTs should only be known to the hub driver, and high speed bus
+- * drivers (only EHCI for now). They affect periodic scheduling and
+- * sometimes control/bulk error recovery.
+- */
+-struct usb_tt {
+- struct usb_device *hub; /* upstream highspeed hub */
+- int multi; /* true means one TT per port */
+- unsigned think_time; /* think time in ns */
+-
+- /* for control/bulk error recovery (CLEAR_TT_BUFFER) */
+- spinlock_t lock;
+- struct list_head clear_list; /* of usb_tt_clear */
+- struct work_struct clear_work;
+-};
+-
+-struct usb_tt_clear {
+- struct list_head clear_list;
+- unsigned tt;
+- u16 devinfo;
+- struct usb_hcd *hcd;
+- struct usb_host_endpoint *ep;
+-};
+-
+-extern int usb_hub_clear_tt_buffer(struct urb *urb);
+-extern void usb_ep0_reinit(struct usb_device *);
+-
+-#endif /* __LINUX_HUB_H */
diff --git a/usb/usb-straighten-out-port-feature-vs.-port-status-usage.patch b/usb/usb-straighten-out-port-feature-vs.-port-status-usage.patch
index b0cdd3b0a7aa51..d90dab095201da 100644
--- a/usb/usb-straighten-out-port-feature-vs.-port-status-usage.patch
+++ b/usb/usb-straighten-out-port-feature-vs.-port-status-usage.patch
@@ -33,7 +33,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
-@@ -3038,7 +3038,7 @@ static void hub_port_connect_change(stru
+@@ -3037,7 +3037,7 @@ static void hub_port_connect_change(stru
/* maybe switch power back on (e.g. root hub was reset) */
if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2
@@ -194,7 +194,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
break;
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
-@@ -3202,7 +3202,7 @@ static int oxu_hub_control(struct usb_hc
+@@ -3201,7 +3201,7 @@ static int oxu_hub_control(struct usb_hc
* Even if OWNER is set, so the port is owned by the
* companion controller, khubd needs to be able to clear
* the port-change status bits (especially
@@ -203,7 +203,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
*/
switch (wValue) {
-@@ -3264,11 +3264,11 @@ static int oxu_hub_control(struct usb_hc
+@@ -3263,11 +3263,11 @@ static int oxu_hub_control(struct usb_hc
/* wPortChange bits */
if (temp & PORT_CSC)
@@ -218,7 +218,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
/* whoever resumes must GetPortStatus to complete it!! */
if (temp & PORT_RESUME) {
-@@ -3286,7 +3286,7 @@ static int oxu_hub_control(struct usb_hc
+@@ -3285,7 +3285,7 @@ static int oxu_hub_control(struct usb_hc
/* resume completed? */
else if (time_after_eq(jiffies,
oxu->reset_done[wIndex])) {
@@ -227,7 +227,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
oxu->reset_done[wIndex] = 0;
/* stop resume signaling */
-@@ -3309,7 +3309,7 @@ static int oxu_hub_control(struct usb_hc
+@@ -3308,7 +3308,7 @@ static int oxu_hub_control(struct usb_hc
if ((temp & PORT_RESET)
&& time_after_eq(jiffies,
oxu->reset_done[wIndex])) {
@@ -236,7 +236,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
oxu->reset_done[wIndex] = 0;
/* force reset to complete */
-@@ -3348,20 +3348,20 @@ static int oxu_hub_control(struct usb_hc
+@@ -3347,20 +3347,20 @@ static int oxu_hub_control(struct usb_hc
*/
if (temp & PORT_CONNECT) {
diff --git a/usb/usb-support-for-allocating-usb-3.0-streams.patch b/usb/usb-support-for-allocating-usb-3.0-streams.patch
index 24ffbd0f1eb7f1..ef97e06605f2f6 100644
--- a/usb/usb-support-for-allocating-usb-3.0-streams.patch
+++ b/usb/usb-support-for-allocating-usb-3.0-streams.patch
@@ -33,9 +33,9 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
Documentation/usb/bulk-streams.txt | 78 +++++++++++++++++++++++++++++++++++++
drivers/usb/core/hcd.c | 69 ++++++++++++++++++++++++++++++++
- drivers/usb/core/hcd.h | 10 ++++
drivers/usb/host/xhci-pci.c | 2
include/linux/usb.h | 10 ++++
+ include/linux/usb/hcd.h | 10 ++++
5 files changed, 169 insertions(+)
--- /dev/null
@@ -121,7 +121,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+ensure that drivers that don't support streams will be able to use the endpoint.
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
-@@ -1815,6 +1815,75 @@ void usb_hcd_reset_endpoint(struct usb_d
+@@ -1814,6 +1814,75 @@ void usb_hcd_reset_endpoint(struct usb_d
}
}
@@ -197,25 +197,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
/* Protect against drivers that try to unlink URBs after the device
* is gone, by waiting until all unlinks for @udev are finished.
* Since we don't currently track URBs by device, simply wait until
---- a/drivers/usb/core/hcd.h
-+++ b/drivers/usb/core/hcd.h
-@@ -250,6 +250,16 @@ struct hc_driver {
- int (*alloc_dev)(struct usb_hcd *, struct usb_device *);
- /* Called by usb_disconnect to free HC device structures */
- void (*free_dev)(struct usb_hcd *, struct usb_device *);
-+ /* Change a group of bulk endpoints to support multiple stream IDs */
-+ int (*alloc_streams)(struct usb_hcd *hcd, struct usb_device *udev,
-+ struct usb_host_endpoint **eps, unsigned int num_eps,
-+ unsigned int num_streams, gfp_t mem_flags);
-+ /* Reverts a group of bulk endpoints back to not using stream IDs.
-+ * Can fail if we run out of memory.
-+ */
-+ int (*free_streams)(struct usb_hcd *hcd, struct usb_device *udev,
-+ struct usb_host_endpoint **eps, unsigned int num_eps,
-+ gfp_t mem_flags);
-
- /* Bandwidth computation functions */
- /* Note that add_endpoint() can only be called once per endpoint before
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -132,6 +132,8 @@ static const struct hc_driver xhci_pci_h
@@ -246,3 +227,22 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
/* used these for multi-interface device registration */
extern int usb_driver_claim_interface(struct usb_driver *driver,
struct usb_interface *iface, void *priv);
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -250,6 +250,16 @@ struct hc_driver {
+ int (*alloc_dev)(struct usb_hcd *, struct usb_device *);
+ /* Called by usb_disconnect to free HC device structures */
+ void (*free_dev)(struct usb_hcd *, struct usb_device *);
++ /* Change a group of bulk endpoints to support multiple stream IDs */
++ int (*alloc_streams)(struct usb_hcd *hcd, struct usb_device *udev,
++ struct usb_host_endpoint **eps, unsigned int num_eps,
++ unsigned int num_streams, gfp_t mem_flags);
++ /* Reverts a group of bulk endpoints back to not using stream IDs.
++ * Can fail if we run out of memory.
++ */
++ int (*free_streams)(struct usb_hcd *hcd, struct usb_device *udev,
++ struct usb_host_endpoint **eps, unsigned int num_eps,
++ gfp_t mem_flags);
+
+ /* Bandwidth computation functions */
+ /* Note that add_endpoint() can only be called once per endpoint before
diff --git a/usb/usb-usbserial-mos7720-add-support-for-parallel-port-on-moschip-7715.patch b/usb/usb-usbserial-mos7720-add-support-for-parallel-port-on-moschip-7715.patch
new file mode 100644
index 00000000000000..e9a1319281b9be
--- /dev/null
+++ b/usb/usb-usbserial-mos7720-add-support-for-parallel-port-on-moschip-7715.patch
@@ -0,0 +1,1078 @@
+From mikedunn@newsguy.com Thu Apr 29 16:00:24 2010
+From: mikedunn@newsguy.com
+Date: Thu, 15 Apr 2010 17:01:33 -0400
+Subject: USB: usbserial: mos7720: add support for parallel port on moschip 7715
+To: linux-usb@vger.kernel.org
+Cc: linux-parport@lists.infradead.org, Mike Dunn <mikedunn@newsguy.com>
+Message-ID: <1271365293-3664-1-git-send-email-mikedunn@newsguy.com>
+
+
+From: Mike Dunn <mikedunn@newsguy.com>
+
+Add support for the parallel port on the moschip MCS7715 device. The port
+registers itself with the parport subsystem as a low-level driver. A separate
+entry to the kernel configuration is added beneath that for the mos7720, to
+avoid the need to link with the parport subsystem code for users who don't have
+or don't want the parallel port. Only compatibility mode is currently supported
+(no ECP/EPP). Tested with both moschip devices (7720 and 7715) on UP and SMP
+hosts, including regression testing of serial port, concurrent operation of
+serial and parallel ports, and various connect / disconnect scenarios.
+
+Signed-off-by: Mike Dunn <mikedunn@newsguy.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/usb/usb-serial.txt | 16
+ drivers/usb/serial/Kconfig | 11
+ drivers/usb/serial/mos7720.c | 806 ++++++++++++++++++++++++++++++++++-----
+ 3 files changed, 747 insertions(+), 86 deletions(-)
+
+--- a/Documentation/usb/usb-serial.txt
++++ b/Documentation/usb/usb-serial.txt
+@@ -440,6 +440,22 @@ Winchiphead CH341 Driver
+ For any questions or problems with this driver, please contact
+ frank@kingswood-consulting.co.uk.
+
++Moschip MCS7720, MCS7715 driver
++
++ These chips are present in devices sold by various manufacturers, such as Syba
++ and Cables Unlimited. There may be others. The 7720 provides two serial
++ ports, and the 7715 provides one serial and one standard PC parallel port.
++ Support for the 7715's parallel port is enabled by a separate option, which
++ will not appear unless parallel port support is first enabled at the top-level
++ of the Device Drivers config menu. Currently only compatibility mode is
++ supported on the parallel port (no ECP/EPP).
++
++ TODO:
++ - Implement ECP/EPP modes for the parallel port.
++ - Baud rates higher than 115200 are currently broken.
++ - Devices with a single serial port based on the Moschip MCS7703 may work
++ with this driver with a simple addition to the usb_device_id table. I
++ don't have one of these devices, so I can't say for sure.
+
+ Generic Serial driver
+
+--- a/drivers/usb/serial/Kconfig
++++ b/drivers/usb/serial/Kconfig
+@@ -425,6 +425,17 @@ config USB_SERIAL_MOS7720
+ To compile this driver as a module, choose M here: the
+ module will be called mos7720.
+
++if USB_SERIAL_MOS7720
++config USB_SERIAL_MOS7715_PARPORT
++ bool "Support for parallel port on the Moschip 7715"
++ select PARPORT_NOT_PC
++ depends on PARPORT
++ ---help---
++ Say Y if you have a Moschip 7715 device and would like to use
++ the parallel port it provides. The port will register with
++ the parport subsystem as a low-level driver.
++endif
++
+ config USB_SERIAL_MOS7840
+ tristate "USB Moschip 7840/7820 USB Serial Driver"
+ ---help---
+--- a/drivers/usb/serial/mos7720.c
++++ b/drivers/usb/serial/mos7720.c
+@@ -34,12 +34,12 @@
+ #include <linux/usb.h>
+ #include <linux/usb/serial.h>
+ #include <linux/uaccess.h>
+-
++#include <linux/parport.h>
+
+ /*
+ * Version Information
+ */
+-#define DRIVER_VERSION "1.0.0.4F"
++#define DRIVER_VERSION "2.0"
+ #define DRIVER_AUTHOR "Aspire Communications pvt Ltd."
+ #define DRIVER_DESC "Moschip USB Serial Driver"
+
+@@ -63,7 +63,7 @@
+ #define NUM_URBS 16 /* URB Count */
+ #define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */
+
+-/* This structure holds all of the local port information */
++/* This structure holds all of the local serial port information */
+ struct moschip_port {
+ __u8 shadowLCR; /* last LCR value received */
+ __u8 shadowMCR; /* last MCR value received */
+@@ -74,11 +74,6 @@ struct moschip_port {
+ struct urb *write_urb_pool[NUM_URBS];
+ };
+
+-/* This structure holds all of the individual serial device information */
+-struct moschip_serial {
+- int interrupt_started;
+-};
+-
+ static int debug;
+
+ static struct usb_serial_driver moschip7720_2port_driver;
+@@ -94,6 +89,649 @@ static const struct usb_device_id moschi
+ };
+ MODULE_DEVICE_TABLE(usb, moschip_port_id_table);
+
++#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
++
++/* initial values for parport regs */
++#define DCR_INIT_VAL 0x0c /* SLCTIN, nINIT */
++#define ECR_INIT_VAL 0x00 /* SPP mode */
++
++struct urbtracker {
++ struct mos7715_parport *mos_parport;
++ struct list_head urblist_entry;
++ struct kref ref_count;
++ struct urb *urb;
++};
++
++enum mos7715_pp_modes {
++ SPP = 0<<5,
++ PS2 = 1<<5, /* moschip calls this 'NIBBLE' mode */
++ PPF = 2<<5, /* moschip calls this 'CB-FIFO mode */
++};
++
++struct mos7715_parport {
++ struct parport *pp; /* back to containing struct */
++ struct kref ref_count; /* to instance of this struct */
++ struct list_head deferred_urbs; /* list deferred async urbs */
++ struct list_head active_urbs; /* list async urbs in flight */
++ spinlock_t listlock; /* protects list access */
++ bool msg_pending; /* usb sync call pending */
++ struct completion syncmsg_compl; /* usb sync call completed */
++ struct tasklet_struct urb_tasklet; /* for sending deferred urbs */
++ struct usb_serial *serial; /* back to containing struct */
++ __u8 shadowECR; /* parallel port regs... */
++ __u8 shadowDCR;
++ atomic_t shadowDSR; /* updated in int-in callback */
++};
++
++/* lock guards against dereferencing NULL ptr in parport ops callbacks */
++static DEFINE_SPINLOCK(release_lock);
++
++enum mos_regs {
++ THR, /* serial port regs */
++ RHR,
++ IER,
++ FCR,
++ ISR,
++ LCR,
++ MCR,
++ LSR,
++ MSR,
++ SPR,
++ DLL,
++ DLM,
++ DPR, /* parallel port regs */
++ DSR,
++ DCR,
++ ECR,
++ SP1_REG, /* device control regs */
++ SP2_REG, /* serial port 2 (7720 only) */
++ PP_REG,
++ SP_CONTROL_REG,
++};
++
++/*
++ * Return the correct value for the Windex field of the setup packet
++ * for a control endpoint message. See the 7715 datasheet.
++ */
++static inline __u16 get_reg_index(enum mos_regs reg)
++{
++ static const __u16 mos7715_index_lookup_table[] = {
++ 0x00, /* THR */
++ 0x00, /* RHR */
++ 0x01, /* IER */
++ 0x02, /* FCR */
++ 0x02, /* ISR */
++ 0x03, /* LCR */
++ 0x04, /* MCR */
++ 0x05, /* LSR */
++ 0x06, /* MSR */
++ 0x07, /* SPR */
++ 0x00, /* DLL */
++ 0x01, /* DLM */
++ 0x00, /* DPR */
++ 0x01, /* DSR */
++ 0x02, /* DCR */
++ 0x0a, /* ECR */
++ 0x01, /* SP1_REG */
++ 0x02, /* SP2_REG (7720 only) */
++ 0x04, /* PP_REG (7715 only) */
++ 0x08, /* SP_CONTROL_REG */
++ };
++ return mos7715_index_lookup_table[reg];
++}
++
++/*
++ * Return the correct value for the upper byte of the Wvalue field of
++ * the setup packet for a control endpoint message.
++ */
++static inline __u16 get_reg_value(enum mos_regs reg)
++{
++ if (reg >= SP1_REG) /* control reg */
++ return 0x0000;
++ else /* parallel port reg (7715 only) */
++ return 0x0100;
++}
++
++/*
++ * Write data byte to the specified device register. The data is embedded in
++ * the value field of the setup packet.
++ */
++static int write_parport_reg(struct mos7715_parport *mos_parport,
++ enum mos_regs reg, __u8 data)
++{
++ struct usb_serial *serial = mos_parport->serial;
++ struct usb_device *usbdev = serial->dev;
++ unsigned int pipe = usb_sndctrlpipe(usbdev, 0);
++ __u8 request = (__u8)0x0e;
++ __u8 requesttype = (__u8)0x40;
++ __u16 value = get_reg_value(reg) + data;
++ __u16 index = get_reg_index(reg);
++ __u16 size = 0;
++ int status;
++ status = usb_control_msg(usbdev, pipe, request, requesttype, value,
++ index, NULL, size, MOS_WDR_TIMEOUT);
++ if (status < 0)
++ dev_err(&usbdev->dev,
++ "mos7720: usb_control_msg() failed: %d", status);
++ return status;
++}
++
++/*
++ * Read data byte from the specified device register. The data returned by the
++ * device is embedded in the value field of the setup packet.
++ */
++static int read_parport_reg(struct mos7715_parport *mos_parport,
++ enum mos_regs reg, __u8 *data)
++{
++ struct usb_device *usbdev = mos_parport->serial->dev;
++ unsigned int pipe = usb_rcvctrlpipe(usbdev, 0);
++ __u8 request = (__u8)0x0d;
++ __u8 requesttype = (__u8)0xc0;
++ __u16 value = get_reg_value(reg);
++ __u16 index = get_reg_index(reg);
++ __u16 size = 1;
++ int status = usb_control_msg(usbdev, pipe, request, requesttype, value,
++ index, data, size, MOS_WDR_TIMEOUT);
++ if (status < 0)
++ dev_err(&usbdev->dev,
++ "mos7720: usb_control_msg() failed: %d", status);
++ return status;
++}
++
++static inline int mos7715_change_mode(struct mos7715_parport *mos_parport,
++ enum mos7715_pp_modes mode)
++{
++ mos_parport->shadowECR = mode;
++ write_parport_reg(mos_parport, ECR, mos_parport->shadowECR);
++ return 0;
++}
++
++static void destroy_mos_parport(struct kref *kref)
++{
++ struct mos7715_parport *mos_parport =
++ container_of(kref, struct mos7715_parport, ref_count);
++
++ dbg("%s called", __func__);
++ kfree(mos_parport);
++}
++
++static void destroy_urbtracker(struct kref *kref)
++{
++ struct urbtracker *urbtrack =
++ container_of(kref, struct urbtracker, ref_count);
++ struct mos7715_parport *mos_parport = urbtrack->mos_parport;
++ dbg("%s called", __func__);
++ usb_free_urb(urbtrack->urb);
++ kfree(urbtrack);
++ kref_put(&mos_parport->ref_count, destroy_mos_parport);
++}
++
++/*
++ * This runs as a tasklet when sending an urb in a non-blocking parallel
++ * port callback had to be deferred because the disconnect mutex could not be
++ * obtained at the time.
++ */
++static void send_deferred_urbs(unsigned long _mos_parport)
++{
++ int ret_val;
++ unsigned long flags;
++ struct mos7715_parport *mos_parport = (void *)_mos_parport;
++ struct urbtracker *urbtrack;
++ struct list_head *cursor, *next;
++
++ dbg("%s called", __func__);
++
++ /* if release function ran, game over */
++ if (unlikely(mos_parport->serial == NULL))
++ return;
++
++ /* try again to get the mutex */
++ if (!mutex_trylock(&mos_parport->serial->disc_mutex)) {
++ dbg("%s: rescheduling tasklet", __func__);
++ tasklet_schedule(&mos_parport->urb_tasklet);
++ return;
++ }
++
++ /* if device disconnected, game over */
++ if (unlikely(mos_parport->serial->disconnected)) {
++ mutex_unlock(&mos_parport->serial->disc_mutex);
++ return;
++ }
++
++ spin_lock_irqsave(&mos_parport->listlock, flags);
++ if (list_empty(&mos_parport->deferred_urbs)) {
++ spin_unlock_irqrestore(&mos_parport->listlock, flags);
++ mutex_unlock(&mos_parport->serial->disc_mutex);
++ dbg("%s: deferred_urbs list empty", __func__);
++ return;
++ }
++
++ /* move contents of deferred_urbs list to active_urbs list and submit */
++ list_for_each_safe(cursor, next, &mos_parport->deferred_urbs)
++ list_move_tail(cursor, &mos_parport->active_urbs);
++ list_for_each_entry(urbtrack, &mos_parport->active_urbs,
++ urblist_entry) {
++ ret_val = usb_submit_urb(urbtrack->urb, GFP_ATOMIC);
++ dbg("%s: urb submitted", __func__);
++ if (ret_val) {
++ dev_err(&mos_parport->serial->dev->dev,
++ "usb_submit_urb() failed: %d", ret_val);
++ list_del(&urbtrack->urblist_entry);
++ kref_put(&urbtrack->ref_count, destroy_urbtracker);
++ }
++ }
++ spin_unlock_irqrestore(&mos_parport->listlock, flags);
++ mutex_unlock(&mos_parport->serial->disc_mutex);
++}
++
++/* callback for parallel port control urbs submitted asynchronously */
++static void async_complete(struct urb *urb)
++{
++ struct urbtracker *urbtrack = urb->context;
++ int status = urb->status;
++ dbg("%s called", __func__);
++ if (unlikely(status))
++ dbg("%s - nonzero urb status received: %d", __func__, status);
++
++ /* remove the urbtracker from the active_urbs list */
++ spin_lock(&urbtrack->mos_parport->listlock);
++ list_del(&urbtrack->urblist_entry);
++ spin_unlock(&urbtrack->mos_parport->listlock);
++ kref_put(&urbtrack->ref_count, destroy_urbtracker);
++}
++
++static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
++ enum mos_regs reg, __u8 data)
++{
++ struct urbtracker *urbtrack;
++ int ret_val;
++ unsigned long flags;
++ struct usb_ctrlrequest setup;
++ struct usb_serial *serial = mos_parport->serial;
++ struct usb_device *usbdev = serial->dev;
++ dbg("%s called", __func__);
++
++ /* create and initialize the control urb and containing urbtracker */
++ urbtrack = kmalloc(sizeof(struct urbtracker), GFP_ATOMIC);
++ if (urbtrack == NULL) {
++ dev_err(&usbdev->dev, "out of memory");
++ return -ENOMEM;
++ }
++ kref_get(&mos_parport->ref_count);
++ urbtrack->mos_parport = mos_parport;
++ urbtrack->urb = usb_alloc_urb(0, GFP_ATOMIC);
++ if (urbtrack->urb == NULL) {
++ dev_err(&usbdev->dev, "out of urbs");
++ kfree(urbtrack);
++ return -ENOMEM;
++ }
++ setup.bRequestType = (__u8)0x40;
++ setup.bRequest = (__u8)0x0e;
++ setup.wValue = get_reg_value(reg);
++ setup.wIndex = get_reg_index(reg);
++ setup.wLength = 0;
++ usb_fill_control_urb(urbtrack->urb, usbdev,
++ usb_sndctrlpipe(usbdev, 0),
++ (unsigned char *)&setup,
++ NULL, 0, async_complete, urbtrack);
++ kref_init(&urbtrack->ref_count);
++ INIT_LIST_HEAD(&urbtrack->urblist_entry);
++
++ /*
++ * get the disconnect mutex, or add tracker to the deferred_urbs list
++ * and schedule a tasklet to try again later
++ */
++ if (!mutex_trylock(&serial->disc_mutex)) {
++ spin_lock_irqsave(&mos_parport->listlock, flags);
++ list_add_tail(&urbtrack->urblist_entry,
++ &mos_parport->deferred_urbs);
++ spin_unlock_irqrestore(&mos_parport->listlock, flags);
++ tasklet_schedule(&mos_parport->urb_tasklet);
++ dbg("tasklet scheduled");
++ return 0;
++ }
++
++ /* bail if device disconnected */
++ if (serial->disconnected) {
++ kref_put(&urbtrack->ref_count, destroy_urbtracker);
++ mutex_unlock(&serial->disc_mutex);
++ return -ENODEV;
++ }
++
++ /* add the tracker to the active_urbs list and submit */
++ spin_lock_irqsave(&mos_parport->listlock, flags);
++ list_add_tail(&urbtrack->urblist_entry, &mos_parport->active_urbs);
++ spin_unlock_irqrestore(&mos_parport->listlock, flags);
++ ret_val = usb_submit_urb(urbtrack->urb, GFP_ATOMIC);
++ mutex_unlock(&serial->disc_mutex);
++ if (ret_val) {
++ dev_err(&usbdev->dev,
++ "%s: submit_urb() failed: %d", __func__, ret_val);
++ spin_lock_irqsave(&mos_parport->listlock, flags);
++ list_del(&urbtrack->urblist_entry);
++ spin_unlock_irqrestore(&mos_parport->listlock, flags);
++ kref_put(&urbtrack->ref_count, destroy_urbtracker);
++ return ret_val;
++ }
++ return 0;
++}
++
++/*
++ * This is the the common top part of all parallel port callback operations that
++ * send synchronous messages to the device. This implements convoluted locking
++ * that avoids two scenarios: (1) a port operation is called after usbserial
++ * has called our release function, at which point struct mos7715_parport has
++ * been destroyed, and (2) the device has been disconnected, but usbserial has
++ * not called the release function yet because someone has a serial port open.
++ * The shared release_lock prevents the first, and the mutex and disconnected
++ * flag maintained by usbserial covers the second. We also use the msg_pending
++ * flag to ensure that all synchronous usb messgage calls have completed before
++ * our release function can return.
++ */
++static int parport_prologue(struct parport *pp)
++{
++ struct mos7715_parport *mos_parport;
++
++ spin_lock(&release_lock);
++ mos_parport = pp->private_data;
++ if (unlikely(mos_parport == NULL)) {
++ /* release fn called, port struct destroyed */
++ spin_unlock(&release_lock);
++ return -1;
++ }
++ mos_parport->msg_pending = true; /* synch usb call pending */
++ INIT_COMPLETION(mos_parport->syncmsg_compl);
++ spin_unlock(&release_lock);
++
++ mutex_lock(&mos_parport->serial->disc_mutex);
++ if (mos_parport->serial->disconnected) {
++ /* device disconnected */
++ mutex_unlock(&mos_parport->serial->disc_mutex);
++ mos_parport->msg_pending = false;
++ complete(&mos_parport->syncmsg_compl);
++ return -1;
++ }
++
++ return 0;
++}
++
++/*
++ * This is the the common bottom part of all parallel port functions that send
++ * synchronous messages to the device.
++ */
++static inline void parport_epilogue(struct parport *pp)
++{
++ struct mos7715_parport *mos_parport = pp->private_data;
++ mutex_unlock(&mos_parport->serial->disc_mutex);
++ mos_parport->msg_pending = false;
++ complete(&mos_parport->syncmsg_compl);
++}
++
++static void parport_mos7715_write_data(struct parport *pp, unsigned char d)
++{
++ struct mos7715_parport *mos_parport = pp->private_data;
++ dbg("%s called: %2.2x", __func__, d);
++ if (parport_prologue(pp) < 0)
++ return;
++ mos7715_change_mode(mos_parport, SPP);
++ write_parport_reg(mos_parport, DPR, (__u8)d);
++ parport_epilogue(pp);
++}
++
++static unsigned char parport_mos7715_read_data(struct parport *pp)
++{
++ struct mos7715_parport *mos_parport = pp->private_data;
++ unsigned char d;
++ dbg("%s called", __func__);
++ if (parport_prologue(pp) < 0)
++ return 0;
++ read_parport_reg(mos_parport, DPR, &d);
++ parport_epilogue(pp);
++ return d;
++}
++
++static void parport_mos7715_write_control(struct parport *pp, unsigned char d)
++{
++ struct mos7715_parport *mos_parport = pp->private_data;
++ __u8 data;
++ dbg("%s called: %2.2x", __func__, d);
++ if (parport_prologue(pp) < 0)
++ return;
++ data = ((__u8)d & 0x0f) | (mos_parport->shadowDCR & 0xf0);
++ write_parport_reg(mos_parport, DCR, data);
++ mos_parport->shadowDCR = data;
++ parport_epilogue(pp);
++}
++
++static unsigned char parport_mos7715_read_control(struct parport *pp)
++{
++ struct mos7715_parport *mos_parport = pp->private_data;
++ __u8 dcr;
++ dbg("%s called", __func__);
++ spin_lock(&release_lock);
++ mos_parport = pp->private_data;
++ if (unlikely(mos_parport == NULL)) {
++ spin_unlock(&release_lock);
++ return 0;
++ }
++ dcr = mos_parport->shadowDCR & 0x0f;
++ spin_unlock(&release_lock);
++ return dcr;
++}
++
++static unsigned char parport_mos7715_frob_control(struct parport *pp,
++ unsigned char mask,
++ unsigned char val)
++{
++ struct mos7715_parport *mos_parport = pp->private_data;
++ __u8 dcr;
++ dbg("%s called", __func__);
++ mask &= 0x0f;
++ val &= 0x0f;
++ if (parport_prologue(pp) < 0)
++ return 0;
++ mos_parport->shadowDCR = (mos_parport->shadowDCR & (~mask)) ^ val;
++ write_parport_reg(mos_parport, DCR, mos_parport->shadowDCR);
++ dcr = mos_parport->shadowDCR & 0x0f;
++ parport_epilogue(pp);
++ return dcr;
++}
++
++static unsigned char parport_mos7715_read_status(struct parport *pp)
++{
++ unsigned char status;
++ struct mos7715_parport *mos_parport = pp->private_data;
++ dbg("%s called", __func__);
++ spin_lock(&release_lock);
++ mos_parport = pp->private_data;
++ if (unlikely(mos_parport == NULL)) { /* release called */
++ spin_unlock(&release_lock);
++ return 0;
++ }
++ status = atomic_read(&mos_parport->shadowDSR) & 0xf8;
++ spin_unlock(&release_lock);
++ return status;
++}
++
++static void parport_mos7715_enable_irq(struct parport *pp)
++{
++ dbg("%s called", __func__);
++}
++static void parport_mos7715_disable_irq(struct parport *pp)
++{
++ dbg("%s called", __func__);
++}
++
++static void parport_mos7715_data_forward(struct parport *pp)
++{
++ struct mos7715_parport *mos_parport = pp->private_data;
++ dbg("%s called", __func__);
++ if (parport_prologue(pp) < 0)
++ return;
++ mos7715_change_mode(mos_parport, PS2);
++ mos_parport->shadowDCR &= ~0x20;
++ write_parport_reg(mos_parport, DCR, mos_parport->shadowDCR);
++ parport_epilogue(pp);
++}
++
++static void parport_mos7715_data_reverse(struct parport *pp)
++{
++ struct mos7715_parport *mos_parport = pp->private_data;
++ dbg("%s called", __func__);
++ if (parport_prologue(pp) < 0)
++ return;
++ mos7715_change_mode(mos_parport, PS2);
++ mos_parport->shadowDCR |= 0x20;
++ write_parport_reg(mos_parport, DCR, mos_parport->shadowDCR);
++ parport_epilogue(pp);
++}
++
++static void parport_mos7715_init_state(struct pardevice *dev,
++ struct parport_state *s)
++{
++ dbg("%s called", __func__);
++ s->u.pc.ctr = DCR_INIT_VAL;
++ s->u.pc.ecr = ECR_INIT_VAL;
++}
++
++/* N.B. Parport core code requires that this function not block */
++static void parport_mos7715_save_state(struct parport *pp,
++ struct parport_state *s)
++{
++ struct mos7715_parport *mos_parport;
++ dbg("%s called", __func__);
++ spin_lock(&release_lock);
++ mos_parport = pp->private_data;
++ if (unlikely(mos_parport == NULL)) { /* release called */
++ spin_unlock(&release_lock);
++ return;
++ }
++ s->u.pc.ctr = mos_parport->shadowDCR;
++ s->u.pc.ecr = mos_parport->shadowECR;
++ spin_unlock(&release_lock);
++}
++
++/* N.B. Parport core code requires that this function not block */
++static void parport_mos7715_restore_state(struct parport *pp,
++ struct parport_state *s)
++{
++ struct mos7715_parport *mos_parport;
++ dbg("%s called", __func__);
++ spin_lock(&release_lock);
++ mos_parport = pp->private_data;
++ if (unlikely(mos_parport == NULL)) { /* release called */
++ spin_unlock(&release_lock);
++ return;
++ }
++ write_parport_reg_nonblock(mos_parport, DCR, mos_parport->shadowDCR);
++ write_parport_reg_nonblock(mos_parport, ECR, mos_parport->shadowECR);
++ spin_unlock(&release_lock);
++}
++
++static size_t parport_mos7715_write_compat(struct parport *pp,
++ const void *buffer,
++ size_t len, int flags)
++{
++ int retval;
++ struct mos7715_parport *mos_parport = pp->private_data;
++ int actual_len;
++ dbg("%s called: %u chars", __func__, (unsigned int)len);
++ if (parport_prologue(pp) < 0)
++ return 0;
++ mos7715_change_mode(mos_parport, PPF);
++ retval = usb_bulk_msg(mos_parport->serial->dev,
++ usb_sndbulkpipe(mos_parport->serial->dev, 2),
++ (void *)buffer, len, &actual_len,
++ MOS_WDR_TIMEOUT);
++ parport_epilogue(pp);
++ if (retval) {
++ dev_err(&mos_parport->serial->dev->dev,
++ "mos7720: usb_bulk_msg() failed: %d", retval);
++ return 0;
++ }
++ return actual_len;
++}
++
++static struct parport_operations parport_mos7715_ops = {
++ .owner = THIS_MODULE,
++ .write_data = parport_mos7715_write_data,
++ .read_data = parport_mos7715_read_data,
++
++ .write_control = parport_mos7715_write_control,
++ .read_control = parport_mos7715_read_control,
++ .frob_control = parport_mos7715_frob_control,
++
++ .read_status = parport_mos7715_read_status,
++
++ .enable_irq = parport_mos7715_enable_irq,
++ .disable_irq = parport_mos7715_disable_irq,
++
++ .data_forward = parport_mos7715_data_forward,
++ .data_reverse = parport_mos7715_data_reverse,
++
++ .init_state = parport_mos7715_init_state,
++ .save_state = parport_mos7715_save_state,
++ .restore_state = parport_mos7715_restore_state,
++
++ .compat_write_data = parport_mos7715_write_compat,
++
++ .nibble_read_data = parport_ieee1284_read_nibble,
++ .byte_read_data = parport_ieee1284_read_byte,
++};
++
++/*
++ * Allocate and initialize parallel port control struct, initialize
++ * the parallel port hardware device, and register with the parport subsystem.
++ */
++static int mos7715_parport_init(struct usb_serial *serial)
++{
++ struct mos7715_parport *mos_parport;
++
++ /* allocate and initialize parallel port control struct */
++ mos_parport = kzalloc(sizeof(struct mos7715_parport), GFP_KERNEL);
++ if (mos_parport == NULL) {
++ dbg("mos7715_parport_init: kzalloc failed");
++ return -ENOMEM;
++ }
++ mos_parport->msg_pending = false;
++ kref_init(&mos_parport->ref_count);
++ spin_lock_init(&mos_parport->listlock);
++ INIT_LIST_HEAD(&mos_parport->active_urbs);
++ INIT_LIST_HEAD(&mos_parport->deferred_urbs);
++ usb_set_serial_data(serial, mos_parport); /* hijack private pointer */
++ mos_parport->serial = serial;
++ tasklet_init(&mos_parport->urb_tasklet, send_deferred_urbs,
++ (unsigned long) mos_parport);
++ init_completion(&mos_parport->syncmsg_compl);
++
++ /* cycle parallel port reset bit */
++ write_parport_reg(mos_parport, PP_REG, (__u8)0x80);
++ write_parport_reg(mos_parport, PP_REG, (__u8)0x00);
++
++ /* initialize device registers */
++ mos_parport->shadowDCR = DCR_INIT_VAL;
++ write_parport_reg(mos_parport, DCR, mos_parport->shadowDCR);
++ mos_parport->shadowECR = ECR_INIT_VAL;
++ write_parport_reg(mos_parport, ECR, mos_parport->shadowECR);
++
++ /* register with parport core */
++ mos_parport->pp = parport_register_port(0, PARPORT_IRQ_NONE,
++ PARPORT_DMA_NONE,
++ &parport_mos7715_ops);
++ if (mos_parport->pp == NULL) {
++ dev_err(&serial->interface->dev,
++ "Could not register parport\n");
++ kref_put(&mos_parport->ref_count, destroy_mos_parport);
++ return -EIO;
++ }
++ mos_parport->pp->private_data = mos_parport;
++ mos_parport->pp->modes = PARPORT_MODE_COMPAT | PARPORT_MODE_PCSPP;
++ mos_parport->pp->dev = &serial->interface->dev;
++ parport_announce_port(mos_parport->pp);
++
++ return 0;
++}
++#endif /* CONFIG_USB_SERIAL_MOS7715_PARPORT */
+
+ /*
+ * mos7720_interrupt_callback
+@@ -109,8 +747,6 @@ static void mos7720_interrupt_callback(s
+ __u8 sp1;
+ __u8 sp2;
+
+- dbg(" : Entering");
+-
+ switch (status) {
+ case 0:
+ /* success */
+@@ -118,6 +754,7 @@ static void mos7720_interrupt_callback(s
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
++ case -ENODEV:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d", __func__,
+ status);
+@@ -161,7 +798,7 @@ static void mos7720_interrupt_callback(s
+ dbg("Serial Port 1: Receiver time out");
+ break;
+ case SERIAL_IIR_MS:
+- dbg("Serial Port 1: Modem status change");
++ /* dbg("Serial Port 1: Modem status change"); */
+ break;
+ }
+
+@@ -174,7 +811,7 @@ static void mos7720_interrupt_callback(s
+ dbg("Serial Port 2: Receiver time out");
+ break;
+ case SERIAL_IIR_MS:
+- dbg("Serial Port 2: Modem status change");
++ /* dbg("Serial Port 2: Modem status change"); */
+ break;
+ }
+ }
+@@ -208,6 +845,7 @@ static void mos7715_interrupt_callback(s
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
++ case -ENODEV:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d", __func__,
+ status);
+@@ -243,11 +881,21 @@ static void mos7715_interrupt_callback(s
+ dbg("Serial Port: Receiver time out");
+ break;
+ case SERIAL_IIR_MS:
+- dbg("Serial Port: Modem status change");
++ /* dbg("Serial Port: Modem status change"); */
+ break;
+ }
+ }
+
++#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
++ { /* update local copy of DSR reg */
++ struct usb_serial_port *port = urb->context;
++ struct mos7715_parport *mos_parport = port->serial->private;
++ if (unlikely(mos_parport == NULL))
++ return;
++ atomic_set(&mos_parport->shadowDSR, data[2]);
++ }
++#endif
++
+ exit:
+ result = usb_submit_urb(urb, GFP_ATOMIC);
+ if (result)
+@@ -267,7 +915,6 @@ static void mos7720_bulk_in_callback(str
+ int retval;
+ unsigned char *data ;
+ struct usb_serial_port *port;
+- struct moschip_port *mos7720_port;
+ struct tty_struct *tty;
+ int status = urb->status;
+
+@@ -276,13 +923,7 @@ static void mos7720_bulk_in_callback(str
+ return;
+ }
+
+- mos7720_port = urb->context;
+- if (!mos7720_port) {
+- dbg("NULL mos7720_port pointer");
+- return ;
+- }
+-
+- port = mos7720_port->port;
++ port = urb->context;
+
+ dbg("Entering...%s", __func__);
+
+@@ -332,8 +973,6 @@ static void mos7720_bulk_out_data_callba
+ return ;
+ }
+
+- dbg("Entering .........");
+-
+ tty = tty_port_tty_get(&mos7720_port->port->port);
+
+ if (tty && mos7720_port->open)
+@@ -424,7 +1063,6 @@ static int mos7720_open(struct tty_struc
+ struct usb_serial *serial;
+ struct usb_serial_port *port0;
+ struct urb *urb;
+- struct moschip_serial *mos7720_serial;
+ struct moschip_port *mos7720_port;
+ int response;
+ int port_number;
+@@ -440,11 +1078,6 @@ static int mos7720_open(struct tty_struc
+
+ port0 = serial->port[0];
+
+- mos7720_serial = usb_get_serial_data(serial);
+-
+- if (mos7720_serial == NULL || port0 == NULL)
+- return -ENODEV;
+-
+ usb_clear_halt(serial->dev, port->write_urb->pipe);
+ usb_clear_halt(serial->dev, port->read_urb->pipe);
+
+@@ -549,43 +1182,6 @@ static int mos7720_open(struct tty_struc
+ data = 0x0c;
+ send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
+
+- /* see if we've set up our endpoint info yet *
+- * (can't set it up in mos7720_startup as the *
+- * structures were not set up at that time.) */
+- if (!mos7720_serial->interrupt_started) {
+- dbg("Interrupt buffer NULL !!!");
+-
+- /* not set up yet, so do it now */
+- mos7720_serial->interrupt_started = 1;
+-
+- dbg("To Submit URB !!!");
+-
+- /* set up our interrupt urb */
+- usb_fill_int_urb(port0->interrupt_in_urb, serial->dev,
+- usb_rcvintpipe(serial->dev,
+- port->interrupt_in_endpointAddress),
+- port0->interrupt_in_buffer,
+- port0->interrupt_in_urb->transfer_buffer_length,
+- mos7720_interrupt_callback, mos7720_port,
+- port0->interrupt_in_urb->interval);
+-
+- /* start interrupt read for this mos7720 this interrupt *
+- * will continue as long as the mos7720 is connected */
+- dbg("Submit URB over !!!");
+- response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL);
+- if (response)
+- dev_err(&port->dev,
+- "%s - Error %d submitting control urb\n",
+- __func__, response);
+- }
+-
+- /* set up our bulk in urb */
+- usb_fill_bulk_urb(port->read_urb, serial->dev,
+- usb_rcvbulkpipe(serial->dev,
+- port->bulk_in_endpointAddress),
+- port->bulk_in_buffer,
+- port->read_urb->transfer_buffer_length,
+- mos7720_bulk_in_callback, mos7720_port);
+ response = usb_submit_urb(port->read_urb, GFP_KERNEL);
+ if (response)
+ dev_err(&port->dev, "%s - Error %d submitting read urb\n",
+@@ -897,6 +1493,7 @@ static void mos7720_unthrottle(struct tt
+ }
+ }
+
++/* FIXME: this function does not work */
+ static int set_higher_rates(struct moschip_port *mos7720_port,
+ unsigned int baud)
+ {
+@@ -939,6 +1536,7 @@ static int set_higher_rates(struct mosch
+ * Set for higher rates *
+ ***********************************************/
+
++ /* writing baud rate verbatum into uart clock field clearly not right */
+ data = baud * 0x10;
+ send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data);
+
+@@ -1308,7 +1906,7 @@ static void mos7720_set_termios(struct t
+ return;
+ }
+
+- dbg("setting termios - ASPIRE");
++ dbg("%s\n", "setting termios - ASPIRE");
+
+ cflag = tty->termios->c_cflag;
+
+@@ -1326,7 +1924,7 @@ static void mos7720_set_termios(struct t
+ change_port_settings(tty, mos7720_port, old_termios);
+
+ if (!port->read_urb) {
+- dbg("URB KILLED !!!!!");
++ dbg("%s", "URB KILLED !!!!!");
+ return;
+ }
+
+@@ -1590,12 +2188,12 @@ static int mos7720_ioctl(struct tty_stru
+
+ static int mos7720_startup(struct usb_serial *serial)
+ {
+- struct moschip_serial *mos7720_serial;
+ struct moschip_port *mos7720_port;
+ struct usb_device *dev;
+ int i;
+ char data;
+ u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
++ int ret_val;
+
+ dbg("%s: Entering ..........", __func__);
+
+@@ -1606,15 +2204,6 @@ static int mos7720_startup(struct usb_se
+
+ dev = serial->dev;
+
+- /* create our private serial structure */
+- mos7720_serial = kzalloc(sizeof(struct moschip_serial), GFP_KERNEL);
+- if (mos7720_serial == NULL) {
+- dev_err(&dev->dev, "%s - Out of memory\n", __func__);
+- return -ENOMEM;
+- }
+-
+- usb_set_serial_data(serial, mos7720_serial);
+-
+ /*
+ * The 7715 uses the first bulk in/out endpoint pair for the parallel
+ * port, and the second for the serial port. Because the usbserial core
+@@ -1638,16 +2227,12 @@ static int mos7720_startup(struct usb_se
+ serial->port[1]->interrupt_in_buffer = NULL;
+ }
+
+- /* we set up the pointers to the endpoints in the mos7720_open *
+- * function, as the structures aren't created yet. */
+
+- /* set up port private structures */
++ /* set up serial port private structures */
+ for (i = 0; i < serial->num_ports; ++i) {
+ mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
+ if (mos7720_port == NULL) {
+ dev_err(&dev->dev, "%s - Out of memory\n", __func__);
+- usb_set_serial_data(serial, NULL);
+- kfree(mos7720_serial);
+ return -ENOMEM;
+ }
+
+@@ -1669,6 +2254,20 @@ static int mos7720_startup(struct usb_se
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ);
+
++ /* start the interrupt urb */
++ ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
++ if (ret_val)
++ dev_err(&dev->dev,
++ "%s - Error %d submitting control urb\n",
++ __func__, ret_val);
++
++#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
++ if (product == MOSCHIP_DEVICE_ID_7715) {
++ ret_val = mos7715_parport_init(serial);
++ if (ret_val < 0)
++ return ret_val;
++ }
++#endif
+ /* LSR For Port 1 */
+ send_mos_cmd(serial, MOS_READ, 0x00, UART_LSR, &data);
+ dbg("LSR:%x", data);
+@@ -1684,12 +2283,47 @@ static void mos7720_release(struct usb_s
+ {
+ int i;
+
++#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
++ /* close the parallel port */
++
++ if (le16_to_cpu(serial->dev->descriptor.idProduct)
++ == MOSCHIP_DEVICE_ID_7715) {
++ struct urbtracker *urbtrack;
++ unsigned long flags;
++ struct mos7715_parport *mos_parport =
++ usb_get_serial_data(serial);
++
++ /* prevent NULL ptr dereference in port callbacks */
++ spin_lock(&release_lock);
++ mos_parport->pp->private_data = NULL;
++ spin_unlock(&release_lock);
++
++ /* wait for synchronous usb calls to return */
++ if (mos_parport->msg_pending)
++ wait_for_completion_timeout(&mos_parport->syncmsg_compl,
++ MOS_WDR_TIMEOUT);
++
++ parport_remove_port(mos_parport->pp);
++ usb_set_serial_data(serial, NULL);
++ mos_parport->serial = NULL;
++
++ /* if tasklet currently scheduled, wait for it to complete */
++ tasklet_kill(&mos_parport->urb_tasklet);
++
++ /* unlink any urbs sent by the tasklet */
++ spin_lock_irqsave(&mos_parport->listlock, flags);
++ list_for_each_entry(urbtrack,
++ &mos_parport->active_urbs,
++ urblist_entry)
++ usb_unlink_urb(urbtrack->urb);
++ spin_unlock_irqrestore(&mos_parport->listlock, flags);
++
++ kref_put(&mos_parport->ref_count, destroy_mos_parport);
++ }
++#endif
+ /* free private structure allocated for serial port */
+ for (i = 0; i < serial->num_ports; ++i)
+ kfree(usb_get_serial_port_data(serial->port[i]));
+-
+- /* free private structure allocated for serial device */
+- kfree(usb_get_serial_data(serial));
+ }
+
+ static struct usb_driver usb_driver = {
diff --git a/usb/usb-usbserial-mos7720-cleanup-consolidation-replace-send_mos_cmd-with-read-write-_mos_reg.patch b/usb/usb-usbserial-mos7720-cleanup-consolidation-replace-send_mos_cmd-with-read-write-_mos_reg.patch
new file mode 100644
index 00000000000000..6060d5457c7a57
--- /dev/null
+++ b/usb/usb-usbserial-mos7720-cleanup-consolidation-replace-send_mos_cmd-with-read-write-_mos_reg.patch
@@ -0,0 +1,747 @@
+From mikedunn@newsguy.com Thu Apr 29 16:01:05 2010
+From: mikedunn@newsguy.com
+Date: Thu, 15 Apr 2010 17:02:09 -0400
+Subject: USB: usbserial: mos7720: cleanup, consolidation, replace send_mos_cmd with {read,write}_mos_reg
+To: linux-usb@vger.kernel.org
+Cc: linux-parport@lists.infradead.org, Mike Dunn <mikedunn@newsguy.com>
+Message-ID: <1271365329-3696-1-git-send-email-mikedunn@newsguy.com>
+
+
+From: Mike Dunn <mikedunn@newsguy.com>
+
+No functionality added or bugs fixed, just improved code consistency and
+(hopefully) readability by replacing send_mos_cmd with the register read & write
+functions that were used for parallel port registers. Also shortens overall
+file length.
+
+Thoroughly tested, with emphasis on regression testing the serial port.
+
+Signed-off-by: Mike Dunn <mikedunn@newsguy.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/mos7720.c | 392 +++++++++++++------------------------------
+ 1 file changed, 124 insertions(+), 268 deletions(-)
+
+--- a/drivers/usb/serial/mos7720.c
++++ b/drivers/usb/serial/mos7720.c
+@@ -39,16 +39,13 @@
+ /*
+ * Version Information
+ */
+-#define DRIVER_VERSION "2.0"
++#define DRIVER_VERSION "2.1"
+ #define DRIVER_AUTHOR "Aspire Communications pvt Ltd."
+ #define DRIVER_DESC "Moschip USB Serial Driver"
+
+ /* default urb timeout */
+ #define MOS_WDR_TIMEOUT (HZ * 5)
+
+-#define MOS_PORT1 0x0200
+-#define MOS_PORT2 0x0300
+-#define MOS_VENREG 0x0000
+ #define MOS_MAX_PORT 0x02
+ #define MOS_WRITE 0x0E
+ #define MOS_READ 0x0D
+@@ -126,6 +123,10 @@ struct mos7715_parport {
+ /* lock guards against dereferencing NULL ptr in parport ops callbacks */
+ static DEFINE_SPINLOCK(release_lock);
+
++#endif /* CONFIG_USB_SERIAL_MOS7715_PARPORT */
++
++static const unsigned int dummy; /* for clarity in register access fns */
++
+ enum mos_regs {
+ THR, /* serial port regs */
+ RHR,
+@@ -184,32 +185,35 @@ static inline __u16 get_reg_index(enum m
+ * Return the correct value for the upper byte of the Wvalue field of
+ * the setup packet for a control endpoint message.
+ */
+-static inline __u16 get_reg_value(enum mos_regs reg)
++static inline __u16 get_reg_value(enum mos_regs reg,
++ unsigned int serial_portnum)
+ {
+ if (reg >= SP1_REG) /* control reg */
+ return 0x0000;
+- else /* parallel port reg (7715 only) */
++
++ else if (reg >= DPR) /* parallel port reg (7715 only) */
+ return 0x0100;
++
++ else /* serial port reg */
++ return (serial_portnum + 2) << 8;
+ }
+
+ /*
+ * Write data byte to the specified device register. The data is embedded in
+- * the value field of the setup packet.
++ * the value field of the setup packet. serial_portnum is ignored for registers
++ * not specific to a particular serial port.
+ */
+-static int write_parport_reg(struct mos7715_parport *mos_parport,
+- enum mos_regs reg, __u8 data)
++static int write_mos_reg(struct usb_serial *serial, unsigned int serial_portnum,
++ enum mos_regs reg, __u8 data)
+ {
+- struct usb_serial *serial = mos_parport->serial;
+ struct usb_device *usbdev = serial->dev;
+ unsigned int pipe = usb_sndctrlpipe(usbdev, 0);
+ __u8 request = (__u8)0x0e;
+ __u8 requesttype = (__u8)0x40;
+- __u16 value = get_reg_value(reg) + data;
+ __u16 index = get_reg_index(reg);
+- __u16 size = 0;
+- int status;
+- status = usb_control_msg(usbdev, pipe, request, requesttype, value,
+- index, NULL, size, MOS_WDR_TIMEOUT);
++ __u16 value = get_reg_value(reg, serial_portnum) + data;
++ int status = usb_control_msg(usbdev, pipe, request, requesttype, value,
++ index, NULL, 0, MOS_WDR_TIMEOUT);
+ if (status < 0)
+ dev_err(&usbdev->dev,
+ "mos7720: usb_control_msg() failed: %d", status);
+@@ -218,31 +222,33 @@ static int write_parport_reg(struct mos7
+
+ /*
+ * Read data byte from the specified device register. The data returned by the
+- * device is embedded in the value field of the setup packet.
++ * device is embedded in the value field of the setup packet. serial_portnum is
++ * ignored for registers that are not specific to a particular serial port.
+ */
+-static int read_parport_reg(struct mos7715_parport *mos_parport,
+- enum mos_regs reg, __u8 *data)
++static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum,
++ enum mos_regs reg, __u8 *data)
+ {
+- struct usb_device *usbdev = mos_parport->serial->dev;
++ struct usb_device *usbdev = serial->dev;
+ unsigned int pipe = usb_rcvctrlpipe(usbdev, 0);
+ __u8 request = (__u8)0x0d;
+ __u8 requesttype = (__u8)0xc0;
+- __u16 value = get_reg_value(reg);
+ __u16 index = get_reg_index(reg);
+- __u16 size = 1;
++ __u16 value = get_reg_value(reg, serial_portnum);
+ int status = usb_control_msg(usbdev, pipe, request, requesttype, value,
+- index, data, size, MOS_WDR_TIMEOUT);
++ index, data, 1, MOS_WDR_TIMEOUT);
+ if (status < 0)
+ dev_err(&usbdev->dev,
+ "mos7720: usb_control_msg() failed: %d", status);
+ return status;
+ }
+
++#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
++
+ static inline int mos7715_change_mode(struct mos7715_parport *mos_parport,
+ enum mos7715_pp_modes mode)
+ {
+ mos_parport->shadowECR = mode;
+- write_parport_reg(mos_parport, ECR, mos_parport->shadowECR);
++ write_mos_reg(mos_parport->serial, dummy, ECR, mos_parport->shadowECR);
+ return 0;
+ }
+
+@@ -367,7 +373,7 @@ static int write_parport_reg_nonblock(st
+ }
+ setup.bRequestType = (__u8)0x40;
+ setup.bRequest = (__u8)0x0e;
+- setup.wValue = get_reg_value(reg);
++ setup.wValue = get_reg_value(reg, dummy);
+ setup.wIndex = get_reg_index(reg);
+ setup.wLength = 0;
+ usb_fill_control_urb(urbtrack->urb, usbdev,
+@@ -474,7 +480,7 @@ static void parport_mos7715_write_data(s
+ if (parport_prologue(pp) < 0)
+ return;
+ mos7715_change_mode(mos_parport, SPP);
+- write_parport_reg(mos_parport, DPR, (__u8)d);
++ write_mos_reg(mos_parport->serial, dummy, DPR, (__u8)d);
+ parport_epilogue(pp);
+ }
+
+@@ -485,7 +491,7 @@ static unsigned char parport_mos7715_rea
+ dbg("%s called", __func__);
+ if (parport_prologue(pp) < 0)
+ return 0;
+- read_parport_reg(mos_parport, DPR, &d);
++ read_mos_reg(mos_parport->serial, dummy, DPR, &d);
+ parport_epilogue(pp);
+ return d;
+ }
+@@ -498,7 +504,7 @@ static void parport_mos7715_write_contro
+ if (parport_prologue(pp) < 0)
+ return;
+ data = ((__u8)d & 0x0f) | (mos_parport->shadowDCR & 0xf0);
+- write_parport_reg(mos_parport, DCR, data);
++ write_mos_reg(mos_parport->serial, dummy, DCR, data);
+ mos_parport->shadowDCR = data;
+ parport_epilogue(pp);
+ }
+@@ -531,7 +537,7 @@ static unsigned char parport_mos7715_fro
+ if (parport_prologue(pp) < 0)
+ return 0;
+ mos_parport->shadowDCR = (mos_parport->shadowDCR & (~mask)) ^ val;
+- write_parport_reg(mos_parport, DCR, mos_parport->shadowDCR);
++ write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR);
+ dcr = mos_parport->shadowDCR & 0x0f;
+ parport_epilogue(pp);
+ return dcr;
+@@ -570,7 +576,7 @@ static void parport_mos7715_data_forward
+ return;
+ mos7715_change_mode(mos_parport, PS2);
+ mos_parport->shadowDCR &= ~0x20;
+- write_parport_reg(mos_parport, DCR, mos_parport->shadowDCR);
++ write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR);
+ parport_epilogue(pp);
+ }
+
+@@ -582,7 +588,7 @@ static void parport_mos7715_data_reverse
+ return;
+ mos7715_change_mode(mos_parport, PS2);
+ mos_parport->shadowDCR |= 0x20;
+- write_parport_reg(mos_parport, DCR, mos_parport->shadowDCR);
++ write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR);
+ parport_epilogue(pp);
+ }
+
+@@ -705,14 +711,14 @@ static int mos7715_parport_init(struct u
+ init_completion(&mos_parport->syncmsg_compl);
+
+ /* cycle parallel port reset bit */
+- write_parport_reg(mos_parport, PP_REG, (__u8)0x80);
+- write_parport_reg(mos_parport, PP_REG, (__u8)0x00);
++ write_mos_reg(mos_parport->serial, dummy, PP_REG, (__u8)0x80);
++ write_mos_reg(mos_parport->serial, dummy, PP_REG, (__u8)0x00);
+
+ /* initialize device registers */
+ mos_parport->shadowDCR = DCR_INIT_VAL;
+- write_parport_reg(mos_parport, DCR, mos_parport->shadowDCR);
++ write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR);
+ mos_parport->shadowECR = ECR_INIT_VAL;
+- write_parport_reg(mos_parport, ECR, mos_parport->shadowECR);
++ write_mos_reg(mos_parport->serial, dummy, ECR, mos_parport->shadowECR);
+
+ /* register with parport core */
+ mos_parport->pp = parport_register_port(0, PARPORT_IRQ_NONE,
+@@ -754,7 +760,6 @@ static void mos7720_interrupt_callback(s
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+- case -ENODEV:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d", __func__,
+ status);
+@@ -981,56 +986,6 @@ static void mos7720_bulk_out_data_callba
+ }
+
+ /*
+- * send_mos_cmd
+- * this function will be used for sending command to device
+- */
+-static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value,
+- __u16 index, u8 *data)
+-{
+- int status;
+- u8 *buf;
+- u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
+-
+- if (value < MOS_MAX_PORT) {
+- if (product == MOSCHIP_DEVICE_ID_7715)
+- value = 0x0200; /* identifies the 7715's serial port */
+- else
+- value = value*0x100+0x200;
+- } else {
+- value = 0x0000;
+- if ((product == MOSCHIP_DEVICE_ID_7715) &&
+- (index != 0x08)) {
+- dbg("serial->product== MOSCHIP_DEVICE_ID_7715");
+- /* index = 0x01 ; */
+- }
+- }
+-
+- if (request == MOS_WRITE) {
+- value = value + *data;
+- status = usb_control_msg(serial->dev,
+- usb_sndctrlpipe(serial->dev, 0), MOS_WRITE,
+- 0x40, value, index, NULL, 0, MOS_WDR_TIMEOUT);
+- } else {
+- buf = kmalloc(1, GFP_KERNEL);
+- if (!buf) {
+- status = -ENOMEM;
+- goto out;
+- }
+- status = usb_control_msg(serial->dev,
+- usb_rcvctrlpipe(serial->dev, 0), MOS_READ,
+- 0xc0, value, index, buf, 1, MOS_WDR_TIMEOUT);
+- *data = *buf;
+- kfree(buf);
+- }
+-out:
+- if (status < 0)
+- dbg("Command Write failed Value %x index %x", value, index);
+-
+- return status;
+-}
+-
+-
+-/*
+ * mos77xx_probe
+ * this function installs the appropriate read interrupt endpoint callback
+ * depending on whether the device is a 7720 or 7715, thus avoiding costly
+@@ -1066,7 +1021,7 @@ static int mos7720_open(struct tty_struc
+ struct moschip_port *mos7720_port;
+ int response;
+ int port_number;
+- char data;
++ __u8 data;
+ int allocated_urbs = 0;
+ int j;
+
+@@ -1122,65 +1077,35 @@ static int mos7720_open(struct tty_struc
+ * 0x08 : SP1/2 Control Reg
+ */
+ port_number = port->number - port->serial->minor;
+- send_mos_cmd(port->serial, MOS_READ, port_number, UART_LSR, &data);
++ read_mos_reg(serial, port_number, LSR, &data);
++
+ dbg("SS::%p LSR:%x", mos7720_port, data);
+
+ dbg("Check:Sending Command ..........");
+
+- data = 0x02;
+- send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x01, &data);
+- data = 0x02;
+- send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x02, &data);
+-
+- data = 0x00;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
+- data = 0x00;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data);
+-
+- data = 0xCF;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data);
+- data = 0x03;
+- mos7720_port->shadowLCR = data;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
+- data = 0x0b;
+- mos7720_port->shadowMCR = data;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+- data = 0x0b;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+-
+- data = 0x00;
+- send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
+- data = 0x00;
+- send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
+-
+-/* data = 0x00;
+- send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, port_number + 1, &data);
+- data = 0x03;
+- send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data);
+- data = 0x00;
+- send_mos_cmd(port->serial, MOS_WRITE, MOS_MAX_PORT,
+- port_number + 1, &data);
+-*/
+- data = 0x00;
+- send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
++ write_mos_reg(serial, dummy, SP1_REG, 0x02);
++ write_mos_reg(serial, dummy, SP2_REG, 0x02);
+
+- data = data | (port->number - port->serial->minor + 1);
+- send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
++ write_mos_reg(serial, port_number, IER, 0x00);
++ write_mos_reg(serial, port_number, FCR, 0x00);
+
+- data = 0x83;
+- mos7720_port->shadowLCR = data;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
+- data = 0x0c;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data);
+- data = 0x00;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
+- data = 0x03;
+- mos7720_port->shadowLCR = data;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
+- data = 0x0c;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
+- data = 0x0c;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
++ write_mos_reg(serial, port_number, FCR, 0xcf);
++ mos7720_port->shadowLCR = 0x03;
++ write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR);
++ mos7720_port->shadowMCR = 0x0b;
++ write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR);
++
++ write_mos_reg(serial, port_number, SP_CONTROL_REG, 0x00);
++ read_mos_reg(serial, dummy, SP_CONTROL_REG, &data);
++ data = data | (port->number - port->serial->minor + 1);
++ write_mos_reg(serial, dummy, SP_CONTROL_REG, data);
++ mos7720_port->shadowLCR = 0x83;
++ write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR);
++ write_mos_reg(serial, port_number, THR, 0x0c);
++ write_mos_reg(serial, port_number, IER, 0x00);
++ mos7720_port->shadowLCR = 0x03;
++ write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR);
++ write_mos_reg(serial, port_number, IER, 0x0c);
+
+ response = usb_submit_urb(port->read_urb, GFP_KERNEL);
+ if (response)
+@@ -1236,7 +1161,6 @@ static void mos7720_close(struct usb_ser
+ {
+ struct usb_serial *serial;
+ struct moschip_port *mos7720_port;
+- char data;
+ int j;
+
+ dbg("mos7720_close:entering...");
+@@ -1269,13 +1193,10 @@ static void mos7720_close(struct usb_ser
+ /* these commands must not be issued if the device has
+ * been disconnected */
+ if (!serial->disconnected) {
+- data = 0x00;
+- send_mos_cmd(serial, MOS_WRITE,
+- port->number - port->serial->minor, 0x04, &data);
+-
+- data = 0x00;
+- send_mos_cmd(serial, MOS_WRITE,
+- port->number - port->serial->minor, 0x01, &data);
++ write_mos_reg(serial, port->number - port->serial->minor,
++ MCR, 0x00);
++ write_mos_reg(serial, port->number - port->serial->minor,
++ IER, 0x00);
+ }
+ mutex_unlock(&serial->disc_mutex);
+ mos7720_port->open = 0;
+@@ -1304,8 +1225,8 @@ static void mos7720_break(struct tty_str
+ data = mos7720_port->shadowLCR & ~UART_LCR_SBC;
+
+ mos7720_port->shadowLCR = data;
+- send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
+- 0x03, &data);
++ write_mos_reg(serial, port->number - port->serial->minor,
++ LCR, mos7720_port->shadowLCR);
+
+ return;
+ }
+@@ -1450,9 +1371,8 @@ static void mos7720_throttle(struct tty_
+ /* if we are implementing RTS/CTS, toggle that line */
+ if (tty->termios->c_cflag & CRTSCTS) {
+ mos7720_port->shadowMCR &= ~UART_MCR_RTS;
+- status = send_mos_cmd(port->serial, MOS_WRITE,
+- port->number - port->serial->minor,
+- UART_MCR, &mos7720_port->shadowMCR);
++ write_mos_reg(port->serial, port->number - port->serial->minor,
++ MCR, mos7720_port->shadowMCR);
+ if (status != 0)
+ return;
+ }
+@@ -1485,9 +1405,8 @@ static void mos7720_unthrottle(struct tt
+ /* if we are implementing RTS/CTS, toggle that line */
+ if (tty->termios->c_cflag & CRTSCTS) {
+ mos7720_port->shadowMCR |= UART_MCR_RTS;
+- status = send_mos_cmd(port->serial, MOS_WRITE,
+- port->number - port->serial->minor,
+- UART_MCR, &mos7720_port->shadowMCR);
++ write_mos_reg(port->serial, port->number - port->serial->minor,
++ MCR, mos7720_port->shadowMCR);
+ if (status != 0)
+ return;
+ }
+@@ -1497,11 +1416,10 @@ static void mos7720_unthrottle(struct tt
+ static int set_higher_rates(struct moschip_port *mos7720_port,
+ unsigned int baud)
+ {
+- unsigned char data;
+ struct usb_serial_port *port;
+ struct usb_serial *serial;
+ int port_number;
+-
++ enum mos_regs sp_reg;
+ if (mos7720_port == NULL)
+ return -EINVAL;
+
+@@ -1514,59 +1432,35 @@ static int set_higher_rates(struct mosch
+ dbg("Sending Setting Commands ..........");
+ port_number = port->number - port->serial->minor;
+
+- data = 0x000;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
+- data = 0x000;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data);
+- data = 0x0CF;
+- send_mos_cmd(serial, MOS_WRITE, port->number, 0x02, &data);
+- data = 0x00b;
+- mos7720_port->shadowMCR = data;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+- data = 0x00b;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+-
+- data = 0x000;
+- send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
+- data = 0x000;
+- send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
+-
++ write_mos_reg(serial, port_number, IER, 0x00);
++ write_mos_reg(serial, port_number, FCR, 0x00);
++ write_mos_reg(serial, port_number, FCR, 0xcf);
++ mos7720_port->shadowMCR = 0x0b;
++ write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR);
++ write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x00);
+
+ /***********************************************
+ * Set for higher rates *
+ ***********************************************/
+-
+ /* writing baud rate verbatum into uart clock field clearly not right */
+- data = baud * 0x10;
+- send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data);
+-
+- data = 0x003;
+- send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
+- data = 0x003;
+- send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
+-
+- data = 0x02b;
+- mos7720_port->shadowMCR = data;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+- data = 0x02b;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
++ if (port_number == 0)
++ sp_reg = SP1_REG;
++ else
++ sp_reg = SP2_REG;
++ write_mos_reg(serial, dummy, sp_reg, baud * 0x10);
++ write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x03);
++ mos7720_port->shadowMCR = 0x2b;
++ write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR);
+
+ /***********************************************
+ * Set DLL/DLM
+ ***********************************************/
+-
+- data = mos7720_port->shadowLCR | UART_LCR_DLAB;
+- mos7720_port->shadowLCR = data;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
+-
+- data = 0x001; /* DLL */
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data);
+- data = 0x000; /* DLM */
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
+-
+- data = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
+- mos7720_port->shadowLCR = data;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
++ mos7720_port->shadowLCR = mos7720_port->shadowLCR | UART_LCR_DLAB;
++ write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR);
++ write_mos_reg(serial, port_number, DLL, 0x01);
++ write_mos_reg(serial, port_number, DLM, 0x00);
++ mos7720_port->shadowLCR = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
++ write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR);
+
+ return 0;
+ }
+@@ -1654,7 +1548,6 @@ static int send_cmd_write_baud_rate(stru
+ struct usb_serial *serial;
+ int divisor;
+ int status;
+- unsigned char data;
+ unsigned char number;
+
+ if (mos7720_port == NULL)
+@@ -1676,21 +1569,16 @@ static int send_cmd_write_baud_rate(stru
+ }
+
+ /* Enable access to divisor latch */
+- data = mos7720_port->shadowLCR | UART_LCR_DLAB;
+- mos7720_port->shadowLCR = data;
+- send_mos_cmd(serial, MOS_WRITE, number, UART_LCR, &data);
++ mos7720_port->shadowLCR = mos7720_port->shadowLCR | UART_LCR_DLAB;
++ write_mos_reg(serial, number, LCR, mos7720_port->shadowLCR);
+
+ /* Write the divisor */
+- data = ((unsigned char)(divisor & 0xff));
+- send_mos_cmd(serial, MOS_WRITE, number, 0x00, &data);
+-
+- data = ((unsigned char)((divisor & 0xff00) >> 8));
+- send_mos_cmd(serial, MOS_WRITE, number, 0x01, &data);
++ write_mos_reg(serial, number, DLL, (__u8)(divisor & 0xff));
++ write_mos_reg(serial, number, DLM, (__u8)((divisor & 0xff00) >> 8));
+
+ /* Disable access to divisor latch */
+- data = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
+- mos7720_port->shadowLCR = data;
+- send_mos_cmd(serial, MOS_WRITE, number, 0x03, &data);
++ mos7720_port->shadowLCR = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
++ write_mos_reg(serial, number, LCR, mos7720_port->shadowLCR);
+
+ return status;
+ }
+@@ -1715,7 +1603,6 @@ static void change_port_settings(struct
+ __u8 lStop;
+ int status;
+ int port_number;
+- char data;
+
+ if (mos7720_port == NULL)
+ return ;
+@@ -1794,30 +1681,19 @@ static void change_port_settings(struct
+
+ /* Update the LCR with the correct value */
+ mos7720_port->shadowLCR &=
+- ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
++ ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
+ mos7720_port->shadowLCR |= (lData | lParity | lStop);
+
+
+ /* Disable Interrupts */
+- data = 0x00;
+- send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
+- UART_IER, &data);
+-
+- data = 0x00;
+- send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data);
+-
+- data = 0xcf;
+- send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data);
++ write_mos_reg(serial, port_number, IER, 0x00);
++ write_mos_reg(serial, port_number, FCR, 0x00);
++ write_mos_reg(serial, port_number, FCR, 0xcf);
+
+ /* Send the updated LCR value to the mos7720 */
+- data = mos7720_port->shadowLCR;
+- send_mos_cmd(serial, MOS_WRITE, port_number, UART_LCR, &data);
+-
+- data = 0x00b;
+- mos7720_port->shadowMCR = data;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+- data = 0x00b;
+- send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
++ write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR);
++ mos7720_port->shadowMCR = 0x0b;
++ write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR);
+
+ /* set up the MCR register and send it to the mos7720 */
+ mos7720_port->shadowMCR = UART_MCR_OUT2;
+@@ -1828,21 +1704,15 @@ static void change_port_settings(struct
+ mos7720_port->shadowMCR |= (UART_MCR_XONANY);
+ /* To set hardware flow control to the specified *
+ * serial port, in SP1/2_CONTROL_REG */
+- if (port->number) {
+- data = 0x001;
+- send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT,
+- 0x08, &data);
+- } else {
+- data = 0x002;
+- send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT,
+- 0x08, &data);
+- }
+- } else {
++ if (port->number)
++ write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01);
++ else
++ write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02);
++
++ } else
+ mos7720_port->shadowMCR &= ~(UART_MCR_XONANY);
+- }
+
+- data = mos7720_port->shadowMCR;
+- send_mos_cmd(serial, MOS_WRITE, port_number, UART_MCR, &data);
++ write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR);
+
+ /* Determine divisor based on baud rate */
+ baud = tty_get_baud_rate(tty);
+@@ -1855,8 +1725,7 @@ static void change_port_settings(struct
+ if (baud >= 230400) {
+ set_higher_rates(mos7720_port, baud);
+ /* Enable Interrupts */
+- data = 0x0c;
+- send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data);
++ write_mos_reg(serial, port_number, IER, 0x0c);
+ return;
+ }
+
+@@ -1867,8 +1736,7 @@ static void change_port_settings(struct
+ if (cflag & CBAUD)
+ tty_encode_baud_rate(tty, baud, baud);
+ /* Enable Interrupts */
+- data = 0x0c;
+- send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data);
++ write_mos_reg(serial, port_number, IER, 0x0c);
+
+ if (port->read_urb->status != -EINPROGRESS) {
+ port->read_urb->dev = serial->dev;
+@@ -1959,8 +1827,7 @@ static int get_lsr_info(struct tty_struc
+
+ count = mos7720_chars_in_buffer(tty);
+ if (count == 0) {
+- send_mos_cmd(port->serial, MOS_READ, port_number,
+- UART_LSR, &data);
++ read_mos_reg(port->serial, port_number, LSR, &data);
+ if ((data & (UART_LSR_TEMT | UART_LSR_THRE))
+ == (UART_LSR_TEMT | UART_LSR_THRE)) {
+ dbg("%s -- Empty", __func__);
+@@ -1998,13 +1865,11 @@ static int mos7720_tiocmget(struct tty_s
+ }
+
+ static int mos7720_tiocmset(struct tty_struct *tty, struct file *file,
+- unsigned int set, unsigned int clear)
++ unsigned int set, unsigned int clear)
+ {
+ struct usb_serial_port *port = tty->driver_data;
+ struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
+ unsigned int mcr ;
+- unsigned char lmcr;
+-
+ dbg("%s - port %d", __func__, port->number);
+ dbg("he was at tiocmget");
+
+@@ -2025,10 +1890,8 @@ static int mos7720_tiocmset(struct tty_s
+ mcr &= ~UART_MCR_LOOP;
+
+ mos7720_port->shadowMCR = mcr;
+- lmcr = mos7720_port->shadowMCR;
+-
+- send_mos_cmd(port->serial, MOS_WRITE,
+- port->number - port->serial->minor, UART_MCR, &lmcr);
++ write_mos_reg(port->serial, port->number - port->serial->minor,
++ MCR, mos7720_port->shadowMCR);
+
+ return 0;
+ }
+@@ -2038,7 +1901,6 @@ static int set_modem_info(struct moschip
+ {
+ unsigned int mcr ;
+ unsigned int arg;
+- unsigned char data;
+
+ struct usb_serial_port *port;
+
+@@ -2073,10 +1935,8 @@ static int set_modem_info(struct moschip
+ }
+
+ mos7720_port->shadowMCR = mcr;
+-
+- data = mos7720_port->shadowMCR;
+- send_mos_cmd(port->serial, MOS_WRITE,
+- port->number - port->serial->minor, UART_MCR, &data);
++ write_mos_reg(port->serial, port->number - port->serial->minor,
++ MCR, mos7720_port->shadowMCR);
+
+ return 0;
+ }
+@@ -2269,11 +2129,7 @@ static int mos7720_startup(struct usb_se
+ }
+ #endif
+ /* LSR For Port 1 */
+- send_mos_cmd(serial, MOS_READ, 0x00, UART_LSR, &data);
+- dbg("LSR:%x", data);
+-
+- /* LSR For Port 2 */
+- send_mos_cmd(serial, MOS_READ, 0x01, UART_LSR, &data);
++ read_mos_reg(serial, 0, LSR, &data);
+ dbg("LSR:%x", data);
+
+ return 0;
diff --git a/usb/usb-use-pm-core-routines-to-enable-disable-autosuspend.patch b/usb/usb-use-pm-core-routines-to-enable-disable-autosuspend.patch
index 13593136a77ce6..d0647faccabade 100644
--- a/usb/usb-use-pm-core-routines-to-enable-disable-autosuspend.patch
+++ b/usb/usb-use-pm-core-routines-to-enable-disable-autosuspend.patch
@@ -22,7 +22,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
-@@ -1355,13 +1355,9 @@ int usb_resume(struct device *dev, pm_me
+@@ -1356,13 +1356,9 @@ int usb_resume(struct device *dev, pm_me
*
* The caller must hold @udev's device lock.
*/
@@ -38,7 +38,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
}
EXPORT_SYMBOL_GPL(usb_enable_autosuspend);
-@@ -1374,16 +1370,9 @@ EXPORT_SYMBOL_GPL(usb_enable_autosuspend
+@@ -1375,16 +1371,9 @@ EXPORT_SYMBOL_GPL(usb_enable_autosuspend
*
* The caller must hold @udev's device lock.
*/
@@ -57,7 +57,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
}
EXPORT_SYMBOL_GPL(usb_disable_autosuspend);
-@@ -1527,7 +1516,7 @@ void usb_autopm_put_interface_async(stru
+@@ -1528,7 +1517,7 @@ void usb_autopm_put_interface_async(stru
atomic_dec(&intf->pm_usage_cnt);
pm_runtime_put_noidle(&intf->dev);