USB fixes for 3.8-rc6
Here are a few tiny USB fixes for 3.8-rc6. Nothing major here, some host controller bug fixes to resolve a number of bugs that people have reported, and a bunch of additional device ids are added to a number of drivers (which caused code to be deleted from the usb-storage driver, always nice.) Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iEYEABECAAYFAlERRT4ACgkQMUfUDdst+ylxAQCghY23x/0vT9oCsrWZzKeOFOMB J64AoNjVngpCpIcmh/yk1tgjSRSQu3dn =p4nA -----END PGP SIGNATURE----- Merge tag 'usb-3.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb Pull USB fixes from Greg Kroah-Hartman: "Here are a few tiny USB fixes for 3.8-rc6. Nothing major here, some host controller bug fixes to resolve a number of bugs that people have reported, and a bunch of additional device ids are added to a number of drivers (which caused code to be deleted from the usb-storage driver, always nice)" * tag 'usb-3.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (22 commits) USB: storage: optimize to match the Huawei USB storage devices and support new switch command USB: storage: Define a new macro for USB storage match rules USB: ftdi_sio: add Zolix FTDI PID USB: option: add Changhong CH690 USB: ftdi_sio: add PID/VID entries for ELV WS 300 PC II USB: add OWL CM-160 support to cp210x driver USB: EHCI: fix bug in scheduling periodic split transfers USB: EHCI: fix for leaking isochronous data USB: option: add support for Telit LE920 USB: qcserial: add Telit Gobi QDL device USB: EHCI: fix timer bug affecting port resume USB: UHCI: notify usbcore about port resumes USB: EHCI: notify usbcore about port resumes USB: add usb_hcd_{start,end}_port_resume USB: EHCI: unlink one async QH at a time USB: EHCI: remove ASS/PSS polling timeout usb: Using correct way to clear usb3.0 device's remote wakeup feature. usb: Prevent dead ports when xhci is not enabled USB: XHCI: fix memory leak of URB-private data drivers: xhci: fix incorrect bit test ...
This commit is contained in:
Коммит
0f632118a1
|
@ -39,6 +39,7 @@
|
|||
#include <asm/unaligned.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/hcd.h>
|
||||
|
@ -1025,6 +1026,49 @@ static int register_root_hub(struct usb_hcd *hcd)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* usb_hcd_start_port_resume - a root-hub port is sending a resume signal
|
||||
* @bus: the bus which the root hub belongs to
|
||||
* @portnum: the port which is being resumed
|
||||
*
|
||||
* HCDs should call this function when they know that a resume signal is
|
||||
* being sent to a root-hub port. The root hub will be prevented from
|
||||
* going into autosuspend until usb_hcd_end_port_resume() is called.
|
||||
*
|
||||
* The bus's private lock must be held by the caller.
|
||||
*/
|
||||
void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum)
|
||||
{
|
||||
unsigned bit = 1 << portnum;
|
||||
|
||||
if (!(bus->resuming_ports & bit)) {
|
||||
bus->resuming_ports |= bit;
|
||||
pm_runtime_get_noresume(&bus->root_hub->dev);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_hcd_start_port_resume);
|
||||
|
||||
/*
|
||||
* usb_hcd_end_port_resume - a root-hub port has stopped sending a resume signal
|
||||
* @bus: the bus which the root hub belongs to
|
||||
* @portnum: the port which is being resumed
|
||||
*
|
||||
* HCDs should call this function when they know that a resume signal has
|
||||
* stopped being sent to a root-hub port. The root hub will be allowed to
|
||||
* autosuspend again.
|
||||
*
|
||||
* The bus's private lock must be held by the caller.
|
||||
*/
|
||||
void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum)
|
||||
{
|
||||
unsigned bit = 1 << portnum;
|
||||
|
||||
if (bus->resuming_ports & bit) {
|
||||
bus->resuming_ports &= ~bit;
|
||||
pm_runtime_put_noidle(&bus->root_hub->dev);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_hcd_end_port_resume);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -2838,6 +2838,23 @@ void usb_enable_ltm(struct usb_device *udev)
|
|||
EXPORT_SYMBOL_GPL(usb_enable_ltm);
|
||||
|
||||
#ifdef CONFIG_USB_SUSPEND
|
||||
/*
|
||||
* usb_disable_function_remotewakeup - disable usb3.0
|
||||
* device's function remote wakeup
|
||||
* @udev: target device
|
||||
*
|
||||
* Assume there's only one function on the USB 3.0
|
||||
* device and disable remote wake for the first
|
||||
* interface. FIXME if the interface association
|
||||
* descriptor shows there's more than one function.
|
||||
*/
|
||||
static int usb_disable_function_remotewakeup(struct usb_device *udev)
|
||||
{
|
||||
return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE,
|
||||
USB_INTRF_FUNC_SUSPEND, 0, NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
}
|
||||
|
||||
/*
|
||||
* usb_port_suspend - suspend a usb device's upstream port
|
||||
|
@ -2955,12 +2972,19 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
|
|||
dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n",
|
||||
port1, status);
|
||||
/* paranoia: "should not happen" */
|
||||
if (udev->do_remote_wakeup)
|
||||
(void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE,
|
||||
USB_DEVICE_REMOTE_WAKEUP, 0,
|
||||
NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
if (udev->do_remote_wakeup) {
|
||||
if (!hub_is_superspeed(hub->hdev)) {
|
||||
(void) usb_control_msg(udev,
|
||||
usb_sndctrlpipe(udev, 0),
|
||||
USB_REQ_CLEAR_FEATURE,
|
||||
USB_RECIP_DEVICE,
|
||||
USB_DEVICE_REMOTE_WAKEUP, 0,
|
||||
NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
} else
|
||||
(void) usb_disable_function_remotewakeup(udev);
|
||||
|
||||
}
|
||||
|
||||
/* Try to enable USB2 hardware LPM again */
|
||||
if (udev->usb2_hw_lpm_capable == 1)
|
||||
|
@ -3052,20 +3076,30 @@ static int finish_port_resume(struct usb_device *udev)
|
|||
* udev->reset_resume
|
||||
*/
|
||||
} else if (udev->actconfig && !udev->reset_resume) {
|
||||
le16_to_cpus(&devstatus);
|
||||
if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) {
|
||||
status = usb_control_msg(udev,
|
||||
usb_sndctrlpipe(udev, 0),
|
||||
USB_REQ_CLEAR_FEATURE,
|
||||
if (!hub_is_superspeed(udev->parent)) {
|
||||
le16_to_cpus(&devstatus);
|
||||
if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP))
|
||||
status = usb_control_msg(udev,
|
||||
usb_sndctrlpipe(udev, 0),
|
||||
USB_REQ_CLEAR_FEATURE,
|
||||
USB_RECIP_DEVICE,
|
||||
USB_DEVICE_REMOTE_WAKEUP, 0,
|
||||
NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
if (status)
|
||||
dev_dbg(&udev->dev,
|
||||
"disable remote wakeup, status %d\n",
|
||||
status);
|
||||
USB_DEVICE_REMOTE_WAKEUP, 0,
|
||||
NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
} else {
|
||||
status = usb_get_status(udev, USB_RECIP_INTERFACE, 0,
|
||||
&devstatus);
|
||||
le16_to_cpus(&devstatus);
|
||||
if (!status && devstatus & (USB_INTRF_STAT_FUNC_RW_CAP
|
||||
| USB_INTRF_STAT_FUNC_RW))
|
||||
status =
|
||||
usb_disable_function_remotewakeup(udev);
|
||||
}
|
||||
|
||||
if (status)
|
||||
dev_dbg(&udev->dev,
|
||||
"disable remote wakeup, status %d\n",
|
||||
status);
|
||||
status = 0;
|
||||
}
|
||||
return status;
|
||||
|
|
|
@ -797,6 +797,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|||
ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
|
||||
set_bit(i, &ehci->resuming_ports);
|
||||
ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
|
||||
usb_hcd_start_port_resume(&hcd->self, i);
|
||||
mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -649,7 +649,11 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
|
|||
status = STS_PCD;
|
||||
}
|
||||
}
|
||||
/* FIXME autosuspend idle root hubs */
|
||||
|
||||
/* If a resume is in progress, make sure it can finish */
|
||||
if (ehci->resuming_ports)
|
||||
mod_timer(&hcd->rh_timer, jiffies + msecs_to_jiffies(25));
|
||||
|
||||
spin_unlock_irqrestore (&ehci->lock, flags);
|
||||
return status ? retval : 0;
|
||||
}
|
||||
|
@ -851,6 +855,7 @@ static int ehci_hub_control (
|
|||
/* resume signaling for 20 msec */
|
||||
ehci->reset_done[wIndex] = jiffies
|
||||
+ msecs_to_jiffies(20);
|
||||
usb_hcd_start_port_resume(&hcd->self, wIndex);
|
||||
/* check the port again */
|
||||
mod_timer(&ehci_to_hcd(ehci)->rh_timer,
|
||||
ehci->reset_done[wIndex]);
|
||||
|
@ -862,6 +867,7 @@ static int ehci_hub_control (
|
|||
clear_bit(wIndex, &ehci->suspended_ports);
|
||||
set_bit(wIndex, &ehci->port_c_suspend);
|
||||
ehci->reset_done[wIndex] = 0;
|
||||
usb_hcd_end_port_resume(&hcd->self, wIndex);
|
||||
|
||||
/* stop resume signaling */
|
||||
temp = ehci_readl(ehci, status_reg);
|
||||
|
@ -950,6 +956,7 @@ static int ehci_hub_control (
|
|||
ehci->reset_done[wIndex] = 0;
|
||||
if (temp & PORT_PE)
|
||||
set_bit(wIndex, &ehci->port_c_suspend);
|
||||
usb_hcd_end_port_resume(&hcd->self, wIndex);
|
||||
}
|
||||
|
||||
if (temp & PORT_OC)
|
||||
|
|
|
@ -1197,17 +1197,26 @@ static void start_iaa_cycle(struct ehci_hcd *ehci, bool nested)
|
|||
if (ehci->async_iaa || ehci->async_unlinking)
|
||||
return;
|
||||
|
||||
/* Do all the waiting QHs at once */
|
||||
ehci->async_iaa = ehci->async_unlink;
|
||||
ehci->async_unlink = NULL;
|
||||
|
||||
/* If the controller isn't running, we don't have to wait for it */
|
||||
if (unlikely(ehci->rh_state < EHCI_RH_RUNNING)) {
|
||||
|
||||
/* Do all the waiting QHs */
|
||||
ehci->async_iaa = ehci->async_unlink;
|
||||
ehci->async_unlink = NULL;
|
||||
|
||||
if (!nested) /* Avoid recursion */
|
||||
end_unlink_async(ehci);
|
||||
|
||||
/* Otherwise start a new IAA cycle */
|
||||
} else if (likely(ehci->rh_state == EHCI_RH_RUNNING)) {
|
||||
struct ehci_qh *qh;
|
||||
|
||||
/* Do only the first waiting QH (nVidia bug?) */
|
||||
qh = ehci->async_unlink;
|
||||
ehci->async_iaa = qh;
|
||||
ehci->async_unlink = qh->unlink_next;
|
||||
qh->unlink_next = NULL;
|
||||
|
||||
/* Make sure the unlinks are all visible to the hardware */
|
||||
wmb();
|
||||
|
||||
|
@ -1255,34 +1264,35 @@ static void end_unlink_async(struct ehci_hcd *ehci)
|
|||
}
|
||||
}
|
||||
|
||||
static void start_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh);
|
||||
|
||||
static void unlink_empty_async(struct ehci_hcd *ehci)
|
||||
{
|
||||
struct ehci_qh *qh, *next;
|
||||
bool stopped = (ehci->rh_state < EHCI_RH_RUNNING);
|
||||
struct ehci_qh *qh;
|
||||
struct ehci_qh *qh_to_unlink = NULL;
|
||||
bool check_unlinks_later = false;
|
||||
int count = 0;
|
||||
|
||||
/* Unlink all the async QHs that have been empty for a timer cycle */
|
||||
next = ehci->async->qh_next.qh;
|
||||
while (next) {
|
||||
qh = next;
|
||||
next = qh->qh_next.qh;
|
||||
|
||||
/* Find the last async QH which has been empty for a timer cycle */
|
||||
for (qh = ehci->async->qh_next.qh; qh; qh = qh->qh_next.qh) {
|
||||
if (list_empty(&qh->qtd_list) &&
|
||||
qh->qh_state == QH_STATE_LINKED) {
|
||||
if (!stopped && qh->unlink_cycle ==
|
||||
ehci->async_unlink_cycle)
|
||||
++count;
|
||||
if (qh->unlink_cycle == ehci->async_unlink_cycle)
|
||||
check_unlinks_later = true;
|
||||
else
|
||||
single_unlink_async(ehci, qh);
|
||||
qh_to_unlink = qh;
|
||||
}
|
||||
}
|
||||
|
||||
/* Start a new IAA cycle if any QHs are waiting for it */
|
||||
if (ehci->async_unlink)
|
||||
start_iaa_cycle(ehci, false);
|
||||
/* If nothing else is being unlinked, unlink the last empty QH */
|
||||
if (!ehci->async_iaa && !ehci->async_unlink && qh_to_unlink) {
|
||||
start_unlink_async(ehci, qh_to_unlink);
|
||||
--count;
|
||||
}
|
||||
|
||||
/* QHs that haven't been empty for long enough will be handled later */
|
||||
if (check_unlinks_later) {
|
||||
/* Other QHs will be handled later */
|
||||
if (count > 0) {
|
||||
ehci_enable_event(ehci, EHCI_HRTIMER_ASYNC_UNLINKS, true);
|
||||
++ehci->async_unlink_cycle;
|
||||
}
|
||||
|
|
|
@ -213,7 +213,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask)
|
|||
}
|
||||
|
||||
static const unsigned char
|
||||
max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 };
|
||||
max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 };
|
||||
|
||||
/* carryover low/fullspeed bandwidth that crosses uframe boundries */
|
||||
static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
|
||||
|
@ -2212,11 +2212,11 @@ static void scan_isoc(struct ehci_hcd *ehci)
|
|||
}
|
||||
ehci->now_frame = now_frame;
|
||||
|
||||
frame = ehci->last_iso_frame;
|
||||
for (;;) {
|
||||
union ehci_shadow q, *q_p;
|
||||
__hc32 type, *hw_p;
|
||||
|
||||
frame = ehci->last_iso_frame;
|
||||
restart:
|
||||
/* scan each element in frame's queue for completions */
|
||||
q_p = &ehci->pshadow [frame];
|
||||
|
@ -2321,6 +2321,9 @@ restart:
|
|||
/* Stop when we have reached the current frame */
|
||||
if (frame == now_frame)
|
||||
break;
|
||||
ehci->last_iso_frame = (frame + 1) & fmask;
|
||||
|
||||
/* The last frame may still have active siTDs */
|
||||
ehci->last_iso_frame = frame;
|
||||
frame = (frame + 1) & fmask;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,14 +113,15 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci)
|
|||
|
||||
if (want != actual) {
|
||||
|
||||
/* Poll again later, but give up after about 20 ms */
|
||||
if (ehci->ASS_poll_count++ < 20) {
|
||||
ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
|
||||
return;
|
||||
}
|
||||
ehci_dbg(ehci, "Waited too long for the async schedule status (%x/%x), giving up\n",
|
||||
want, actual);
|
||||
/* Poll again later */
|
||||
ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
|
||||
++ehci->ASS_poll_count;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ehci->ASS_poll_count > 20)
|
||||
ehci_dbg(ehci, "ASS poll count reached %d\n",
|
||||
ehci->ASS_poll_count);
|
||||
ehci->ASS_poll_count = 0;
|
||||
|
||||
/* 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)
|
|||
|
||||
if (want != actual) {
|
||||
|
||||
/* Poll again later, but give up after about 20 ms */
|
||||
if (ehci->PSS_poll_count++ < 20) {
|
||||
ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
|
||||
return;
|
||||
}
|
||||
ehci_dbg(ehci, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
|
||||
want, actual);
|
||||
/* Poll again later */
|
||||
ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ehci->PSS_poll_count > 20)
|
||||
ehci_dbg(ehci, "PSS poll count reached %d\n",
|
||||
ehci->PSS_poll_count);
|
||||
ehci->PSS_poll_count = 0;
|
||||
|
||||
/* The status is up-to-date; restart or stop the schedule as needed */
|
||||
|
|
|
@ -780,6 +780,7 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)
|
|||
"defaulting to EHCI.\n");
|
||||
dev_warn(&xhci_pdev->dev,
|
||||
"USB 3.0 devices will work at USB 2.0 speeds.\n");
|
||||
usb_disable_xhci_ports(xhci_pdev);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,6 +116,7 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port,
|
|||
}
|
||||
}
|
||||
clear_bit(port, &uhci->resuming_ports);
|
||||
usb_hcd_end_port_resume(&uhci_to_hcd(uhci)->self, port);
|
||||
}
|
||||
|
||||
/* 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)
|
|||
set_bit(port, &uhci->resuming_ports);
|
||||
uhci->ports_timeout = jiffies +
|
||||
msecs_to_jiffies(25);
|
||||
usb_hcd_start_port_resume(
|
||||
&uhci_to_hcd(uhci)->self, port);
|
||||
|
||||
/* Make sure we see the port again
|
||||
* after the resuming period is over. */
|
||||
|
|
|
@ -1698,7 +1698,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
|
|||
faked_port_index + 1);
|
||||
if (slot_id && xhci->devs[slot_id])
|
||||
xhci_ring_device(xhci, slot_id);
|
||||
if (bus_state->port_remote_wakeup && (1 << faked_port_index)) {
|
||||
if (bus_state->port_remote_wakeup & (1 << faked_port_index)) {
|
||||
bus_state->port_remote_wakeup &=
|
||||
~(1 << faked_port_index);
|
||||
xhci_test_and_clear_bit(xhci, port_array,
|
||||
|
@ -2589,6 +2589,8 @@ cleanup:
|
|||
(trb_comp_code != COMP_STALL &&
|
||||
trb_comp_code != COMP_BABBLE))
|
||||
xhci_urb_free_priv(xhci, urb_priv);
|
||||
else
|
||||
kfree(urb_priv);
|
||||
|
||||
usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);
|
||||
if ((urb->actual_length != urb->transfer_buffer_length &&
|
||||
|
@ -3108,7 +3110,7 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
|
|||
* running_total.
|
||||
*/
|
||||
packets_transferred = (running_total + trb_buff_len) /
|
||||
usb_endpoint_maxp(&urb->ep->desc);
|
||||
GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
|
||||
|
||||
if ((total_packet_count - packets_transferred) > 31)
|
||||
return 31 << 17;
|
||||
|
@ -3642,7 +3644,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|||
td_len = urb->iso_frame_desc[i].length;
|
||||
td_remain_len = td_len;
|
||||
total_packet_count = DIV_ROUND_UP(td_len,
|
||||
usb_endpoint_maxp(&urb->ep->desc));
|
||||
GET_MAX_PACKET(
|
||||
usb_endpoint_maxp(&urb->ep->desc)));
|
||||
/* A zero-length transfer still involves at least one packet. */
|
||||
if (total_packet_count == 0)
|
||||
total_packet_count++;
|
||||
|
@ -3664,9 +3667,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|||
td = urb_priv->td[i];
|
||||
for (j = 0; j < trbs_per_td; j++) {
|
||||
u32 remainder = 0;
|
||||
field = TRB_TBC(burst_count) | TRB_TLBPC(residue);
|
||||
field = 0;
|
||||
|
||||
if (first_trb) {
|
||||
field = TRB_TBC(burst_count) |
|
||||
TRB_TLBPC(residue);
|
||||
/* Queue the isoc TRB */
|
||||
field |= TRB_TYPE(TRB_ISOC);
|
||||
/* Assume URB_ISO_ASAP is set */
|
||||
|
|
|
@ -60,6 +60,7 @@ static const struct usb_device_id id_table[] = {
|
|||
{ USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */
|
||||
{ USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */
|
||||
{ USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */
|
||||
{ USB_DEVICE(0x0FDE, 0xCA05) }, /* OWL Wireless Electricity Monitor CM-160 */
|
||||
{ USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */
|
||||
{ USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
|
||||
{ USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
|
||||
|
|
|
@ -584,6 +584,7 @@ static struct usb_device_id id_table_combined [] = {
|
|||
/*
|
||||
* ELV devices:
|
||||
*/
|
||||
{ USB_DEVICE(FTDI_ELV_VID, FTDI_ELV_WS300_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) },
|
||||
|
@ -670,6 +671,7 @@ static struct usb_device_id id_table_combined [] = {
|
|||
{ USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_OMNI1509) },
|
||||
{ USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_MHAM_KW_PID) },
|
||||
|
|
|
@ -147,6 +147,11 @@
|
|||
#define XSENS_CONVERTER_6_PID 0xD38E
|
||||
#define XSENS_CONVERTER_7_PID 0xD38F
|
||||
|
||||
/**
|
||||
* Zolix (www.zolix.com.cb) product ids
|
||||
*/
|
||||
#define FTDI_OMNI1509 0xD491 /* Omni1509 embedded USB-serial */
|
||||
|
||||
/*
|
||||
* NDI (www.ndigital.com) product ids
|
||||
*/
|
||||
|
@ -204,7 +209,7 @@
|
|||
|
||||
/*
|
||||
* ELV USB devices submitted by Christian Abt of ELV (www.elv.de).
|
||||
* All of these devices use FTDI's vendor ID (0x0403).
|
||||
* Almost all of these devices use FTDI's vendor ID (0x0403).
|
||||
* Further IDs taken from ELV Windows .inf file.
|
||||
*
|
||||
* The previously included PID for the UO 100 module was incorrect.
|
||||
|
@ -212,6 +217,8 @@
|
|||
*
|
||||
* Armin Laeuger originally sent the PID for the UM 100 module.
|
||||
*/
|
||||
#define FTDI_ELV_VID 0x1B1F /* ELV AG */
|
||||
#define FTDI_ELV_WS300_PID 0xC006 /* eQ3 WS 300 PC II */
|
||||
#define FTDI_ELV_USR_PID 0xE000 /* ELV Universal-Sound-Recorder */
|
||||
#define FTDI_ELV_MSM1_PID 0xE001 /* ELV Mini-Sound-Modul */
|
||||
#define FTDI_ELV_KL100_PID 0xE002 /* ELV Kfz-Leistungsmesser KL 100 */
|
||||
|
|
|
@ -242,6 +242,7 @@ static void option_instat_callback(struct urb *urb);
|
|||
#define TELIT_PRODUCT_CC864_DUAL 0x1005
|
||||
#define TELIT_PRODUCT_CC864_SINGLE 0x1006
|
||||
#define TELIT_PRODUCT_DE910_DUAL 0x1010
|
||||
#define TELIT_PRODUCT_LE920 0x1200
|
||||
|
||||
/* ZTE PRODUCTS */
|
||||
#define ZTE_VENDOR_ID 0x19d2
|
||||
|
@ -453,6 +454,10 @@ static void option_instat_callback(struct urb *urb);
|
|||
#define TPLINK_VENDOR_ID 0x2357
|
||||
#define TPLINK_PRODUCT_MA180 0x0201
|
||||
|
||||
/* Changhong products */
|
||||
#define CHANGHONG_VENDOR_ID 0x2077
|
||||
#define CHANGHONG_PRODUCT_CH690 0x7001
|
||||
|
||||
/* some devices interfaces need special handling due to a number of reasons */
|
||||
enum option_blacklist_reason {
|
||||
OPTION_BLACKLIST_NONE = 0,
|
||||
|
@ -534,6 +539,11 @@ static const struct option_blacklist_info zte_1255_blacklist = {
|
|||
.reserved = BIT(3) | BIT(4),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info telit_le920_blacklist = {
|
||||
.sendsetup = BIT(0),
|
||||
.reserved = BIT(1) | BIT(5),
|
||||
};
|
||||
|
||||
static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
|
||||
|
@ -784,6 +794,8 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
|
||||
.driver_info = (kernel_ulong_t)&telit_le920_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
|
||||
|
@ -1318,6 +1330,7 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) },
|
||||
{ USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, option_ids);
|
||||
|
|
|
@ -53,6 +53,7 @@ static const struct usb_device_id id_table[] = {
|
|||
{DEVICE_G1K(0x05c6, 0x9221)}, /* Generic Gobi QDL device */
|
||||
{DEVICE_G1K(0x05c6, 0x9231)}, /* Generic Gobi QDL device */
|
||||
{DEVICE_G1K(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */
|
||||
{DEVICE_G1K(0x1bc7, 0x900e)}, /* Telit Gobi QDL device */
|
||||
|
||||
/* Gobi 2000 devices */
|
||||
{USB_DEVICE(0x1410, 0xa010)}, /* Novatel Gobi 2000 QDL device */
|
||||
|
|
|
@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* This places the HUAWEI E220 devices in multi-port mode */
|
||||
int usb_stor_huawei_e220_init(struct us_data *us)
|
||||
/* This places the HUAWEI usb dongles in multi-port mode */
|
||||
static int usb_stor_huawei_feature_init(struct us_data *us)
|
||||
{
|
||||
int result;
|
||||
|
||||
|
@ -104,3 +104,75 @@ int usb_stor_huawei_e220_init(struct us_data *us)
|
|||
US_DEBUGP("Huawei mode set result is %d\n", result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* It will send a scsi switch command called rewind' to huawei dongle.
|
||||
* When the dongle receives this command at the first time,
|
||||
* it will reboot immediately. After rebooted, it will ignore this command.
|
||||
* So it is unnecessary to read its response.
|
||||
*/
|
||||
static int usb_stor_huawei_scsi_init(struct us_data *us)
|
||||
{
|
||||
int result = 0;
|
||||
int act_len = 0;
|
||||
struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf;
|
||||
char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN);
|
||||
bcbw->Tag = 0;
|
||||
bcbw->DataTransferLength = 0;
|
||||
bcbw->Flags = bcbw->Lun = 0;
|
||||
bcbw->Length = sizeof(rewind_cmd);
|
||||
memset(bcbw->CDB, 0, sizeof(bcbw->CDB));
|
||||
memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd));
|
||||
|
||||
result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw,
|
||||
US_BULK_CB_WRAP_LEN, &act_len);
|
||||
US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* It tries to find the supported Huawei USB dongles.
|
||||
* In Huawei, they assign the following product IDs
|
||||
* for all of their mobile broadband dongles,
|
||||
* including the new dongles in the future.
|
||||
* So if the product ID is not included in this list,
|
||||
* it means it is not Huawei's mobile broadband dongles.
|
||||
*/
|
||||
static int usb_stor_huawei_dongles_pid(struct us_data *us)
|
||||
{
|
||||
struct usb_interface_descriptor *idesc;
|
||||
int idProduct;
|
||||
|
||||
idesc = &us->pusb_intf->cur_altsetting->desc;
|
||||
idProduct = us->pusb_dev->descriptor.idProduct;
|
||||
/* The first port is CDROM,
|
||||
* means the dongle in the single port mode,
|
||||
* and a switch command is required to be sent. */
|
||||
if (idesc && idesc->bInterfaceNumber == 0) {
|
||||
if ((idProduct == 0x1001)
|
||||
|| (idProduct == 0x1003)
|
||||
|| (idProduct == 0x1004)
|
||||
|| (idProduct >= 0x1401 && idProduct <= 0x1500)
|
||||
|| (idProduct >= 0x1505 && idProduct <= 0x1600)
|
||||
|| (idProduct >= 0x1c02 && idProduct <= 0x2202)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_stor_huawei_init(struct us_data *us)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (usb_stor_huawei_dongles_pid(us)) {
|
||||
if (us->pusb_dev->descriptor.idProduct >= 0x1446)
|
||||
result = usb_stor_huawei_scsi_init(us);
|
||||
else
|
||||
result = usb_stor_huawei_feature_init(us);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us);
|
|||
* flash reader */
|
||||
int usb_stor_ucr61s2b_init(struct us_data *us);
|
||||
|
||||
/* This places the HUAWEI E220 devices in multi-port mode */
|
||||
int usb_stor_huawei_e220_init(struct us_data *us);
|
||||
/* This places the HUAWEI usb dongles in multi-port mode */
|
||||
int usb_stor_huawei_init(struct us_data *us);
|
||||
|
|
|
@ -1527,335 +1527,10 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100,
|
|||
/* Reported by fangxiaozhi <huananhu@huawei.com>
|
||||
* This brings the HUAWEI data card devices into multi-port mode
|
||||
*/
|
||||
UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000,
|
||||
UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1402, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1404, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1407, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x140A, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x140B, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x140C, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x140D, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x140E, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x140F, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x141A, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x141B, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x141C, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x141D, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x141E, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x141F, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1420, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1421, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1422, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1423, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1424, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1425, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1426, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1427, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1428, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1429, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x142A, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x142B, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x142C, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x142D, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x142E, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x142F, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1430, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1431, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1432, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1433, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1434, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1435, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1436, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1437, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1438, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x1439, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x143A, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x143B, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x143C, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x143D, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x143E, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
0),
|
||||
UNUSUAL_DEV( 0x12d1, 0x143F, 0x0000, 0x0000,
|
||||
"HUAWEI MOBILE",
|
||||
"Mass Storage",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init,
|
||||
0),
|
||||
|
||||
/* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
|
||||
|
|
|
@ -120,6 +120,17 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks");
|
|||
.useTransport = use_transport, \
|
||||
}
|
||||
|
||||
#define UNUSUAL_VENDOR_INTF(idVendor, cl, sc, pr, \
|
||||
vendor_name, product_name, use_protocol, use_transport, \
|
||||
init_function, Flags) \
|
||||
{ \
|
||||
.vendorName = vendor_name, \
|
||||
.productName = product_name, \
|
||||
.useProtocol = use_protocol, \
|
||||
.useTransport = use_transport, \
|
||||
.initFunction = init_function, \
|
||||
}
|
||||
|
||||
static struct us_unusual_dev us_unusual_dev_list[] = {
|
||||
# include "unusual_devs.h"
|
||||
{ } /* Terminating entry */
|
||||
|
@ -131,6 +142,7 @@ static struct us_unusual_dev for_dynamic_ids =
|
|||
#undef UNUSUAL_DEV
|
||||
#undef COMPLIANT_DEV
|
||||
#undef USUAL_DEV
|
||||
#undef UNUSUAL_VENDOR_INTF
|
||||
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
|
||||
|
|
|
@ -41,6 +41,20 @@
|
|||
#define USUAL_DEV(useProto, useTrans) \
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans) }
|
||||
|
||||
/* Define the device is matched with Vendor ID and interface descriptors */
|
||||
#define UNUSUAL_VENDOR_INTF(id_vendor, cl, sc, pr, \
|
||||
vendorName, productName, useProtocol, useTransport, \
|
||||
initFunction, flags) \
|
||||
{ \
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO \
|
||||
| USB_DEVICE_ID_MATCH_VENDOR, \
|
||||
.idVendor = (id_vendor), \
|
||||
.bInterfaceClass = (cl), \
|
||||
.bInterfaceSubClass = (sc), \
|
||||
.bInterfaceProtocol = (pr), \
|
||||
.driver_info = (flags) \
|
||||
}
|
||||
|
||||
struct usb_device_id usb_storage_usb_ids[] = {
|
||||
# include "unusual_devs.h"
|
||||
{ } /* Terminating entry */
|
||||
|
@ -50,6 +64,7 @@ MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids);
|
|||
#undef UNUSUAL_DEV
|
||||
#undef COMPLIANT_DEV
|
||||
#undef USUAL_DEV
|
||||
#undef UNUSUAL_VENDOR_INTF
|
||||
|
||||
/*
|
||||
* The table of devices to ignore
|
||||
|
|
|
@ -357,6 +357,8 @@ struct usb_bus {
|
|||
int bandwidth_int_reqs; /* number of Interrupt requests */
|
||||
int bandwidth_isoc_reqs; /* number of Isoc. requests */
|
||||
|
||||
unsigned resuming_ports; /* bit array: resuming root-hub ports */
|
||||
|
||||
#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
|
||||
struct mon_bus *mon_bus; /* non-null when associated */
|
||||
int monitored; /* non-zero when monitored */
|
||||
|
|
|
@ -430,6 +430,9 @@ extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
|
|||
extern void usb_wakeup_notification(struct usb_device *hdev,
|
||||
unsigned int portnum);
|
||||
|
||||
extern void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum);
|
||||
extern void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum);
|
||||
|
||||
/* 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)))
|
||||
|
|
|
@ -152,6 +152,12 @@
|
|||
#define USB_INTRF_FUNC_SUSPEND_LP (1 << (8 + 0))
|
||||
#define USB_INTRF_FUNC_SUSPEND_RW (1 << (8 + 1))
|
||||
|
||||
/*
|
||||
* Interface status, Figure 9-5 USB 3.0 spec
|
||||
*/
|
||||
#define USB_INTRF_STAT_FUNC_RW_CAP 1
|
||||
#define USB_INTRF_STAT_FUNC_RW 2
|
||||
|
||||
#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
|
||||
|
||||
/* Bit array elements as returned by the USB_REQ_GET_STATUS request. */
|
||||
|
|
Загрузка…
Ссылка в новой задаче