diff options
-rw-r--r-- | drivers/usb/core/hcd.c | 44 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 70 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 9 | ||||
-rw-r--r-- | drivers/usb/host/ehci-q.c | 50 | ||||
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 9 | ||||
-rw-r--r-- | drivers/usb/host/ehci-timer.c | 29 | ||||
-rw-r--r-- | drivers/usb/host/pci-quirks.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/uhci-hub.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 13 | ||||
-rw-r--r-- | drivers/usb/serial/cp210x.c | 1 | ||||
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/ftdi_sio_ids.h | 9 | ||||
-rw-r--r-- | drivers/usb/serial/option.c | 13 | ||||
-rw-r--r-- | drivers/usb/serial/qcserial.c | 1 | ||||
-rw-r--r-- | drivers/usb/storage/initializers.c | 76 | ||||
-rw-r--r-- | drivers/usb/storage/initializers.h | 4 | ||||
-rw-r--r-- | drivers/usb/storage/unusual_devs.h | 329 | ||||
-rw-r--r-- | drivers/usb/storage/usb.c | 12 | ||||
-rw-r--r-- | drivers/usb/storage/usual-tables.c | 15 | ||||
-rw-r--r-- | include/linux/usb.h | 2 | ||||
-rw-r--r-- | include/linux/usb/hcd.h | 3 | ||||
-rw-r--r-- | include/uapi/linux/usb/ch9.h | 6 |
23 files changed, 310 insertions, 392 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 2459896d040a..99b34a30354f 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <asm/unaligned.h> | 39 | #include <asm/unaligned.h> |
40 | #include <linux/platform_device.h> | 40 | #include <linux/platform_device.h> |
41 | #include <linux/workqueue.h> | 41 | #include <linux/workqueue.h> |
42 | #include <linux/pm_runtime.h> | ||
42 | 43 | ||
43 | #include <linux/usb.h> | 44 | #include <linux/usb.h> |
44 | #include <linux/usb/hcd.h> | 45 | #include <linux/usb/hcd.h> |
@@ -1029,6 +1030,49 @@ static int register_root_hub(struct usb_hcd *hcd) | |||
1029 | return retval; | 1030 | return retval; |
1030 | } | 1031 | } |
1031 | 1032 | ||
1033 | /* | ||
1034 | * usb_hcd_start_port_resume - a root-hub port is sending a resume signal | ||
1035 | * @bus: the bus which the root hub belongs to | ||
1036 | * @portnum: the port which is being resumed | ||
1037 | * | ||
1038 | * HCDs should call this function when they know that a resume signal is | ||
1039 | * being sent to a root-hub port. The root hub will be prevented from | ||
1040 | * going into autosuspend until usb_hcd_end_port_resume() is called. | ||
1041 | * | ||
1042 | * The bus's private lock must be held by the caller. | ||
1043 | */ | ||
1044 | void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum) | ||
1045 | { | ||
1046 | unsigned bit = 1 << portnum; | ||
1047 | |||
1048 | if (!(bus->resuming_ports & bit)) { | ||
1049 | bus->resuming_ports |= bit; | ||
1050 | pm_runtime_get_noresume(&bus->root_hub->dev); | ||
1051 | } | ||
1052 | } | ||
1053 | EXPORT_SYMBOL_GPL(usb_hcd_start_port_resume); | ||
1054 | |||
1055 | /* | ||
1056 | * usb_hcd_end_port_resume - a root-hub port has stopped sending a resume signal | ||
1057 | * @bus: the bus which the root hub belongs to | ||
1058 | * @portnum: the port which is being resumed | ||
1059 | * | ||
1060 | * HCDs should call this function when they know that a resume signal has | ||
1061 | * stopped being sent to a root-hub port. The root hub will be allowed to | ||
1062 | * autosuspend again. | ||
1063 | * | ||
1064 | * The bus's private lock must be held by the caller. | ||
1065 | */ | ||
1066 | void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum) | ||
1067 | { | ||
1068 | unsigned bit = 1 << portnum; | ||
1069 | |||
1070 | if (bus->resuming_ports & bit) { | ||
1071 | bus->resuming_ports &= ~bit; | ||
1072 | pm_runtime_put_noidle(&bus->root_hub->dev); | ||
1073 | } | ||
1074 | } | ||
1075 | EXPORT_SYMBOL_GPL(usb_hcd_end_port_resume); | ||
1032 | 1076 | ||
1033 | /*-------------------------------------------------------------------------*/ | 1077 | /*-------------------------------------------------------------------------*/ |
1034 | 1078 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0883364e7347..1775ad471edd 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -2822,6 +2822,23 @@ void usb_enable_ltm(struct usb_device *udev) | |||
2822 | EXPORT_SYMBOL_GPL(usb_enable_ltm); | 2822 | EXPORT_SYMBOL_GPL(usb_enable_ltm); |
2823 | 2823 | ||
2824 | #ifdef CONFIG_USB_SUSPEND | 2824 | #ifdef CONFIG_USB_SUSPEND |
2825 | /* | ||
2826 | * usb_disable_function_remotewakeup - disable usb3.0 | ||
2827 | * device's function remote wakeup | ||
2828 | * @udev: target device | ||
2829 | * | ||
2830 | * Assume there's only one function on the USB 3.0 | ||
2831 | * device and disable remote wake for the first | ||
2832 | * interface. FIXME if the interface association | ||
2833 | * descriptor shows there's more than one function. | ||
2834 | */ | ||
2835 | static int usb_disable_function_remotewakeup(struct usb_device *udev) | ||
2836 | { | ||
2837 | return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
2838 | USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE, | ||
2839 | USB_INTRF_FUNC_SUSPEND, 0, NULL, 0, | ||
2840 | USB_CTRL_SET_TIMEOUT); | ||
2841 | } | ||
2825 | 2842 | ||
2826 | /* | 2843 | /* |
2827 | * usb_port_suspend - suspend a usb device's upstream port | 2844 | * usb_port_suspend - suspend a usb device's upstream port |
@@ -2939,12 +2956,19 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
2939 | dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n", | 2956 | dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n", |
2940 | port1, status); | 2957 | port1, status); |
2941 | /* paranoia: "should not happen" */ | 2958 | /* paranoia: "should not happen" */ |
2942 | if (udev->do_remote_wakeup) | 2959 | if (udev->do_remote_wakeup) { |
2943 | (void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 2960 | if (!hub_is_superspeed(hub->hdev)) { |
2944 | USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, | 2961 | (void) usb_control_msg(udev, |
2945 | USB_DEVICE_REMOTE_WAKEUP, 0, | 2962 | usb_sndctrlpipe(udev, 0), |
2946 | NULL, 0, | 2963 | USB_REQ_CLEAR_FEATURE, |
2947 | USB_CTRL_SET_TIMEOUT); | 2964 | USB_RECIP_DEVICE, |
2965 | USB_DEVICE_REMOTE_WAKEUP, 0, | ||
2966 | NULL, 0, | ||
2967 | USB_CTRL_SET_TIMEOUT); | ||
2968 | } else | ||
2969 | (void) usb_disable_function_remotewakeup(udev); | ||
2970 | |||
2971 | } | ||
2948 | 2972 | ||
2949 | /* Try to enable USB2 hardware LPM again */ | 2973 | /* Try to enable USB2 hardware LPM again */ |
2950 | if (udev->usb2_hw_lpm_capable == 1) | 2974 | if (udev->usb2_hw_lpm_capable == 1) |
@@ -3051,20 +3075,30 @@ static int finish_port_resume(struct usb_device *udev) | |||
3051 | * udev->reset_resume | 3075 | * udev->reset_resume |
3052 | */ | 3076 | */ |
3053 | } else if (udev->actconfig && !udev->reset_resume) { | 3077 | } else if (udev->actconfig && !udev->reset_resume) { |
3054 | le16_to_cpus(&devstatus); | 3078 | if (!hub_is_superspeed(udev->parent)) { |
3055 | if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { | 3079 | le16_to_cpus(&devstatus); |
3056 | status = usb_control_msg(udev, | 3080 | if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) |
3057 | usb_sndctrlpipe(udev, 0), | 3081 | status = usb_control_msg(udev, |
3058 | USB_REQ_CLEAR_FEATURE, | 3082 | usb_sndctrlpipe(udev, 0), |
3083 | USB_REQ_CLEAR_FEATURE, | ||
3059 | USB_RECIP_DEVICE, | 3084 | USB_RECIP_DEVICE, |
3060 | USB_DEVICE_REMOTE_WAKEUP, 0, | 3085 | USB_DEVICE_REMOTE_WAKEUP, 0, |
3061 | NULL, 0, | 3086 | NULL, 0, |
3062 | USB_CTRL_SET_TIMEOUT); | 3087 | USB_CTRL_SET_TIMEOUT); |
3063 | if (status) | 3088 | } else { |
3064 | dev_dbg(&udev->dev, | 3089 | status = usb_get_status(udev, USB_RECIP_INTERFACE, 0, |
3065 | "disable remote wakeup, status %d\n", | 3090 | &devstatus); |
3066 | status); | 3091 | le16_to_cpus(&devstatus); |
3092 | if (!status && devstatus & (USB_INTRF_STAT_FUNC_RW_CAP | ||
3093 | | USB_INTRF_STAT_FUNC_RW)) | ||
3094 | status = | ||
3095 | usb_disable_function_remotewakeup(udev); | ||
3067 | } | 3096 | } |
3097 | |||
3098 | if (status) | ||
3099 | dev_dbg(&udev->dev, | ||
3100 | "disable remote wakeup, status %d\n", | ||
3101 | status); | ||
3068 | status = 0; | 3102 | status = 0; |
3069 | } | 3103 | } |
3070 | return status; | 3104 | return status; |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 09537b2f1002..b416a3fc9959 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -797,6 +797,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
797 | ehci->reset_done[i] = jiffies + msecs_to_jiffies(25); | 797 | ehci->reset_done[i] = jiffies + msecs_to_jiffies(25); |
798 | set_bit(i, &ehci->resuming_ports); | 798 | set_bit(i, &ehci->resuming_ports); |
799 | ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); | 799 | ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); |
800 | usb_hcd_start_port_resume(&hcd->self, i); | ||
800 | mod_timer(&hcd->rh_timer, ehci->reset_done[i]); | 801 | mod_timer(&hcd->rh_timer, ehci->reset_done[i]); |
801 | } | 802 | } |
802 | } | 803 | } |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 4ccb97c0678f..4d3b294f203e 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -649,7 +649,11 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
649 | status = STS_PCD; | 649 | status = STS_PCD; |
650 | } | 650 | } |
651 | } | 651 | } |
652 | /* FIXME autosuspend idle root hubs */ | 652 | |
653 | /* If a resume is in progress, make sure it can finish */ | ||
654 | if (ehci->resuming_ports) | ||
655 | mod_timer(&hcd->rh_timer, jiffies + msecs_to_jiffies(25)); | ||
656 | |||
653 | spin_unlock_irqrestore (&ehci->lock, flags); | 657 | spin_unlock_irqrestore (&ehci->lock, flags); |
654 | return status ? retval : 0; | 658 | return status ? retval : 0; |
655 | } | 659 | } |
@@ -851,6 +855,7 @@ static int ehci_hub_control ( | |||
851 | /* resume signaling for 20 msec */ | 855 | /* resume signaling for 20 msec */ |
852 | ehci->reset_done[wIndex] = jiffies | 856 | ehci->reset_done[wIndex] = jiffies |
853 | + msecs_to_jiffies(20); | 857 | + msecs_to_jiffies(20); |
858 | usb_hcd_start_port_resume(&hcd->self, wIndex); | ||
854 | /* check the port again */ | 859 | /* check the port again */ |
855 | mod_timer(&ehci_to_hcd(ehci)->rh_timer, | 860 | mod_timer(&ehci_to_hcd(ehci)->rh_timer, |
856 | ehci->reset_done[wIndex]); | 861 | ehci->reset_done[wIndex]); |
@@ -862,6 +867,7 @@ static int ehci_hub_control ( | |||
862 | clear_bit(wIndex, &ehci->suspended_ports); | 867 | clear_bit(wIndex, &ehci->suspended_ports); |
863 | set_bit(wIndex, &ehci->port_c_suspend); | 868 | set_bit(wIndex, &ehci->port_c_suspend); |
864 | ehci->reset_done[wIndex] = 0; | 869 | ehci->reset_done[wIndex] = 0; |
870 | usb_hcd_end_port_resume(&hcd->self, wIndex); | ||
865 | 871 | ||
866 | /* stop resume signaling */ | 872 | /* stop resume signaling */ |
867 | temp = ehci_readl(ehci, status_reg); | 873 | temp = ehci_readl(ehci, status_reg); |
@@ -950,6 +956,7 @@ static int ehci_hub_control ( | |||
950 | ehci->reset_done[wIndex] = 0; | 956 | ehci->reset_done[wIndex] = 0; |
951 | if (temp & PORT_PE) | 957 | if (temp & PORT_PE) |
952 | set_bit(wIndex, &ehci->port_c_suspend); | 958 | set_bit(wIndex, &ehci->port_c_suspend); |
959 | usb_hcd_end_port_resume(&hcd->self, wIndex); | ||
953 | } | 960 | } |
954 | 961 | ||
955 | if (temp & PORT_OC) | 962 | if (temp & PORT_OC) |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 3d989028c836..fd252f0cfb3a 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -1197,17 +1197,26 @@ static void start_iaa_cycle(struct ehci_hcd *ehci, bool nested) | |||
1197 | if (ehci->async_iaa || ehci->async_unlinking) | 1197 | if (ehci->async_iaa || ehci->async_unlinking) |
1198 | return; | 1198 | return; |
1199 | 1199 | ||
1200 | /* Do all the waiting QHs at once */ | ||
1201 | ehci->async_iaa = ehci->async_unlink; | ||
1202 | ehci->async_unlink = NULL; | ||
1203 | |||
1204 | /* If the controller isn't running, we don't have to wait for it */ | 1200 | /* If the controller isn't running, we don't have to wait for it */ |
1205 | if (unlikely(ehci->rh_state < EHCI_RH_RUNNING)) { | 1201 | if (unlikely(ehci->rh_state < EHCI_RH_RUNNING)) { |
1202 | |||
1203 | /* Do all the waiting QHs */ | ||
1204 | ehci->async_iaa = ehci->async_unlink; | ||
1205 | ehci->async_unlink = NULL; | ||
1206 | |||
1206 | if (!nested) /* Avoid recursion */ | 1207 | if (!nested) /* Avoid recursion */ |
1207 | end_unlink_async(ehci); | 1208 | end_unlink_async(ehci); |
1208 | 1209 | ||
1209 | /* Otherwise start a new IAA cycle */ | 1210 | /* Otherwise start a new IAA cycle */ |
1210 | } else if (likely(ehci->rh_state == EHCI_RH_RUNNING)) { | 1211 | } else if (likely(ehci->rh_state == EHCI_RH_RUNNING)) { |
1212 | struct ehci_qh *qh; | ||
1213 | |||
1214 | /* Do only the first waiting QH (nVidia bug?) */ | ||
1215 | qh = ehci->async_unlink; | ||
1216 | ehci->async_iaa = qh; | ||
1217 | ehci->async_unlink = qh->unlink_next; | ||
1218 | qh->unlink_next = NULL; | ||
1219 | |||
1211 | /* Make sure the unlinks are all visible to the hardware */ | 1220 | /* Make sure the unlinks are all visible to the hardware */ |
1212 | wmb(); | 1221 | wmb(); |
1213 | 1222 | ||
@@ -1255,34 +1264,35 @@ static void end_unlink_async(struct ehci_hcd *ehci) | |||
1255 | } | 1264 | } |
1256 | } | 1265 | } |
1257 | 1266 | ||
1267 | static void start_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh); | ||
1268 | |||
1258 | static void unlink_empty_async(struct ehci_hcd *ehci) | 1269 | static void unlink_empty_async(struct ehci_hcd *ehci) |
1259 | { | 1270 | { |
1260 | struct ehci_qh *qh, *next; | 1271 | struct ehci_qh *qh; |
1261 | bool stopped = (ehci->rh_state < EHCI_RH_RUNNING); | 1272 | struct ehci_qh *qh_to_unlink = NULL; |
1262 | bool check_unlinks_later = false; | 1273 | bool check_unlinks_later = false; |
1274 | int count = 0; | ||
1263 | 1275 | ||
1264 | /* Unlink all the async QHs that have been empty for a timer cycle */ | 1276 | /* Find the last async QH which has been empty for a timer cycle */ |
1265 | next = ehci->async->qh_next.qh; | 1277 | for (qh = ehci->async->qh_next.qh; qh; qh = qh->qh_next.qh) { |
1266 | while (next) { | ||
1267 | qh = next; | ||
1268 | next = qh->qh_next.qh; | ||
1269 | |||
1270 | if (list_empty(&qh->qtd_list) && | 1278 | if (list_empty(&qh->qtd_list) && |
1271 | qh->qh_state == QH_STATE_LINKED) { | 1279 | qh->qh_state == QH_STATE_LINKED) { |
1272 | if (!stopped && qh->unlink_cycle == | 1280 | ++count; |
1273 | ehci->async_unlink_cycle) | 1281 | if (qh->unlink_cycle == ehci->async_unlink_cycle) |
1274 | check_unlinks_later = true; | 1282 | check_unlinks_later = true; |
1275 | else | 1283 | else |
1276 | single_unlink_async(ehci, qh); | 1284 | qh_to_unlink = qh; |
1277 | } | 1285 | } |
1278 | } | 1286 | } |
1279 | 1287 | ||
1280 | /* Start a new IAA cycle if any QHs are waiting for it */ | 1288 | /* If nothing else is being unlinked, unlink the last empty QH */ |
1281 | if (ehci->async_unlink) | 1289 | if (!ehci->async_iaa && !ehci->async_unlink && qh_to_unlink) { |
1282 | start_iaa_cycle(ehci, false); | 1290 | start_unlink_async(ehci, qh_to_unlink); |
1291 | --count; | ||
1292 | } | ||
1283 | 1293 | ||
1284 | /* QHs that haven't been empty for long enough will be handled later */ | 1294 | /* Other QHs will be handled later */ |
1285 | if (check_unlinks_later) { | 1295 | if (count > 0) { |
1286 | ehci_enable_event(ehci, EHCI_HRTIMER_ASYNC_UNLINKS, true); | 1296 | ehci_enable_event(ehci, EHCI_HRTIMER_ASYNC_UNLINKS, true); |
1287 | ++ehci->async_unlink_cycle; | 1297 | ++ehci->async_unlink_cycle; |
1288 | } | 1298 | } |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 69ebee73c0c1..b476daf49f6f 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -213,7 +213,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask) | |||
213 | } | 213 | } |
214 | 214 | ||
215 | static const unsigned char | 215 | static const unsigned char |
216 | max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 }; | 216 | max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 }; |
217 | 217 | ||
218 | /* carryover low/fullspeed bandwidth that crosses uframe boundries */ | 218 | /* carryover low/fullspeed bandwidth that crosses uframe boundries */ |
219 | static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8]) | 219 | static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8]) |
@@ -2212,11 +2212,11 @@ static void scan_isoc(struct ehci_hcd *ehci) | |||
2212 | } | 2212 | } |
2213 | ehci->now_frame = now_frame; | 2213 | ehci->now_frame = now_frame; |
2214 | 2214 | ||
2215 | frame = ehci->last_iso_frame; | ||
2215 | for (;;) { | 2216 | for (;;) { |
2216 | union ehci_shadow q, *q_p; | 2217 | union ehci_shadow q, *q_p; |
2217 | __hc32 type, *hw_p; | 2218 | __hc32 type, *hw_p; |
2218 | 2219 | ||
2219 | frame = ehci->last_iso_frame; | ||
2220 | restart: | 2220 | restart: |
2221 | /* scan each element in frame's queue for completions */ | 2221 | /* scan each element in frame's queue for completions */ |
2222 | q_p = &ehci->pshadow [frame]; | 2222 | q_p = &ehci->pshadow [frame]; |
@@ -2321,6 +2321,9 @@ restart: | |||
2321 | /* Stop when we have reached the current frame */ | 2321 | /* Stop when we have reached the current frame */ |
2322 | if (frame == now_frame) | 2322 | if (frame == now_frame) |
2323 | break; | 2323 | break; |
2324 | ehci->last_iso_frame = (frame + 1) & fmask; | 2324 | |
2325 | /* The last frame may still have active siTDs */ | ||
2326 | ehci->last_iso_frame = frame; | ||
2327 | frame = (frame + 1) & fmask; | ||
2325 | } | 2328 | } |
2326 | } | 2329 | } |
diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c index 20dbdcbe9b0f..f904071d70df 100644 --- a/drivers/usb/host/ehci-timer.c +++ b/drivers/usb/host/ehci-timer.c | |||
@@ -113,14 +113,15 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci) | |||
113 | 113 | ||
114 | if (want != actual) { | 114 | if (want != actual) { |
115 | 115 | ||
116 | /* Poll again later, but give up after about 20 ms */ | 116 | /* Poll again later */ |
117 | if (ehci->ASS_poll_count++ < 20) { | 117 | ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); |
118 | ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); | 118 | ++ehci->ASS_poll_count; |
119 | return; | 119 | return; |
120 | } | ||
121 | ehci_dbg(ehci, "Waited too long for the async schedule status (%x/%x), giving up\n", | ||
122 | want, actual); | ||
123 | } | 120 | } |
121 | |||
122 | if (ehci->ASS_poll_count > 20) | ||
123 | ehci_dbg(ehci, "ASS poll count reached %d\n", | ||
124 | ehci->ASS_poll_count); | ||
124 | ehci->ASS_poll_count = 0; | 125 | ehci->ASS_poll_count = 0; |
125 | 126 | ||
126 | /* The status is up-to-date; restart or stop the schedule as needed */ | 127 | /* The status is up-to-date; restart or stop the schedule as needed */ |
@@ -159,14 +160,14 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci) | |||
159 | 160 | ||
160 | if (want != actual) { | 161 | if (want != actual) { |
161 | 162 | ||
162 | /* Poll again later, but give up after about 20 ms */ | 163 | /* Poll again later */ |
163 | if (ehci->PSS_poll_count++ < 20) { | 164 | ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true); |
164 | ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true); | 165 | return; |
165 | return; | ||
166 | } | ||
167 | ehci_dbg(ehci, "Waited too long for the periodic schedule status (%x/%x), giving up\n", | ||
168 | want, actual); | ||
169 | } | 166 | } |
167 | |||
168 | if (ehci->PSS_poll_count > 20) | ||
169 | ehci_dbg(ehci, "PSS poll count reached %d\n", | ||
170 | ehci->PSS_poll_count); | ||
170 | ehci->PSS_poll_count = 0; | 171 | ehci->PSS_poll_count = 0; |
171 | 172 | ||
172 | /* The status is up-to-date; restart or stop the schedule as needed */ | 173 | /* The status is up-to-date; restart or stop the schedule as needed */ |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index a3b6d7104ae2..4c338ec03a07 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -780,6 +780,7 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) | |||
780 | "defaulting to EHCI.\n"); | 780 | "defaulting to EHCI.\n"); |
781 | dev_warn(&xhci_pdev->dev, | 781 | dev_warn(&xhci_pdev->dev, |
782 | "USB 3.0 devices will work at USB 2.0 speeds.\n"); | 782 | "USB 3.0 devices will work at USB 2.0 speeds.\n"); |
783 | usb_disable_xhci_ports(xhci_pdev); | ||
783 | return; | 784 | return; |
784 | } | 785 | } |
785 | 786 | ||
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 533b864f2e67..f87bee6d2789 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c | |||
@@ -116,6 +116,7 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, | |||
116 | } | 116 | } |
117 | } | 117 | } |
118 | clear_bit(port, &uhci->resuming_ports); | 118 | clear_bit(port, &uhci->resuming_ports); |
119 | usb_hcd_end_port_resume(&uhci_to_hcd(uhci)->self, port); | ||
119 | } | 120 | } |
120 | 121 | ||
121 | /* Wait for the UHCI controller in HP's iLO2 server management chip. | 122 | /* Wait for the UHCI controller in HP's iLO2 server management chip. |
@@ -167,6 +168,8 @@ static void uhci_check_ports(struct uhci_hcd *uhci) | |||
167 | set_bit(port, &uhci->resuming_ports); | 168 | set_bit(port, &uhci->resuming_ports); |
168 | uhci->ports_timeout = jiffies + | 169 | uhci->ports_timeout = jiffies + |
169 | msecs_to_jiffies(25); | 170 | msecs_to_jiffies(25); |
171 | usb_hcd_start_port_resume( | ||
172 | &uhci_to_hcd(uhci)->self, port); | ||
170 | 173 | ||
171 | /* Make sure we see the port again | 174 | /* Make sure we see the port again |
172 | * after the resuming period is over. */ | 175 | * after the resuming period is over. */ |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index f69720983fc7..882875465301 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -1698,7 +1698,7 @@ static void handle_port_status(struct xhci_hcd *xhci, | |||
1698 | faked_port_index + 1); | 1698 | faked_port_index + 1); |
1699 | if (slot_id && xhci->devs[slot_id]) | 1699 | if (slot_id && xhci->devs[slot_id]) |
1700 | xhci_ring_device(xhci, slot_id); | 1700 | xhci_ring_device(xhci, slot_id); |
1701 | if (bus_state->port_remote_wakeup && (1 << faked_port_index)) { | 1701 | if (bus_state->port_remote_wakeup & (1 << faked_port_index)) { |
1702 | bus_state->port_remote_wakeup &= | 1702 | bus_state->port_remote_wakeup &= |
1703 | ~(1 << faked_port_index); | 1703 | ~(1 << faked_port_index); |
1704 | xhci_test_and_clear_bit(xhci, port_array, | 1704 | xhci_test_and_clear_bit(xhci, port_array, |
@@ -2589,6 +2589,8 @@ cleanup: | |||
2589 | (trb_comp_code != COMP_STALL && | 2589 | (trb_comp_code != COMP_STALL && |
2590 | trb_comp_code != COMP_BABBLE)) | 2590 | trb_comp_code != COMP_BABBLE)) |
2591 | xhci_urb_free_priv(xhci, urb_priv); | 2591 | xhci_urb_free_priv(xhci, urb_priv); |
2592 | else | ||
2593 | kfree(urb_priv); | ||
2592 | 2594 | ||
2593 | usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); | 2595 | usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); |
2594 | if ((urb->actual_length != urb->transfer_buffer_length && | 2596 | if ((urb->actual_length != urb->transfer_buffer_length && |
@@ -3106,7 +3108,7 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len, | |||
3106 | * running_total. | 3108 | * running_total. |
3107 | */ | 3109 | */ |
3108 | packets_transferred = (running_total + trb_buff_len) / | 3110 | packets_transferred = (running_total + trb_buff_len) / |
3109 | usb_endpoint_maxp(&urb->ep->desc); | 3111 | GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc)); |
3110 | 3112 | ||
3111 | if ((total_packet_count - packets_transferred) > 31) | 3113 | if ((total_packet_count - packets_transferred) > 31) |
3112 | return 31 << 17; | 3114 | return 31 << 17; |
@@ -3640,7 +3642,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
3640 | td_len = urb->iso_frame_desc[i].length; | 3642 | td_len = urb->iso_frame_desc[i].length; |
3641 | td_remain_len = td_len; | 3643 | td_remain_len = td_len; |
3642 | total_packet_count = DIV_ROUND_UP(td_len, | 3644 | total_packet_count = DIV_ROUND_UP(td_len, |
3643 | usb_endpoint_maxp(&urb->ep->desc)); | 3645 | GET_MAX_PACKET( |
3646 | usb_endpoint_maxp(&urb->ep->desc))); | ||
3644 | /* A zero-length transfer still involves at least one packet. */ | 3647 | /* A zero-length transfer still involves at least one packet. */ |
3645 | if (total_packet_count == 0) | 3648 | if (total_packet_count == 0) |
3646 | total_packet_count++; | 3649 | total_packet_count++; |
@@ -3662,9 +3665,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
3662 | td = urb_priv->td[i]; | 3665 | td = urb_priv->td[i]; |
3663 | for (j = 0; j < trbs_per_td; j++) { | 3666 | for (j = 0; j < trbs_per_td; j++) { |
3664 | u32 remainder = 0; | 3667 | u32 remainder = 0; |
3665 | field = TRB_TBC(burst_count) | TRB_TLBPC(residue); | 3668 | field = 0; |
3666 | 3669 | ||
3667 | if (first_trb) { | 3670 | if (first_trb) { |
3671 | field = TRB_TBC(burst_count) | | ||
3672 | TRB_TLBPC(residue); | ||
3668 | /* Queue the isoc TRB */ | 3673 | /* Queue the isoc TRB */ |
3669 | field |= TRB_TYPE(TRB_ISOC); | 3674 | field |= TRB_TYPE(TRB_ISOC); |
3670 | /* Assume URB_ISO_ASAP is set */ | 3675 | /* Assume URB_ISO_ASAP is set */ |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index f14736f647ff..edc0f0dcad83 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -60,6 +60,7 @@ static const struct usb_device_id id_table[] = { | |||
60 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ | 60 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ |
61 | { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */ | 61 | { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */ |
62 | { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */ | 62 | { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */ |
63 | { USB_DEVICE(0x0FDE, 0xCA05) }, /* OWL Wireless Electricity Monitor CM-160 */ | ||
63 | { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ | 64 | { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ |
64 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ | 65 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ |
65 | { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ | 66 | { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ba68835d06a6..90ceef1776c3 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -584,6 +584,7 @@ static struct usb_device_id id_table_combined [] = { | |||
584 | /* | 584 | /* |
585 | * ELV devices: | 585 | * ELV devices: |
586 | */ | 586 | */ |
587 | { USB_DEVICE(FTDI_ELV_VID, FTDI_ELV_WS300_PID) }, | ||
587 | { USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) }, | 588 | { USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) }, |
588 | { USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) }, | 589 | { USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) }, |
589 | { USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) }, | 590 | { USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) }, |
@@ -670,6 +671,7 @@ static struct usb_device_id id_table_combined [] = { | |||
670 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) }, | 671 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) }, |
671 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) }, | 672 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) }, |
672 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) }, | 673 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) }, |
674 | { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) }, | ||
673 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, | 675 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, |
674 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, | 676 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, |
675 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_KW_PID) }, | 677 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_KW_PID) }, |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index fa5d56038276..9d359e189a64 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -147,6 +147,11 @@ | |||
147 | #define XSENS_CONVERTER_6_PID 0xD38E | 147 | #define XSENS_CONVERTER_6_PID 0xD38E |
148 | #define XSENS_CONVERTER_7_PID 0xD38F | 148 | #define XSENS_CONVERTER_7_PID 0xD38F |
149 | 149 | ||
150 | /** | ||
151 | * Zolix (www.zolix.com.cb) product ids | ||
152 | */ | ||
153 | #define FTDI_OMNI1509 0xD491 /* Omni1509 embedded USB-serial */ | ||
154 | |||
150 | /* | 155 | /* |
151 | * NDI (www.ndigital.com) product ids | 156 | * NDI (www.ndigital.com) product ids |
152 | */ | 157 | */ |
@@ -204,7 +209,7 @@ | |||
204 | 209 | ||
205 | /* | 210 | /* |
206 | * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). | 211 | * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). |
207 | * All of these devices use FTDI's vendor ID (0x0403). | 212 | * Almost all of these devices use FTDI's vendor ID (0x0403). |
208 | * Further IDs taken from ELV Windows .inf file. | 213 | * Further IDs taken from ELV Windows .inf file. |
209 | * | 214 | * |
210 | * The previously included PID for the UO 100 module was incorrect. | 215 | * The previously included PID for the UO 100 module was incorrect. |
@@ -212,6 +217,8 @@ | |||
212 | * | 217 | * |
213 | * Armin Laeuger originally sent the PID for the UM 100 module. | 218 | * Armin Laeuger originally sent the PID for the UM 100 module. |
214 | */ | 219 | */ |
220 | #define FTDI_ELV_VID 0x1B1F /* ELV AG */ | ||
221 | #define FTDI_ELV_WS300_PID 0xC006 /* eQ3 WS 300 PC II */ | ||
215 | #define FTDI_ELV_USR_PID 0xE000 /* ELV Universal-Sound-Recorder */ | 222 | #define FTDI_ELV_USR_PID 0xE000 /* ELV Universal-Sound-Recorder */ |
216 | #define FTDI_ELV_MSM1_PID 0xE001 /* ELV Mini-Sound-Modul */ | 223 | #define FTDI_ELV_MSM1_PID 0xE001 /* ELV Mini-Sound-Modul */ |
217 | #define FTDI_ELV_KL100_PID 0xE002 /* ELV Kfz-Leistungsmesser KL 100 */ | 224 | #define FTDI_ELV_KL100_PID 0xE002 /* ELV Kfz-Leistungsmesser KL 100 */ |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index b51abfd87cc6..868a57d898cf 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -242,6 +242,7 @@ static void option_instat_callback(struct urb *urb); | |||
242 | #define TELIT_PRODUCT_CC864_DUAL 0x1005 | 242 | #define TELIT_PRODUCT_CC864_DUAL 0x1005 |
243 | #define TELIT_PRODUCT_CC864_SINGLE 0x1006 | 243 | #define TELIT_PRODUCT_CC864_SINGLE 0x1006 |
244 | #define TELIT_PRODUCT_DE910_DUAL 0x1010 | 244 | #define TELIT_PRODUCT_DE910_DUAL 0x1010 |
245 | #define TELIT_PRODUCT_LE920 0x1200 | ||
245 | 246 | ||
246 | /* ZTE PRODUCTS */ | 247 | /* ZTE PRODUCTS */ |
247 | #define ZTE_VENDOR_ID 0x19d2 | 248 | #define ZTE_VENDOR_ID 0x19d2 |
@@ -453,6 +454,10 @@ static void option_instat_callback(struct urb *urb); | |||
453 | #define TPLINK_VENDOR_ID 0x2357 | 454 | #define TPLINK_VENDOR_ID 0x2357 |
454 | #define TPLINK_PRODUCT_MA180 0x0201 | 455 | #define TPLINK_PRODUCT_MA180 0x0201 |
455 | 456 | ||
457 | /* Changhong products */ | ||
458 | #define CHANGHONG_VENDOR_ID 0x2077 | ||
459 | #define CHANGHONG_PRODUCT_CH690 0x7001 | ||
460 | |||
456 | /* some devices interfaces need special handling due to a number of reasons */ | 461 | /* some devices interfaces need special handling due to a number of reasons */ |
457 | enum option_blacklist_reason { | 462 | enum option_blacklist_reason { |
458 | OPTION_BLACKLIST_NONE = 0, | 463 | OPTION_BLACKLIST_NONE = 0, |
@@ -535,6 +540,11 @@ static const struct option_blacklist_info zte_1255_blacklist = { | |||
535 | .reserved = BIT(3) | BIT(4), | 540 | .reserved = BIT(3) | BIT(4), |
536 | }; | 541 | }; |
537 | 542 | ||
543 | static const struct option_blacklist_info telit_le920_blacklist = { | ||
544 | .sendsetup = BIT(0), | ||
545 | .reserved = BIT(1) | BIT(5), | ||
546 | }; | ||
547 | |||
538 | static const struct usb_device_id option_ids[] = { | 548 | static const struct usb_device_id option_ids[] = { |
539 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 549 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
540 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 550 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
@@ -785,6 +795,8 @@ static const struct usb_device_id option_ids[] = { | |||
785 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) }, | 795 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) }, |
786 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, | 796 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, |
787 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, | 797 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, |
798 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920), | ||
799 | .driver_info = (kernel_ulong_t)&telit_le920_blacklist }, | ||
788 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ | 800 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ |
789 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), | 801 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), |
790 | .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, | 802 | .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, |
@@ -1326,6 +1338,7 @@ static const struct usb_device_id option_ids[] = { | |||
1326 | { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) }, | 1338 | { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) }, |
1327 | { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), | 1339 | { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), |
1328 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 1340 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
1341 | { USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) }, | ||
1329 | { } /* Terminating entry */ | 1342 | { } /* Terminating entry */ |
1330 | }; | 1343 | }; |
1331 | MODULE_DEVICE_TABLE(usb, option_ids); | 1344 | MODULE_DEVICE_TABLE(usb, option_ids); |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index aa148c21ea40..24662547dc5b 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -53,6 +53,7 @@ static const struct usb_device_id id_table[] = { | |||
53 | {DEVICE_G1K(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ | 53 | {DEVICE_G1K(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ |
54 | {DEVICE_G1K(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ | 54 | {DEVICE_G1K(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ |
55 | {DEVICE_G1K(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ | 55 | {DEVICE_G1K(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ |
56 | {DEVICE_G1K(0x1bc7, 0x900e)}, /* Telit Gobi QDL device */ | ||
56 | 57 | ||
57 | /* Gobi 2000 devices */ | 58 | /* Gobi 2000 devices */ |
58 | {USB_DEVICE(0x1410, 0xa010)}, /* Novatel Gobi 2000 QDL device */ | 59 | {USB_DEVICE(0x1410, 0xa010)}, /* Novatel Gobi 2000 QDL device */ |
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 105d900150c1..16b0bf055eeb 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c | |||
@@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us) | |||
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | /* This places the HUAWEI E220 devices in multi-port mode */ | 95 | /* This places the HUAWEI usb dongles in multi-port mode */ |
96 | int usb_stor_huawei_e220_init(struct us_data *us) | 96 | static int usb_stor_huawei_feature_init(struct us_data *us) |
97 | { | 97 | { |
98 | int result; | 98 | int result; |
99 | 99 | ||
@@ -104,3 +104,75 @@ int usb_stor_huawei_e220_init(struct us_data *us) | |||
104 | US_DEBUGP("Huawei mode set result is %d\n", result); | 104 | US_DEBUGP("Huawei mode set result is %d\n", result); |
105 | return 0; | 105 | return 0; |
106 | } | 106 | } |
107 | |||
108 | /* | ||
109 | * It will send a scsi switch command called rewind' to huawei dongle. | ||
110 | * When the dongle receives this command at the first time, | ||
111 | * it will reboot immediately. After rebooted, it will ignore this command. | ||
112 | * So it is unnecessary to read its response. | ||
113 | */ | ||
114 | static int usb_stor_huawei_scsi_init(struct us_data *us) | ||
115 | { | ||
116 | int result = 0; | ||
117 | int act_len = 0; | ||
118 | struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf; | ||
119 | char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00, | ||
120 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||
121 | |||
122 | bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN); | ||
123 | bcbw->Tag = 0; | ||
124 | bcbw->DataTransferLength = 0; | ||
125 | bcbw->Flags = bcbw->Lun = 0; | ||
126 | bcbw->Length = sizeof(rewind_cmd); | ||
127 | memset(bcbw->CDB, 0, sizeof(bcbw->CDB)); | ||
128 | memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd)); | ||
129 | |||
130 | result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw, | ||
131 | US_BULK_CB_WRAP_LEN, &act_len); | ||
132 | US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result); | ||
133 | return result; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * It tries to find the supported Huawei USB dongles. | ||
138 | * In Huawei, they assign the following product IDs | ||
139 | * for all of their mobile broadband dongles, | ||
140 | * including the new dongles in the future. | ||
141 | * So if the product ID is not included in this list, | ||
142 | * it means it is not Huawei's mobile broadband dongles. | ||
143 | */ | ||
144 | static int usb_stor_huawei_dongles_pid(struct us_data *us) | ||
145 | { | ||
146 | struct usb_interface_descriptor *idesc; | ||
147 | int idProduct; | ||
148 | |||
149 | idesc = &us->pusb_intf->cur_altsetting->desc; | ||
150 | idProduct = us->pusb_dev->descriptor.idProduct; | ||
151 | /* The first port is CDROM, | ||
152 | * means the dongle in the single port mode, | ||
153 | * and a switch command is required to be sent. */ | ||
154 | if (idesc && idesc->bInterfaceNumber == 0) { | ||
155 | if ((idProduct == 0x1001) | ||
156 | || (idProduct == 0x1003) | ||
157 | || (idProduct == 0x1004) | ||
158 | || (idProduct >= 0x1401 && idProduct <= 0x1500) | ||
159 | || (idProduct >= 0x1505 && idProduct <= 0x1600) | ||
160 | || (idProduct >= 0x1c02 && idProduct <= 0x2202)) { | ||
161 | return 1; | ||
162 | } | ||
163 | } | ||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | int usb_stor_huawei_init(struct us_data *us) | ||
168 | { | ||
169 | int result = 0; | ||
170 | |||
171 | if (usb_stor_huawei_dongles_pid(us)) { | ||
172 | if (us->pusb_dev->descriptor.idProduct >= 0x1446) | ||
173 | result = usb_stor_huawei_scsi_init(us); | ||
174 | else | ||
175 | result = usb_stor_huawei_feature_init(us); | ||
176 | } | ||
177 | return result; | ||
178 | } | ||
diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h index 529327fbb06b..5376d4fc76f0 100644 --- a/drivers/usb/storage/initializers.h +++ b/drivers/usb/storage/initializers.h | |||
@@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us); | |||
46 | * flash reader */ | 46 | * flash reader */ |
47 | int usb_stor_ucr61s2b_init(struct us_data *us); | 47 | int usb_stor_ucr61s2b_init(struct us_data *us); |
48 | 48 | ||
49 | /* This places the HUAWEI E220 devices in multi-port mode */ | 49 | /* This places the HUAWEI usb dongles in multi-port mode */ |
50 | int usb_stor_huawei_e220_init(struct us_data *us); | 50 | int usb_stor_huawei_init(struct us_data *us); |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d305a5aa3a5d..72923b56bbf6 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -1527,335 +1527,10 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100, | |||
1527 | /* Reported by fangxiaozhi <huananhu@huawei.com> | 1527 | /* Reported by fangxiaozhi <huananhu@huawei.com> |
1528 | * This brings the HUAWEI data card devices into multi-port mode | 1528 | * This brings the HUAWEI data card devices into multi-port mode |
1529 | */ | 1529 | */ |
1530 | UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000, | 1530 | UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50, |
1531 | "HUAWEI MOBILE", | 1531 | "HUAWEI MOBILE", |
1532 | "Mass Storage", | 1532 | "Mass Storage", |
1533 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | 1533 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init, |
1534 | 0), | ||
1535 | UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000, | ||
1536 | "HUAWEI MOBILE", | ||
1537 | "Mass Storage", | ||
1538 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1539 | 0), | ||
1540 | UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000, | ||
1541 | "HUAWEI MOBILE", | ||
1542 | "Mass Storage", | ||
1543 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1544 | 0), | ||
1545 | UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000, | ||
1546 | "HUAWEI MOBILE", | ||
1547 | "Mass Storage", | ||
1548 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1549 | 0), | ||
1550 | UNUSUAL_DEV( 0x12d1, 0x1402, 0x0000, 0x0000, | ||
1551 | "HUAWEI MOBILE", | ||
1552 | "Mass Storage", | ||
1553 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1554 | 0), | ||
1555 | UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000, | ||
1556 | "HUAWEI MOBILE", | ||
1557 | "Mass Storage", | ||
1558 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1559 | 0), | ||
1560 | UNUSUAL_DEV( 0x12d1, 0x1404, 0x0000, 0x0000, | ||
1561 | "HUAWEI MOBILE", | ||
1562 | "Mass Storage", | ||
1563 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1564 | 0), | ||
1565 | UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000, | ||
1566 | "HUAWEI MOBILE", | ||
1567 | "Mass Storage", | ||
1568 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1569 | 0), | ||
1570 | UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000, | ||
1571 | "HUAWEI MOBILE", | ||
1572 | "Mass Storage", | ||
1573 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1574 | 0), | ||
1575 | UNUSUAL_DEV( 0x12d1, 0x1407, 0x0000, 0x0000, | ||
1576 | "HUAWEI MOBILE", | ||
1577 | "Mass Storage", | ||
1578 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1579 | 0), | ||
1580 | UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000, | ||
1581 | "HUAWEI MOBILE", | ||
1582 | "Mass Storage", | ||
1583 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1584 | 0), | ||
1585 | UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000, | ||
1586 | "HUAWEI MOBILE", | ||
1587 | "Mass Storage", | ||
1588 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1589 | 0), | ||
1590 | UNUSUAL_DEV( 0x12d1, 0x140A, 0x0000, 0x0000, | ||
1591 | "HUAWEI MOBILE", | ||
1592 | "Mass Storage", | ||
1593 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1594 | 0), | ||
1595 | UNUSUAL_DEV( 0x12d1, 0x140B, 0x0000, 0x0000, | ||
1596 | "HUAWEI MOBILE", | ||
1597 | "Mass Storage", | ||
1598 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1599 | 0), | ||
1600 | UNUSUAL_DEV( 0x12d1, 0x140C, 0x0000, 0x0000, | ||
1601 | "HUAWEI MOBILE", | ||
1602 | "Mass Storage", | ||
1603 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1604 | 0), | ||
1605 | UNUSUAL_DEV( 0x12d1, 0x140D, 0x0000, 0x0000, | ||
1606 | "HUAWEI MOBILE", | ||
1607 | "Mass Storage", | ||
1608 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1609 | 0), | ||
1610 | UNUSUAL_DEV( 0x12d1, 0x140E, 0x0000, 0x0000, | ||
1611 | "HUAWEI MOBILE", | ||
1612 | "Mass Storage", | ||
1613 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1614 | 0), | ||
1615 | UNUSUAL_DEV( 0x12d1, 0x140F, 0x0000, 0x0000, | ||
1616 | "HUAWEI MOBILE", | ||
1617 | "Mass Storage", | ||
1618 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1619 | 0), | ||
1620 | UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000, | ||
1621 | "HUAWEI MOBILE", | ||
1622 | "Mass Storage", | ||
1623 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1624 | 0), | ||
1625 | UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000, | ||
1626 | "HUAWEI MOBILE", | ||
1627 | "Mass Storage", | ||
1628 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1629 | 0), | ||
1630 | UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000, | ||
1631 | "HUAWEI MOBILE", | ||
1632 | "Mass Storage", | ||
1633 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1634 | 0), | ||
1635 | UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000, | ||
1636 | "HUAWEI MOBILE", | ||
1637 | "Mass Storage", | ||
1638 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1639 | 0), | ||
1640 | UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000, | ||
1641 | "HUAWEI MOBILE", | ||
1642 | "Mass Storage", | ||
1643 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1644 | 0), | ||
1645 | UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000, | ||
1646 | "HUAWEI MOBILE", | ||
1647 | "Mass Storage", | ||
1648 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1649 | 0), | ||
1650 | UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000, | ||
1651 | "HUAWEI MOBILE", | ||
1652 | "Mass Storage", | ||
1653 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1654 | 0), | ||
1655 | UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000, | ||
1656 | "HUAWEI MOBILE", | ||
1657 | "Mass Storage", | ||
1658 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1659 | 0), | ||
1660 | UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000, | ||
1661 | "HUAWEI MOBILE", | ||
1662 | "Mass Storage", | ||
1663 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1664 | 0), | ||
1665 | UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000, | ||
1666 | "HUAWEI MOBILE", | ||
1667 | "Mass Storage", | ||
1668 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1669 | 0), | ||
1670 | UNUSUAL_DEV( 0x12d1, 0x141A, 0x0000, 0x0000, | ||
1671 | "HUAWEI MOBILE", | ||
1672 | "Mass Storage", | ||
1673 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1674 | 0), | ||
1675 | UNUSUAL_DEV( 0x12d1, 0x141B, 0x0000, 0x0000, | ||
1676 | "HUAWEI MOBILE", | ||
1677 | "Mass Storage", | ||
1678 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1679 | 0), | ||
1680 | UNUSUAL_DEV( 0x12d1, 0x141C, 0x0000, 0x0000, | ||
1681 | "HUAWEI MOBILE", | ||
1682 | "Mass Storage", | ||
1683 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1684 | 0), | ||
1685 | UNUSUAL_DEV( 0x12d1, 0x141D, 0x0000, 0x0000, | ||
1686 | "HUAWEI MOBILE", | ||
1687 | "Mass Storage", | ||
1688 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1689 | 0), | ||
1690 | UNUSUAL_DEV( 0x12d1, 0x141E, 0x0000, 0x0000, | ||
1691 | "HUAWEI MOBILE", | ||
1692 | "Mass Storage", | ||
1693 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1694 | 0), | ||
1695 | UNUSUAL_DEV( 0x12d1, 0x141F, 0x0000, 0x0000, | ||
1696 | "HUAWEI MOBILE", | ||
1697 | "Mass Storage", | ||
1698 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1699 | 0), | ||
1700 | UNUSUAL_DEV( 0x12d1, 0x1420, 0x0000, 0x0000, | ||
1701 | "HUAWEI MOBILE", | ||
1702 | "Mass Storage", | ||
1703 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1704 | 0), | ||
1705 | UNUSUAL_DEV( 0x12d1, 0x1421, 0x0000, 0x0000, | ||
1706 | "HUAWEI MOBILE", | ||
1707 | "Mass Storage", | ||
1708 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1709 | 0), | ||
1710 | UNUSUAL_DEV( 0x12d1, 0x1422, 0x0000, 0x0000, | ||
1711 | "HUAWEI MOBILE", | ||
1712 | "Mass Storage", | ||
1713 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1714 | 0), | ||
1715 | UNUSUAL_DEV( 0x12d1, 0x1423, 0x0000, 0x0000, | ||
1716 | "HUAWEI MOBILE", | ||
1717 | "Mass Storage", | ||
1718 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1719 | 0), | ||
1720 | UNUSUAL_DEV( 0x12d1, 0x1424, 0x0000, 0x0000, | ||
1721 | "HUAWEI MOBILE", | ||
1722 | "Mass Storage", | ||
1723 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1724 | 0), | ||
1725 | UNUSUAL_DEV( 0x12d1, 0x1425, 0x0000, 0x0000, | ||
1726 | "HUAWEI MOBILE", | ||
1727 | "Mass Storage", | ||
1728 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1729 | 0), | ||
1730 | UNUSUAL_DEV( 0x12d1, 0x1426, 0x0000, 0x0000, | ||
1731 | "HUAWEI MOBILE", | ||
1732 | "Mass Storage", | ||
1733 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1734 | 0), | ||
1735 | UNUSUAL_DEV( 0x12d1, 0x1427, 0x0000, 0x0000, | ||
1736 | "HUAWEI MOBILE", | ||
1737 | "Mass Storage", | ||
1738 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1739 | 0), | ||
1740 | UNUSUAL_DEV( 0x12d1, 0x1428, 0x0000, 0x0000, | ||
1741 | "HUAWEI MOBILE", | ||
1742 | "Mass Storage", | ||
1743 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1744 | 0), | ||
1745 | UNUSUAL_DEV( 0x12d1, 0x1429, 0x0000, 0x0000, | ||
1746 | "HUAWEI MOBILE", | ||
1747 | "Mass Storage", | ||
1748 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1749 | 0), | ||
1750 | UNUSUAL_DEV( 0x12d1, 0x142A, 0x0000, 0x0000, | ||
1751 | "HUAWEI MOBILE", | ||
1752 | "Mass Storage", | ||
1753 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1754 | 0), | ||
1755 | UNUSUAL_DEV( 0x12d1, 0x142B, 0x0000, 0x0000, | ||
1756 | "HUAWEI MOBILE", | ||
1757 | "Mass Storage", | ||
1758 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1759 | 0), | ||
1760 | UNUSUAL_DEV( 0x12d1, 0x142C, 0x0000, 0x0000, | ||
1761 | "HUAWEI MOBILE", | ||
1762 | "Mass Storage", | ||
1763 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1764 | 0), | ||
1765 | UNUSUAL_DEV( 0x12d1, 0x142D, 0x0000, 0x0000, | ||
1766 | "HUAWEI MOBILE", | ||
1767 | "Mass Storage", | ||
1768 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1769 | 0), | ||
1770 | UNUSUAL_DEV( 0x12d1, 0x142E, 0x0000, 0x0000, | ||
1771 | "HUAWEI MOBILE", | ||
1772 | "Mass Storage", | ||
1773 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1774 | 0), | ||
1775 | UNUSUAL_DEV( 0x12d1, 0x142F, 0x0000, 0x0000, | ||
1776 | "HUAWEI MOBILE", | ||
1777 | "Mass Storage", | ||
1778 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1779 | 0), | ||
1780 | UNUSUAL_DEV( 0x12d1, 0x1430, 0x0000, 0x0000, | ||
1781 | "HUAWEI MOBILE", | ||
1782 | "Mass Storage", | ||
1783 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1784 | 0), | ||
1785 | UNUSUAL_DEV( 0x12d1, 0x1431, 0x0000, 0x0000, | ||
1786 | "HUAWEI MOBILE", | ||
1787 | "Mass Storage", | ||
1788 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1789 | 0), | ||
1790 | UNUSUAL_DEV( 0x12d1, 0x1432, 0x0000, 0x0000, | ||
1791 | "HUAWEI MOBILE", | ||
1792 | "Mass Storage", | ||
1793 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1794 | 0), | ||
1795 | UNUSUAL_DEV( 0x12d1, 0x1433, 0x0000, 0x0000, | ||
1796 | "HUAWEI MOBILE", | ||
1797 | "Mass Storage", | ||
1798 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1799 | 0), | ||
1800 | UNUSUAL_DEV( 0x12d1, 0x1434, 0x0000, 0x0000, | ||
1801 | "HUAWEI MOBILE", | ||
1802 | "Mass Storage", | ||
1803 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1804 | 0), | ||
1805 | UNUSUAL_DEV( 0x12d1, 0x1435, 0x0000, 0x0000, | ||
1806 | "HUAWEI MOBILE", | ||
1807 | "Mass Storage", | ||
1808 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1809 | 0), | ||
1810 | UNUSUAL_DEV( 0x12d1, 0x1436, 0x0000, 0x0000, | ||
1811 | "HUAWEI MOBILE", | ||
1812 | "Mass Storage", | ||
1813 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1814 | 0), | ||
1815 | UNUSUAL_DEV( 0x12d1, 0x1437, 0x0000, 0x0000, | ||
1816 | "HUAWEI MOBILE", | ||
1817 | "Mass Storage", | ||
1818 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1819 | 0), | ||
1820 | UNUSUAL_DEV( 0x12d1, 0x1438, 0x0000, 0x0000, | ||
1821 | "HUAWEI MOBILE", | ||
1822 | "Mass Storage", | ||
1823 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1824 | 0), | ||
1825 | UNUSUAL_DEV( 0x12d1, 0x1439, 0x0000, 0x0000, | ||
1826 | "HUAWEI MOBILE", | ||
1827 | "Mass Storage", | ||
1828 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1829 | 0), | ||
1830 | UNUSUAL_DEV( 0x12d1, 0x143A, 0x0000, 0x0000, | ||
1831 | "HUAWEI MOBILE", | ||
1832 | "Mass Storage", | ||
1833 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1834 | 0), | ||
1835 | UNUSUAL_DEV( 0x12d1, 0x143B, 0x0000, 0x0000, | ||
1836 | "HUAWEI MOBILE", | ||
1837 | "Mass Storage", | ||
1838 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1839 | 0), | ||
1840 | UNUSUAL_DEV( 0x12d1, 0x143C, 0x0000, 0x0000, | ||
1841 | "HUAWEI MOBILE", | ||
1842 | "Mass Storage", | ||
1843 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1844 | 0), | ||
1845 | UNUSUAL_DEV( 0x12d1, 0x143D, 0x0000, 0x0000, | ||
1846 | "HUAWEI MOBILE", | ||
1847 | "Mass Storage", | ||
1848 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1849 | 0), | ||
1850 | UNUSUAL_DEV( 0x12d1, 0x143E, 0x0000, 0x0000, | ||
1851 | "HUAWEI MOBILE", | ||
1852 | "Mass Storage", | ||
1853 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1854 | 0), | ||
1855 | UNUSUAL_DEV( 0x12d1, 0x143F, 0x0000, 0x0000, | ||
1856 | "HUAWEI MOBILE", | ||
1857 | "Mass Storage", | ||
1858 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1859 | 0), | 1534 | 0), |
1860 | 1535 | ||
1861 | /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ | 1536 | /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 07b3e5406f48..d6bee407af02 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -120,6 +120,17 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks"); | |||
120 | .useTransport = use_transport, \ | 120 | .useTransport = use_transport, \ |
121 | } | 121 | } |
122 | 122 | ||
123 | #define UNUSUAL_VENDOR_INTF(idVendor, cl, sc, pr, \ | ||
124 | vendor_name, product_name, use_protocol, use_transport, \ | ||
125 | init_function, Flags) \ | ||
126 | { \ | ||
127 | .vendorName = vendor_name, \ | ||
128 | .productName = product_name, \ | ||
129 | .useProtocol = use_protocol, \ | ||
130 | .useTransport = use_transport, \ | ||
131 | .initFunction = init_function, \ | ||
132 | } | ||
133 | |||
123 | static struct us_unusual_dev us_unusual_dev_list[] = { | 134 | static struct us_unusual_dev us_unusual_dev_list[] = { |
124 | # include "unusual_devs.h" | 135 | # include "unusual_devs.h" |
125 | { } /* Terminating entry */ | 136 | { } /* Terminating entry */ |
@@ -131,6 +142,7 @@ static struct us_unusual_dev for_dynamic_ids = | |||
131 | #undef UNUSUAL_DEV | 142 | #undef UNUSUAL_DEV |
132 | #undef COMPLIANT_DEV | 143 | #undef COMPLIANT_DEV |
133 | #undef USUAL_DEV | 144 | #undef USUAL_DEV |
145 | #undef UNUSUAL_VENDOR_INTF | ||
134 | 146 | ||
135 | #ifdef CONFIG_LOCKDEP | 147 | #ifdef CONFIG_LOCKDEP |
136 | 148 | ||
diff --git a/drivers/usb/storage/usual-tables.c b/drivers/usb/storage/usual-tables.c index b78a526910fb..5ef8ce74aae4 100644 --- a/drivers/usb/storage/usual-tables.c +++ b/drivers/usb/storage/usual-tables.c | |||
@@ -41,6 +41,20 @@ | |||
41 | #define USUAL_DEV(useProto, useTrans) \ | 41 | #define USUAL_DEV(useProto, useTrans) \ |
42 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans) } | 42 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans) } |
43 | 43 | ||
44 | /* Define the device is matched with Vendor ID and interface descriptors */ | ||
45 | #define UNUSUAL_VENDOR_INTF(id_vendor, cl, sc, pr, \ | ||
46 | vendorName, productName, useProtocol, useTransport, \ | ||
47 | initFunction, flags) \ | ||
48 | { \ | ||
49 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO \ | ||
50 | | USB_DEVICE_ID_MATCH_VENDOR, \ | ||
51 | .idVendor = (id_vendor), \ | ||
52 | .bInterfaceClass = (cl), \ | ||
53 | .bInterfaceSubClass = (sc), \ | ||
54 | .bInterfaceProtocol = (pr), \ | ||
55 | .driver_info = (flags) \ | ||
56 | } | ||
57 | |||
44 | struct usb_device_id usb_storage_usb_ids[] = { | 58 | struct usb_device_id usb_storage_usb_ids[] = { |
45 | # include "unusual_devs.h" | 59 | # include "unusual_devs.h" |
46 | { } /* Terminating entry */ | 60 | { } /* Terminating entry */ |
@@ -50,6 +64,7 @@ MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids); | |||
50 | #undef UNUSUAL_DEV | 64 | #undef UNUSUAL_DEV |
51 | #undef COMPLIANT_DEV | 65 | #undef COMPLIANT_DEV |
52 | #undef USUAL_DEV | 66 | #undef USUAL_DEV |
67 | #undef UNUSUAL_VENDOR_INTF | ||
53 | 68 | ||
54 | /* | 69 | /* |
55 | * The table of devices to ignore | 70 | * The table of devices to ignore |
diff --git a/include/linux/usb.h b/include/linux/usb.h index 689b14b26c8d..4d22d0f6167a 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -357,6 +357,8 @@ struct usb_bus { | |||
357 | int bandwidth_int_reqs; /* number of Interrupt requests */ | 357 | int bandwidth_int_reqs; /* number of Interrupt requests */ |
358 | int bandwidth_isoc_reqs; /* number of Isoc. requests */ | 358 | int bandwidth_isoc_reqs; /* number of Isoc. requests */ |
359 | 359 | ||
360 | unsigned resuming_ports; /* bit array: resuming root-hub ports */ | ||
361 | |||
360 | #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) | 362 | #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) |
361 | struct mon_bus *mon_bus; /* non-null when associated */ | 363 | struct mon_bus *mon_bus; /* non-null when associated */ |
362 | int monitored; /* non-zero when monitored */ | 364 | int monitored; /* non-zero when monitored */ |
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 608050b2545f..0a78df5f6cfd 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h | |||
@@ -430,6 +430,9 @@ extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd); | |||
430 | extern void usb_wakeup_notification(struct usb_device *hdev, | 430 | extern void usb_wakeup_notification(struct usb_device *hdev, |
431 | unsigned int portnum); | 431 | unsigned int portnum); |
432 | 432 | ||
433 | extern void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum); | ||
434 | extern void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum); | ||
435 | |||
433 | /* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */ | 436 | /* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */ |
434 | #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1) | 437 | #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1) |
435 | #define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep))) | 438 | #define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep))) |
diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h index 50598472dc41..f738e25377ff 100644 --- a/include/uapi/linux/usb/ch9.h +++ b/include/uapi/linux/usb/ch9.h | |||
@@ -152,6 +152,12 @@ | |||
152 | #define USB_INTRF_FUNC_SUSPEND_LP (1 << (8 + 0)) | 152 | #define USB_INTRF_FUNC_SUSPEND_LP (1 << (8 + 0)) |
153 | #define USB_INTRF_FUNC_SUSPEND_RW (1 << (8 + 1)) | 153 | #define USB_INTRF_FUNC_SUSPEND_RW (1 << (8 + 1)) |
154 | 154 | ||
155 | /* | ||
156 | * Interface status, Figure 9-5 USB 3.0 spec | ||
157 | */ | ||
158 | #define USB_INTRF_STAT_FUNC_RW_CAP 1 | ||
159 | #define USB_INTRF_STAT_FUNC_RW 2 | ||
160 | |||
155 | #define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */ | 161 | #define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */ |
156 | 162 | ||
157 | /* Bit array elements as returned by the USB_REQ_GET_STATUS request. */ | 163 | /* Bit array elements as returned by the USB_REQ_GET_STATUS request. */ |