USB fixes for 3.10-rc4
Here are a number of USB bugfixes and new device ids for the 3.10-rc5 tree. Nothing major here, a number of new device ids (and movement from the option to the zte_ev driver of a number of ids that we had previously gotten wrong, some xhci bugfixes, some usb-serial driver fixes that were recently found, some host controller fixes / reverts, and a variety of smaller other things. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iEYEABECAAYFAlGwzXMACgkQMUfUDdst+ynKMgCgsM5KsOowmq6Xit8kTa5FNv9P kF8An2svAr8CdzEH8i6USghYKA2B1NhC =FAus -----END PGP SIGNATURE----- Merge tag 'usb-3.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb Pull USB fixes from Greg Kroah-Hartman: "Here are a number of USB bugfixes and new device ids for the 3.10-rc5 tree. Nothing major here, a number of new device ids (and movement from the option to the zte_ev driver of a number of ids that we had previously gotten wrong, some xhci bugfixes, some usb-serial driver fixes that were recently found, some host controller fixes / reverts, and a variety of smaller other things" * tag 'usb-3.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (29 commits) USB: option,zte_ev: move most ZTE CDMA devices to zte_ev USB: option: blacklist network interface on Huawei E1820 USB: whiteheat: fix broken port configuration USB: serial: fix TIOCMIWAIT return value USB: mos7720: fix hardware flow control USB: keyspan: remove unused endpoint-array access USB: keyspan: fix bogus array index USB: zte_ev: fix broken open USB: serial: Add Option GTM681W to qcserial device table. USB: Serial: cypress_M8: Enable FRWD Dongle hidcom device USB: EHCI: fix regression related to qh_refresh() usbfs: Increase arbitrary limit for USB 3 isopkt length USB: zte_ev: fix control-message timeouts USB: mos7720: fix message timeouts USB: iuu_phoenix: fix bulk-message timeout USB: ark3116: fix control-message timeout USB: mos7840: fix DMA to stack USB: mos7720: fix DMA to stack USB: visor: fix initialisation of Treo/Kyocera devices USB: serial: fix Treo/Kyocera interrrupt-in urb context ...
This commit is contained in:
commit
c6d6b9d149
24 changed files with 187 additions and 106 deletions
|
@ -1287,9 +1287,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
for (totlen = u = 0; u < uurb->number_of_packets; u++) {
|
for (totlen = u = 0; u < uurb->number_of_packets; u++) {
|
||||||
/* arbitrary limit,
|
/*
|
||||||
* sufficient for USB 2.0 high-bandwidth iso */
|
* arbitrary limit need for USB 3.0
|
||||||
if (isopkt[u].length > 8192) {
|
* bMaxBurst (0~15 allowed, 1~16 packets)
|
||||||
|
* bmAttributes (bit 1:0, mult 0~2, 1~3 packets)
|
||||||
|
* sizemax: 1024 * 16 * 3 = 49152
|
||||||
|
*/
|
||||||
|
if (isopkt[u].length > 49152) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,9 +164,9 @@ static int dwc3_exynos_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct dwc3_exynos *exynos = platform_get_drvdata(pdev);
|
struct dwc3_exynos *exynos = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child);
|
||||||
platform_device_unregister(exynos->usb2_phy);
|
platform_device_unregister(exynos->usb2_phy);
|
||||||
platform_device_unregister(exynos->usb3_phy);
|
platform_device_unregister(exynos->usb3_phy);
|
||||||
device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child);
|
|
||||||
|
|
||||||
clk_disable_unprepare(exynos->clk);
|
clk_disable_unprepare(exynos->clk);
|
||||||
|
|
||||||
|
|
|
@ -196,9 +196,9 @@ static void dwc3_pci_remove(struct pci_dev *pci)
|
||||||
{
|
{
|
||||||
struct dwc3_pci *glue = pci_get_drvdata(pci);
|
struct dwc3_pci *glue = pci_get_drvdata(pci);
|
||||||
|
|
||||||
|
platform_device_unregister(glue->dwc3);
|
||||||
platform_device_unregister(glue->usb2_phy);
|
platform_device_unregister(glue->usb2_phy);
|
||||||
platform_device_unregister(glue->usb3_phy);
|
platform_device_unregister(glue->usb3_phy);
|
||||||
platform_device_unregister(glue->dwc3);
|
|
||||||
pci_set_drvdata(pci, NULL);
|
pci_set_drvdata(pci, NULL);
|
||||||
pci_disable_device(pci);
|
pci_disable_device(pci);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1706,11 +1706,19 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc)
|
||||||
dep = dwc->eps[epnum];
|
dep = dwc->eps[epnum];
|
||||||
if (!dep)
|
if (!dep)
|
||||||
continue;
|
continue;
|
||||||
|
/*
|
||||||
dwc3_free_trb_pool(dep);
|
* Physical endpoints 0 and 1 are special; they form the
|
||||||
|
* bi-directional USB endpoint 0.
|
||||||
if (epnum != 0 && epnum != 1)
|
*
|
||||||
|
* For those two physical endpoints, we don't allocate a TRB
|
||||||
|
* pool nor do we add them the endpoints list. Due to that, we
|
||||||
|
* shouldn't do these two operations otherwise we would end up
|
||||||
|
* with all sorts of bugs when removing dwc3.ko.
|
||||||
|
*/
|
||||||
|
if (epnum != 0 && epnum != 1) {
|
||||||
|
dwc3_free_trb_pool(dep);
|
||||||
list_del(&dep->endpoint.ep_list);
|
list_del(&dep->endpoint.ep_list);
|
||||||
|
}
|
||||||
|
|
||||||
kfree(dep);
|
kfree(dep);
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,7 +213,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const unsigned char
|
static const unsigned char
|
||||||
max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 };
|
max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 };
|
||||||
|
|
||||||
/* carryover low/fullspeed bandwidth that crosses uframe boundries */
|
/* carryover low/fullspeed bandwidth that crosses uframe boundries */
|
||||||
static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
|
static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
|
||||||
|
@ -646,6 +646,10 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
|
||||||
/* reschedule QH iff another request is queued */
|
/* reschedule QH iff another request is queued */
|
||||||
if (!list_empty(&qh->qtd_list) && ehci->rh_state == EHCI_RH_RUNNING) {
|
if (!list_empty(&qh->qtd_list) && ehci->rh_state == EHCI_RH_RUNNING) {
|
||||||
rc = qh_schedule(ehci, qh);
|
rc = qh_schedule(ehci, qh);
|
||||||
|
if (rc == 0) {
|
||||||
|
qh_refresh(ehci, qh);
|
||||||
|
qh_link_periodic(ehci, qh);
|
||||||
|
}
|
||||||
|
|
||||||
/* An error here likely indicates handshake failure
|
/* An error here likely indicates handshake failure
|
||||||
* or no space left in the schedule. Neither fault
|
* or no space left in the schedule. Neither fault
|
||||||
|
@ -653,9 +657,10 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
|
||||||
*
|
*
|
||||||
* FIXME kill the now-dysfunctional queued urbs
|
* FIXME kill the now-dysfunctional queued urbs
|
||||||
*/
|
*/
|
||||||
if (rc != 0)
|
else {
|
||||||
ehci_err(ehci, "can't reschedule qh %p, err %d\n",
|
ehci_err(ehci, "can't reschedule qh %p, err %d\n",
|
||||||
qh, rc);
|
qh, rc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* maybe turn off periodic schedule */
|
/* maybe turn off periodic schedule */
|
||||||
|
|
|
@ -1827,6 +1827,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||||
|
|
||||||
|
if (!xhci->rh_bw)
|
||||||
|
goto no_bw;
|
||||||
|
|
||||||
num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
|
num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
|
||||||
for (i = 0; i < num_ports; i++) {
|
for (i = 0; i < num_ports; i++) {
|
||||||
struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
|
struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
|
||||||
|
@ -1845,6 +1848,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
no_bw:
|
||||||
xhci->num_usb2_ports = 0;
|
xhci->num_usb2_ports = 0;
|
||||||
xhci->num_usb3_ports = 0;
|
xhci->num_usb3_ports = 0;
|
||||||
xhci->num_active_eps = 0;
|
xhci->num_active_eps = 0;
|
||||||
|
@ -2256,6 +2260,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
|
||||||
u32 page_size, temp;
|
u32 page_size, temp;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&xhci->lpm_failed_devs);
|
||||||
|
INIT_LIST_HEAD(&xhci->cancel_cmd_list);
|
||||||
|
|
||||||
page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
|
page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
|
||||||
xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size);
|
xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size);
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
|
@ -2334,7 +2341,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
|
||||||
xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, flags);
|
xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, flags);
|
||||||
if (!xhci->cmd_ring)
|
if (!xhci->cmd_ring)
|
||||||
goto fail;
|
goto fail;
|
||||||
INIT_LIST_HEAD(&xhci->cancel_cmd_list);
|
|
||||||
xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring);
|
xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring);
|
||||||
xhci_dbg(xhci, "First segment DMA is 0x%llx\n",
|
xhci_dbg(xhci, "First segment DMA is 0x%llx\n",
|
||||||
(unsigned long long)xhci->cmd_ring->first_seg->dma);
|
(unsigned long long)xhci->cmd_ring->first_seg->dma);
|
||||||
|
@ -2445,8 +2451,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
|
||||||
if (xhci_setup_port_arrays(xhci, flags))
|
if (xhci_setup_port_arrays(xhci, flags))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&xhci->lpm_failed_devs);
|
|
||||||
|
|
||||||
/* Enable USB 3.0 device notifications for function remote wake, which
|
/* Enable USB 3.0 device notifications for function remote wake, which
|
||||||
* is necessary for allowing USB 3.0 devices to do remote wakeup from
|
* is necessary for allowing USB 3.0 devices to do remote wakeup from
|
||||||
* U3 (device suspend).
|
* U3 (device suspend).
|
||||||
|
|
|
@ -221,6 +221,14 @@ static void xhci_pci_remove(struct pci_dev *dev)
|
||||||
static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
|
static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
|
||||||
{
|
{
|
||||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||||
|
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Systems with the TI redriver that loses port status change events
|
||||||
|
* need to have the registers polled during D3, so avoid D3cold.
|
||||||
|
*/
|
||||||
|
if (xhci_compliance_mode_recovery_timer_quirk_check())
|
||||||
|
pdev->no_d3cold = true;
|
||||||
|
|
||||||
return xhci_suspend(xhci);
|
return xhci_suspend(xhci);
|
||||||
}
|
}
|
||||||
|
|
|
@ -466,7 +466,7 @@ static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci)
|
||||||
* Systems:
|
* Systems:
|
||||||
* Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820
|
* Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820
|
||||||
*/
|
*/
|
||||||
static bool compliance_mode_recovery_timer_quirk_check(void)
|
bool xhci_compliance_mode_recovery_timer_quirk_check(void)
|
||||||
{
|
{
|
||||||
const char *dmi_product_name, *dmi_sys_vendor;
|
const char *dmi_product_name, *dmi_sys_vendor;
|
||||||
|
|
||||||
|
@ -517,7 +517,7 @@ int xhci_init(struct usb_hcd *hcd)
|
||||||
xhci_dbg(xhci, "Finished xhci_init\n");
|
xhci_dbg(xhci, "Finished xhci_init\n");
|
||||||
|
|
||||||
/* Initializing Compliance Mode Recovery Data If Needed */
|
/* Initializing Compliance Mode Recovery Data If Needed */
|
||||||
if (compliance_mode_recovery_timer_quirk_check()) {
|
if (xhci_compliance_mode_recovery_timer_quirk_check()) {
|
||||||
xhci->quirks |= XHCI_COMP_MODE_QUIRK;
|
xhci->quirks |= XHCI_COMP_MODE_QUIRK;
|
||||||
compliance_mode_recovery_timer_init(xhci);
|
compliance_mode_recovery_timer_init(xhci);
|
||||||
}
|
}
|
||||||
|
@ -956,6 +956,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
||||||
struct usb_hcd *hcd = xhci_to_hcd(xhci);
|
struct usb_hcd *hcd = xhci_to_hcd(xhci);
|
||||||
struct usb_hcd *secondary_hcd;
|
struct usb_hcd *secondary_hcd;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
bool comp_timer_running = false;
|
||||||
|
|
||||||
/* Wait a bit if either of the roothubs need to settle from the
|
/* Wait a bit if either of the roothubs need to settle from the
|
||||||
* transition into bus suspend.
|
* transition into bus suspend.
|
||||||
|
@ -993,6 +994,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
||||||
|
|
||||||
/* If restore operation fails, re-initialize the HC during resume */
|
/* If restore operation fails, re-initialize the HC during resume */
|
||||||
if ((temp & STS_SRE) || hibernated) {
|
if ((temp & STS_SRE) || hibernated) {
|
||||||
|
|
||||||
|
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
|
||||||
|
!(xhci_all_ports_seen_u0(xhci))) {
|
||||||
|
del_timer_sync(&xhci->comp_mode_recovery_timer);
|
||||||
|
xhci_dbg(xhci, "Compliance Mode Recovery Timer deleted!\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Let the USB core know _both_ roothubs lost power. */
|
/* Let the USB core know _both_ roothubs lost power. */
|
||||||
usb_root_hub_lost_power(xhci->main_hcd->self.root_hub);
|
usb_root_hub_lost_power(xhci->main_hcd->self.root_hub);
|
||||||
usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub);
|
usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub);
|
||||||
|
@ -1035,6 +1043,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
||||||
retval = xhci_init(hcd->primary_hcd);
|
retval = xhci_init(hcd->primary_hcd);
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
return retval;
|
||||||
|
comp_timer_running = true;
|
||||||
|
|
||||||
xhci_dbg(xhci, "Start the primary HCD\n");
|
xhci_dbg(xhci, "Start the primary HCD\n");
|
||||||
retval = xhci_run(hcd->primary_hcd);
|
retval = xhci_run(hcd->primary_hcd);
|
||||||
if (!retval) {
|
if (!retval) {
|
||||||
|
@ -1076,7 +1086,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
||||||
* to suffer the Compliance Mode issue again. It doesn't matter if
|
* to suffer the Compliance Mode issue again. It doesn't matter if
|
||||||
* ports have entered previously to U0 before system's suspension.
|
* ports have entered previously to U0 before system's suspension.
|
||||||
*/
|
*/
|
||||||
if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
|
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running)
|
||||||
compliance_mode_recovery_timer_init(xhci);
|
compliance_mode_recovery_timer_init(xhci);
|
||||||
|
|
||||||
/* Re-enable port polling. */
|
/* Re-enable port polling. */
|
||||||
|
|
|
@ -1853,4 +1853,7 @@ struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci,
|
||||||
struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
|
struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
|
||||||
struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index);
|
struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index);
|
||||||
|
|
||||||
|
/* xHCI quirks */
|
||||||
|
bool xhci_compliance_mode_recovery_timer_quirk_check(void);
|
||||||
|
|
||||||
#endif /* __LINUX_XHCI_HCD_H */
|
#endif /* __LINUX_XHCI_HCD_H */
|
||||||
|
|
|
@ -1232,7 +1232,6 @@ void musb_host_tx(struct musb *musb, u8 epnum)
|
||||||
void __iomem *mbase = musb->mregs;
|
void __iomem *mbase = musb->mregs;
|
||||||
struct dma_channel *dma;
|
struct dma_channel *dma;
|
||||||
bool transfer_pending = false;
|
bool transfer_pending = false;
|
||||||
static bool use_sg;
|
|
||||||
|
|
||||||
musb_ep_select(mbase, epnum);
|
musb_ep_select(mbase, epnum);
|
||||||
tx_csr = musb_readw(epio, MUSB_TXCSR);
|
tx_csr = musb_readw(epio, MUSB_TXCSR);
|
||||||
|
@ -1463,9 +1462,9 @@ done:
|
||||||
* NULL.
|
* NULL.
|
||||||
*/
|
*/
|
||||||
if (!urb->transfer_buffer)
|
if (!urb->transfer_buffer)
|
||||||
use_sg = true;
|
qh->use_sg = true;
|
||||||
|
|
||||||
if (use_sg) {
|
if (qh->use_sg) {
|
||||||
/* sg_miter_start is already done in musb_ep_program */
|
/* sg_miter_start is already done in musb_ep_program */
|
||||||
if (!sg_miter_next(&qh->sg_miter)) {
|
if (!sg_miter_next(&qh->sg_miter)) {
|
||||||
dev_err(musb->controller, "error: sg list empty\n");
|
dev_err(musb->controller, "error: sg list empty\n");
|
||||||
|
@ -1484,9 +1483,9 @@ done:
|
||||||
|
|
||||||
qh->segsize = length;
|
qh->segsize = length;
|
||||||
|
|
||||||
if (use_sg) {
|
if (qh->use_sg) {
|
||||||
if (offset + length >= urb->transfer_buffer_length)
|
if (offset + length >= urb->transfer_buffer_length)
|
||||||
use_sg = false;
|
qh->use_sg = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
musb_ep_select(mbase, epnum);
|
musb_ep_select(mbase, epnum);
|
||||||
|
@ -1552,7 +1551,6 @@ void musb_host_rx(struct musb *musb, u8 epnum)
|
||||||
bool done = false;
|
bool done = false;
|
||||||
u32 status;
|
u32 status;
|
||||||
struct dma_channel *dma;
|
struct dma_channel *dma;
|
||||||
static bool use_sg;
|
|
||||||
unsigned int sg_flags = SG_MITER_ATOMIC | SG_MITER_TO_SG;
|
unsigned int sg_flags = SG_MITER_ATOMIC | SG_MITER_TO_SG;
|
||||||
|
|
||||||
musb_ep_select(mbase, epnum);
|
musb_ep_select(mbase, epnum);
|
||||||
|
@ -1878,12 +1876,12 @@ void musb_host_rx(struct musb *musb, u8 epnum)
|
||||||
* NULL.
|
* NULL.
|
||||||
*/
|
*/
|
||||||
if (!urb->transfer_buffer) {
|
if (!urb->transfer_buffer) {
|
||||||
use_sg = true;
|
qh->use_sg = true;
|
||||||
sg_miter_start(&qh->sg_miter, urb->sg, 1,
|
sg_miter_start(&qh->sg_miter, urb->sg, 1,
|
||||||
sg_flags);
|
sg_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_sg) {
|
if (qh->use_sg) {
|
||||||
if (!sg_miter_next(&qh->sg_miter)) {
|
if (!sg_miter_next(&qh->sg_miter)) {
|
||||||
dev_err(musb->controller, "error: sg list empty\n");
|
dev_err(musb->controller, "error: sg list empty\n");
|
||||||
sg_miter_stop(&qh->sg_miter);
|
sg_miter_stop(&qh->sg_miter);
|
||||||
|
@ -1913,8 +1911,8 @@ finish:
|
||||||
urb->actual_length += xfer_len;
|
urb->actual_length += xfer_len;
|
||||||
qh->offset += xfer_len;
|
qh->offset += xfer_len;
|
||||||
if (done) {
|
if (done) {
|
||||||
if (use_sg)
|
if (qh->use_sg)
|
||||||
use_sg = false;
|
qh->use_sg = false;
|
||||||
|
|
||||||
if (urb->status == -EINPROGRESS)
|
if (urb->status == -EINPROGRESS)
|
||||||
urb->status = status;
|
urb->status = status;
|
||||||
|
|
|
@ -74,6 +74,7 @@ struct musb_qh {
|
||||||
u16 frame; /* for periodic schedule */
|
u16 frame; /* for periodic schedule */
|
||||||
unsigned iso_idx; /* in urb->iso_frame_desc[] */
|
unsigned iso_idx; /* in urb->iso_frame_desc[] */
|
||||||
struct sg_mapping_iter sg_miter; /* for highmem in PIO mode */
|
struct sg_mapping_iter sg_miter; /* for highmem in PIO mode */
|
||||||
|
bool use_sg; /* to track urb using sglist */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* map from control or bulk queue head to the first qh on that ring */
|
/* map from control or bulk queue head to the first qh on that ring */
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#define DRIVER_NAME "ark3116"
|
#define DRIVER_NAME "ark3116"
|
||||||
|
|
||||||
/* usb timeout of 1 second */
|
/* usb timeout of 1 second */
|
||||||
#define ARK_TIMEOUT (1*HZ)
|
#define ARK_TIMEOUT 1000
|
||||||
|
|
||||||
static const struct usb_device_id id_table[] = {
|
static const struct usb_device_id id_table[] = {
|
||||||
{ USB_DEVICE(0x6547, 0x0232) },
|
{ USB_DEVICE(0x6547, 0x0232) },
|
||||||
|
|
|
@ -65,6 +65,7 @@ static const struct usb_device_id id_table_earthmate[] = {
|
||||||
static const struct usb_device_id id_table_cyphidcomrs232[] = {
|
static const struct usb_device_id id_table_cyphidcomrs232[] = {
|
||||||
{ USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
|
{ USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
|
||||||
{ USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
|
{ USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
|
||||||
|
{ USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) },
|
||||||
{ } /* Terminating entry */
|
{ } /* Terminating entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -78,6 +79,7 @@ static const struct usb_device_id id_table_combined[] = {
|
||||||
{ USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
|
{ USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
|
||||||
{ USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
|
{ USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
|
||||||
{ USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
|
{ USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
|
||||||
|
{ USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) },
|
||||||
{ USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) },
|
{ USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) },
|
||||||
{ } /* Terminating entry */
|
{ } /* Terminating entry */
|
||||||
};
|
};
|
||||||
|
@ -229,6 +231,12 @@ static struct usb_serial_driver * const serial_drivers[] = {
|
||||||
* Cypress serial helper functions
|
* Cypress serial helper functions
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/* FRWD Dongle hidcom needs to skip reset and speed checks */
|
||||||
|
static inline bool is_frwd(struct usb_device *dev)
|
||||||
|
{
|
||||||
|
return ((le16_to_cpu(dev->descriptor.idVendor) == VENDOR_ID_FRWD) &&
|
||||||
|
(le16_to_cpu(dev->descriptor.idProduct) == PRODUCT_ID_CYPHIDCOM_FRWD));
|
||||||
|
}
|
||||||
|
|
||||||
static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
|
static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
|
||||||
{
|
{
|
||||||
|
@ -238,6 +246,10 @@ static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
|
||||||
if (unstable_bauds)
|
if (unstable_bauds)
|
||||||
return new_rate;
|
return new_rate;
|
||||||
|
|
||||||
|
/* FRWD Dongle uses 115200 bps */
|
||||||
|
if (is_frwd(port->serial->dev))
|
||||||
|
return new_rate;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The general purpose firmware for the Cypress M8 allows for
|
* The general purpose firmware for the Cypress M8 allows for
|
||||||
* a maximum speed of 57600bps (I have no idea whether DeLorme
|
* a maximum speed of 57600bps (I have no idea whether DeLorme
|
||||||
|
@ -448,7 +460,11 @@ static int cypress_generic_port_probe(struct usb_serial_port *port)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_reset_configuration(serial->dev);
|
/* Skip reset for FRWD device. It is a workaound:
|
||||||
|
device hangs if it receives SET_CONFIGURE in Configured
|
||||||
|
state. */
|
||||||
|
if (!is_frwd(serial->dev))
|
||||||
|
usb_reset_configuration(serial->dev);
|
||||||
|
|
||||||
priv->cmd_ctrl = 0;
|
priv->cmd_ctrl = 0;
|
||||||
priv->line_control = 0;
|
priv->line_control = 0;
|
||||||
|
|
|
@ -24,6 +24,10 @@
|
||||||
#define VENDOR_ID_CYPRESS 0x04b4
|
#define VENDOR_ID_CYPRESS 0x04b4
|
||||||
#define PRODUCT_ID_CYPHIDCOM 0x5500
|
#define PRODUCT_ID_CYPHIDCOM 0x5500
|
||||||
|
|
||||||
|
/* FRWD Dongle - a GPS sports watch */
|
||||||
|
#define VENDOR_ID_FRWD 0x6737
|
||||||
|
#define PRODUCT_ID_CYPHIDCOM_FRWD 0x0001
|
||||||
|
|
||||||
/* Powercom UPS, chip CY7C63723 */
|
/* Powercom UPS, chip CY7C63723 */
|
||||||
#define VENDOR_ID_POWERCOM 0x0d9f
|
#define VENDOR_ID_POWERCOM 0x0d9f
|
||||||
#define PRODUCT_ID_UPS 0x0002
|
#define PRODUCT_ID_UPS 0x0002
|
||||||
|
|
|
@ -287,7 +287,7 @@ static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
|
||||||
usb_bulk_msg(serial->dev,
|
usb_bulk_msg(serial->dev,
|
||||||
usb_sndbulkpipe(serial->dev,
|
usb_sndbulkpipe(serial->dev,
|
||||||
port->bulk_out_endpointAddress), buf,
|
port->bulk_out_endpointAddress), buf,
|
||||||
count, &actual, HZ * 1);
|
count, &actual, 1000);
|
||||||
|
|
||||||
if (status != IUU_OPERATION_OK)
|
if (status != IUU_OPERATION_OK)
|
||||||
dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status);
|
dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status);
|
||||||
|
@ -307,7 +307,7 @@ static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
|
||||||
usb_bulk_msg(serial->dev,
|
usb_bulk_msg(serial->dev,
|
||||||
usb_rcvbulkpipe(serial->dev,
|
usb_rcvbulkpipe(serial->dev,
|
||||||
port->bulk_in_endpointAddress), buf,
|
port->bulk_in_endpointAddress), buf,
|
||||||
count, &actual, HZ * 1);
|
count, &actual, 1000);
|
||||||
|
|
||||||
if (status != IUU_OPERATION_OK)
|
if (status != IUU_OPERATION_OK)
|
||||||
dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status);
|
dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status);
|
||||||
|
|
|
@ -1548,7 +1548,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
|
||||||
struct keyspan_serial_private *s_priv;
|
struct keyspan_serial_private *s_priv;
|
||||||
struct keyspan_port_private *p_priv;
|
struct keyspan_port_private *p_priv;
|
||||||
const struct keyspan_device_details *d_details;
|
const struct keyspan_device_details *d_details;
|
||||||
int outcont_urb;
|
|
||||||
struct urb *this_urb;
|
struct urb *this_urb;
|
||||||
int device_port, err;
|
int device_port, err;
|
||||||
|
|
||||||
|
@ -1559,7 +1558,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
|
||||||
d_details = s_priv->device_details;
|
d_details = s_priv->device_details;
|
||||||
device_port = port->number - port->serial->minor;
|
device_port = port->number - port->serial->minor;
|
||||||
|
|
||||||
outcont_urb = d_details->outcont_endpoints[port->number];
|
|
||||||
this_urb = p_priv->outcont_urb;
|
this_urb = p_priv->outcont_urb;
|
||||||
|
|
||||||
dev_dbg(&port->dev, "%s - endpoint %d\n", __func__, usb_pipeendpoint(this_urb->pipe));
|
dev_dbg(&port->dev, "%s - endpoint %d\n", __func__, usb_pipeendpoint(this_urb->pipe));
|
||||||
|
@ -1685,14 +1683,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
|
||||||
err = usb_submit_urb(this_urb, GFP_ATOMIC);
|
err = usb_submit_urb(this_urb, GFP_ATOMIC);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed (%d)\n", __func__, err);
|
dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed (%d)\n", __func__, err);
|
||||||
#if 0
|
|
||||||
else {
|
|
||||||
dev_dbg(&port->dev, "%s - usb_submit_urb(%d) OK %d bytes (end %d)\n", __func__
|
|
||||||
outcont_urb, this_urb->transfer_buffer_length,
|
|
||||||
usb_pipeendpoint(this_urb->pipe));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#define DRIVER_DESC "Moschip USB Serial Driver"
|
#define DRIVER_DESC "Moschip USB Serial Driver"
|
||||||
|
|
||||||
/* default urb timeout */
|
/* default urb timeout */
|
||||||
#define MOS_WDR_TIMEOUT (HZ * 5)
|
#define MOS_WDR_TIMEOUT 5000
|
||||||
|
|
||||||
#define MOS_MAX_PORT 0x02
|
#define MOS_MAX_PORT 0x02
|
||||||
#define MOS_WRITE 0x0E
|
#define MOS_WRITE 0x0E
|
||||||
|
@ -227,11 +227,22 @@ static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum,
|
||||||
__u8 requesttype = (__u8)0xc0;
|
__u8 requesttype = (__u8)0xc0;
|
||||||
__u16 index = get_reg_index(reg);
|
__u16 index = get_reg_index(reg);
|
||||||
__u16 value = get_reg_value(reg, serial_portnum);
|
__u16 value = get_reg_value(reg, serial_portnum);
|
||||||
int status = usb_control_msg(usbdev, pipe, request, requesttype, value,
|
u8 *buf;
|
||||||
index, data, 1, MOS_WDR_TIMEOUT);
|
int status;
|
||||||
if (status < 0)
|
|
||||||
|
buf = kmalloc(1, GFP_KERNEL);
|
||||||
|
if (!buf)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
status = usb_control_msg(usbdev, pipe, request, requesttype, value,
|
||||||
|
index, buf, 1, MOS_WDR_TIMEOUT);
|
||||||
|
if (status == 1)
|
||||||
|
*data = *buf;
|
||||||
|
else if (status < 0)
|
||||||
dev_err(&usbdev->dev,
|
dev_err(&usbdev->dev,
|
||||||
"mos7720: usb_control_msg() failed: %d", status);
|
"mos7720: usb_control_msg() failed: %d", status);
|
||||||
|
kfree(buf);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1618,7 +1629,7 @@ static void change_port_settings(struct tty_struct *tty,
|
||||||
mos7720_port->shadowMCR |= (UART_MCR_XONANY);
|
mos7720_port->shadowMCR |= (UART_MCR_XONANY);
|
||||||
/* To set hardware flow control to the specified *
|
/* To set hardware flow control to the specified *
|
||||||
* serial port, in SP1/2_CONTROL_REG */
|
* serial port, in SP1/2_CONTROL_REG */
|
||||||
if (port->number)
|
if (port_number)
|
||||||
write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01);
|
write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01);
|
||||||
else
|
else
|
||||||
write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02);
|
write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02);
|
||||||
|
@ -1927,7 +1938,7 @@ static int mos7720_startup(struct usb_serial *serial)
|
||||||
|
|
||||||
/* setting configuration feature to one */
|
/* setting configuration feature to one */
|
||||||
usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
||||||
(__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ);
|
(__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000);
|
||||||
|
|
||||||
/* start the interrupt urb */
|
/* start the interrupt urb */
|
||||||
ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
|
ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
|
||||||
|
@ -1970,7 +1981,7 @@ static void mos7720_release(struct usb_serial *serial)
|
||||||
/* wait for synchronous usb calls to return */
|
/* wait for synchronous usb calls to return */
|
||||||
if (mos_parport->msg_pending)
|
if (mos_parport->msg_pending)
|
||||||
wait_for_completion_timeout(&mos_parport->syncmsg_compl,
|
wait_for_completion_timeout(&mos_parport->syncmsg_compl,
|
||||||
MOS_WDR_TIMEOUT);
|
msecs_to_jiffies(MOS_WDR_TIMEOUT));
|
||||||
|
|
||||||
parport_remove_port(mos_parport->pp);
|
parport_remove_port(mos_parport->pp);
|
||||||
usb_set_serial_data(serial, NULL);
|
usb_set_serial_data(serial, NULL);
|
||||||
|
|
|
@ -2142,13 +2142,21 @@ static int mos7840_ioctl(struct tty_struct *tty,
|
||||||
static int mos7810_check(struct usb_serial *serial)
|
static int mos7810_check(struct usb_serial *serial)
|
||||||
{
|
{
|
||||||
int i, pass_count = 0;
|
int i, pass_count = 0;
|
||||||
|
u8 *buf;
|
||||||
__u16 data = 0, mcr_data = 0;
|
__u16 data = 0, mcr_data = 0;
|
||||||
__u16 test_pattern = 0x55AA;
|
__u16 test_pattern = 0x55AA;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
|
||||||
|
if (!buf)
|
||||||
|
return 0; /* failed to identify 7810 */
|
||||||
|
|
||||||
/* Store MCR setting */
|
/* Store MCR setting */
|
||||||
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
||||||
MCS_RDREQ, MCS_RD_RTYPE, 0x0300, MODEM_CONTROL_REGISTER,
|
MCS_RDREQ, MCS_RD_RTYPE, 0x0300, MODEM_CONTROL_REGISTER,
|
||||||
&mcr_data, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
buf, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
||||||
|
if (res == VENDOR_READ_LENGTH)
|
||||||
|
mcr_data = *buf;
|
||||||
|
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
/* Send the 1-bit test pattern out to MCS7810 test pin */
|
/* Send the 1-bit test pattern out to MCS7810 test pin */
|
||||||
|
@ -2158,9 +2166,12 @@ static int mos7810_check(struct usb_serial *serial)
|
||||||
MODEM_CONTROL_REGISTER, NULL, 0, MOS_WDR_TIMEOUT);
|
MODEM_CONTROL_REGISTER, NULL, 0, MOS_WDR_TIMEOUT);
|
||||||
|
|
||||||
/* Read the test pattern back */
|
/* Read the test pattern back */
|
||||||
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
res = usb_control_msg(serial->dev,
|
||||||
MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
|
usb_rcvctrlpipe(serial->dev, 0), MCS_RDREQ,
|
||||||
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
|
||||||
|
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
||||||
|
if (res == VENDOR_READ_LENGTH)
|
||||||
|
data = *buf;
|
||||||
|
|
||||||
/* If this is a MCS7810 device, both test patterns must match */
|
/* If this is a MCS7810 device, both test patterns must match */
|
||||||
if (((test_pattern >> i) ^ (~data >> 1)) & 0x0001)
|
if (((test_pattern >> i) ^ (~data >> 1)) & 0x0001)
|
||||||
|
@ -2174,6 +2185,8 @@ static int mos7810_check(struct usb_serial *serial)
|
||||||
MCS_WR_RTYPE, 0x0300 | mcr_data, MODEM_CONTROL_REGISTER, NULL,
|
MCS_WR_RTYPE, 0x0300 | mcr_data, MODEM_CONTROL_REGISTER, NULL,
|
||||||
0, MOS_WDR_TIMEOUT);
|
0, MOS_WDR_TIMEOUT);
|
||||||
|
|
||||||
|
kfree(buf);
|
||||||
|
|
||||||
if (pass_count == 16)
|
if (pass_count == 16)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -2183,11 +2196,17 @@ static int mos7810_check(struct usb_serial *serial)
|
||||||
static int mos7840_calc_num_ports(struct usb_serial *serial)
|
static int mos7840_calc_num_ports(struct usb_serial *serial)
|
||||||
{
|
{
|
||||||
__u16 data = 0x00;
|
__u16 data = 0x00;
|
||||||
|
u8 *buf;
|
||||||
int mos7840_num_ports;
|
int mos7840_num_ports;
|
||||||
|
|
||||||
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
buf = kzalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
|
||||||
MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
|
if (buf) {
|
||||||
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
||||||
|
MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
|
||||||
|
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
||||||
|
data = *buf;
|
||||||
|
kfree(buf);
|
||||||
|
}
|
||||||
|
|
||||||
if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 ||
|
if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 ||
|
||||||
serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) {
|
serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) {
|
||||||
|
|
|
@ -250,13 +250,7 @@ static void option_instat_callback(struct urb *urb);
|
||||||
#define ZTE_PRODUCT_MF622 0x0001
|
#define ZTE_PRODUCT_MF622 0x0001
|
||||||
#define ZTE_PRODUCT_MF628 0x0015
|
#define ZTE_PRODUCT_MF628 0x0015
|
||||||
#define ZTE_PRODUCT_MF626 0x0031
|
#define ZTE_PRODUCT_MF626 0x0031
|
||||||
#define ZTE_PRODUCT_CDMA_TECH 0xfffe
|
|
||||||
#define ZTE_PRODUCT_AC8710 0xfff1
|
|
||||||
#define ZTE_PRODUCT_AC2726 0xfff5
|
|
||||||
#define ZTE_PRODUCT_AC8710T 0xffff
|
|
||||||
#define ZTE_PRODUCT_MC2718 0xffe8
|
#define ZTE_PRODUCT_MC2718 0xffe8
|
||||||
#define ZTE_PRODUCT_AD3812 0xffeb
|
|
||||||
#define ZTE_PRODUCT_MC2716 0xffed
|
|
||||||
|
|
||||||
#define BENQ_VENDOR_ID 0x04a5
|
#define BENQ_VENDOR_ID 0x04a5
|
||||||
#define BENQ_PRODUCT_H10 0x4068
|
#define BENQ_PRODUCT_H10 0x4068
|
||||||
|
@ -495,18 +489,10 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = {
|
||||||
.reserved = BIT(4),
|
.reserved = BIT(4),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option_blacklist_info zte_ad3812_z_blacklist = {
|
|
||||||
.sendsetup = BIT(0) | BIT(1) | BIT(2),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct option_blacklist_info zte_mc2718_z_blacklist = {
|
static const struct option_blacklist_info zte_mc2718_z_blacklist = {
|
||||||
.sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4),
|
.sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option_blacklist_info zte_mc2716_z_blacklist = {
|
|
||||||
.sendsetup = BIT(1) | BIT(2) | BIT(3),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct option_blacklist_info huawei_cdc12_blacklist = {
|
static const struct option_blacklist_info huawei_cdc12_blacklist = {
|
||||||
.reserved = BIT(1) | BIT(2),
|
.reserved = BIT(1) | BIT(2),
|
||||||
};
|
};
|
||||||
|
@ -593,6 +579,8 @@ static const struct usb_device_id option_ids[] = {
|
||||||
.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
|
.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
|
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
|
||||||
.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
|
.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x14ac, 0xff, 0xff, 0xff), /* Huawei E1820 */
|
||||||
|
.driver_info = (kernel_ulong_t) &net_intf1_blacklist },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff),
|
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff),
|
||||||
.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
|
.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
|
||||||
{ USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) },
|
{ USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) },
|
||||||
|
@ -797,7 +785,6 @@ static const struct usb_device_id option_ids[] = {
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012, 0xff) },
|
{ USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012, 0xff) },
|
||||||
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) },
|
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) },
|
||||||
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
|
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
|
||||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
|
|
||||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
|
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
|
||||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
|
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
|
||||||
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
|
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
|
||||||
|
@ -1199,16 +1186,9 @@ static const struct usb_device_id option_ids[] = {
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff),
|
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff),
|
||||||
.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
|
.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
|
||||||
|
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
|
/* NOTE: most ZTE CDMA devices should be driven by zte_ev, not option */
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
|
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
|
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) },
|
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff),
|
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff),
|
||||||
.driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist },
|
.driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff),
|
|
||||||
.driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist },
|
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff),
|
|
||||||
.driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist },
|
|
||||||
{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) },
|
{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) },
|
||||||
{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) },
|
{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) },
|
||||||
{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) },
|
{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) },
|
||||||
|
|
|
@ -118,6 +118,7 @@ static const struct usb_device_id id_table[] = {
|
||||||
{USB_DEVICE(0x1199, 0x901b)}, /* Sierra Wireless MC7770 */
|
{USB_DEVICE(0x1199, 0x901b)}, /* Sierra Wireless MC7770 */
|
||||||
{USB_DEVICE(0x12D1, 0x14F0)}, /* Sony Gobi 3000 QDL */
|
{USB_DEVICE(0x12D1, 0x14F0)}, /* Sony Gobi 3000 QDL */
|
||||||
{USB_DEVICE(0x12D1, 0x14F1)}, /* Sony Gobi 3000 Composite */
|
{USB_DEVICE(0x12D1, 0x14F1)}, /* Sony Gobi 3000 Composite */
|
||||||
|
{USB_DEVICE(0x0AF0, 0x8120)}, /* Option GTM681W */
|
||||||
|
|
||||||
/* non Gobi Qualcomm serial devices */
|
/* non Gobi Qualcomm serial devices */
|
||||||
{USB_DEVICE_INTERFACE_NUMBER(0x0f3d, 0x68a2, 0)}, /* Sierra Wireless MC7700 Device Management */
|
{USB_DEVICE_INTERFACE_NUMBER(0x0f3d, 0x68a2, 0)}, /* Sierra Wireless MC7700 Device Management */
|
||||||
|
|
|
@ -408,7 +408,7 @@ static int serial_ioctl(struct tty_struct *tty,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
struct usb_serial_port *port = tty->driver_data;
|
struct usb_serial_port *port = tty->driver_data;
|
||||||
int retval = -ENODEV;
|
int retval = -ENOIOCTLCMD;
|
||||||
|
|
||||||
dev_dbg(tty->dev, "%s - cmd 0x%.4x\n", __func__, cmd);
|
dev_dbg(tty->dev, "%s - cmd 0x%.4x\n", __func__, cmd);
|
||||||
|
|
||||||
|
@ -420,8 +420,6 @@ static int serial_ioctl(struct tty_struct *tty,
|
||||||
default:
|
default:
|
||||||
if (port->serial->type->ioctl)
|
if (port->serial->type->ioctl)
|
||||||
retval = port->serial->type->ioctl(tty, cmd, arg);
|
retval = port->serial->type->ioctl(tty, cmd, arg);
|
||||||
else
|
|
||||||
retval = -ENOIOCTLCMD;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -560,10 +560,19 @@ static int treo_attach(struct usb_serial *serial)
|
||||||
*/
|
*/
|
||||||
#define COPY_PORT(dest, src) \
|
#define COPY_PORT(dest, src) \
|
||||||
do { \
|
do { \
|
||||||
|
int i; \
|
||||||
|
\
|
||||||
|
for (i = 0; i < ARRAY_SIZE(src->read_urbs); ++i) { \
|
||||||
|
dest->read_urbs[i] = src->read_urbs[i]; \
|
||||||
|
dest->read_urbs[i]->context = dest; \
|
||||||
|
dest->bulk_in_buffers[i] = src->bulk_in_buffers[i]; \
|
||||||
|
} \
|
||||||
dest->read_urb = src->read_urb; \
|
dest->read_urb = src->read_urb; \
|
||||||
dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\
|
dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\
|
||||||
dest->bulk_in_buffer = src->bulk_in_buffer; \
|
dest->bulk_in_buffer = src->bulk_in_buffer; \
|
||||||
|
dest->bulk_in_size = src->bulk_in_size; \
|
||||||
dest->interrupt_in_urb = src->interrupt_in_urb; \
|
dest->interrupt_in_urb = src->interrupt_in_urb; \
|
||||||
|
dest->interrupt_in_urb->context = dest; \
|
||||||
dest->interrupt_in_endpointAddress = \
|
dest->interrupt_in_endpointAddress = \
|
||||||
src->interrupt_in_endpointAddress;\
|
src->interrupt_in_endpointAddress;\
|
||||||
dest->interrupt_in_buffer = src->interrupt_in_buffer; \
|
dest->interrupt_in_buffer = src->interrupt_in_buffer; \
|
||||||
|
|
|
@ -649,7 +649,7 @@ static void firm_setup_port(struct tty_struct *tty)
|
||||||
struct whiteheat_port_settings port_settings;
|
struct whiteheat_port_settings port_settings;
|
||||||
unsigned int cflag = tty->termios.c_cflag;
|
unsigned int cflag = tty->termios.c_cflag;
|
||||||
|
|
||||||
port_settings.port = port->number + 1;
|
port_settings.port = port->number - port->serial->minor + 1;
|
||||||
|
|
||||||
/* get the byte size */
|
/* get the byte size */
|
||||||
switch (cflag & CSIZE) {
|
switch (cflag & CSIZE) {
|
||||||
|
|
|
@ -41,9 +41,6 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
|
||||||
int len;
|
int len;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
|
|
||||||
if (port->number != 0)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);
|
buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -53,7 +50,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
|
||||||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||||
0x22, 0x21,
|
0x22, 0x21,
|
||||||
0x0001, 0x0000, NULL, len,
|
0x0001, 0x0000, NULL, len,
|
||||||
HZ * USB_CTRL_GET_TIMEOUT);
|
USB_CTRL_GET_TIMEOUT);
|
||||||
dev_dbg(dev, "result = %d\n", result);
|
dev_dbg(dev, "result = %d\n", result);
|
||||||
|
|
||||||
/* send 2st cmd and recieve data */
|
/* send 2st cmd and recieve data */
|
||||||
|
@ -65,7 +62,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
|
||||||
result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
||||||
0x21, 0xa1,
|
0x21, 0xa1,
|
||||||
0x0000, 0x0000, buf, len,
|
0x0000, 0x0000, buf, len,
|
||||||
HZ * USB_CTRL_GET_TIMEOUT);
|
USB_CTRL_GET_TIMEOUT);
|
||||||
debug_data(dev, __func__, len, buf, result);
|
debug_data(dev, __func__, len, buf, result);
|
||||||
|
|
||||||
/* send 3 cmd */
|
/* send 3 cmd */
|
||||||
|
@ -84,7 +81,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
|
||||||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||||
0x20, 0x21,
|
0x20, 0x21,
|
||||||
0x0000, 0x0000, buf, len,
|
0x0000, 0x0000, buf, len,
|
||||||
HZ * USB_CTRL_GET_TIMEOUT);
|
USB_CTRL_GET_TIMEOUT);
|
||||||
debug_data(dev, __func__, len, buf, result);
|
debug_data(dev, __func__, len, buf, result);
|
||||||
|
|
||||||
/* send 4 cmd */
|
/* send 4 cmd */
|
||||||
|
@ -95,7 +92,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
|
||||||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||||
0x22, 0x21,
|
0x22, 0x21,
|
||||||
0x0003, 0x0000, NULL, len,
|
0x0003, 0x0000, NULL, len,
|
||||||
HZ * USB_CTRL_GET_TIMEOUT);
|
USB_CTRL_GET_TIMEOUT);
|
||||||
dev_dbg(dev, "result = %d\n", result);
|
dev_dbg(dev, "result = %d\n", result);
|
||||||
|
|
||||||
/* send 5 cmd */
|
/* send 5 cmd */
|
||||||
|
@ -107,7 +104,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
|
||||||
result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
||||||
0x21, 0xa1,
|
0x21, 0xa1,
|
||||||
0x0000, 0x0000, buf, len,
|
0x0000, 0x0000, buf, len,
|
||||||
HZ * USB_CTRL_GET_TIMEOUT);
|
USB_CTRL_GET_TIMEOUT);
|
||||||
debug_data(dev, __func__, len, buf, result);
|
debug_data(dev, __func__, len, buf, result);
|
||||||
|
|
||||||
/* send 6 cmd */
|
/* send 6 cmd */
|
||||||
|
@ -126,7 +123,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
|
||||||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||||
0x20, 0x21,
|
0x20, 0x21,
|
||||||
0x0000, 0x0000, buf, len,
|
0x0000, 0x0000, buf, len,
|
||||||
HZ * USB_CTRL_GET_TIMEOUT);
|
USB_CTRL_GET_TIMEOUT);
|
||||||
debug_data(dev, __func__, len, buf, result);
|
debug_data(dev, __func__, len, buf, result);
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
|
|
||||||
|
@ -166,9 +163,6 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
||||||
int len;
|
int len;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
|
|
||||||
if (port->number != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);
|
buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return;
|
return;
|
||||||
|
@ -178,7 +172,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
||||||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||||
0x22, 0x21,
|
0x22, 0x21,
|
||||||
0x0002, 0x0000, NULL, len,
|
0x0002, 0x0000, NULL, len,
|
||||||
HZ * USB_CTRL_GET_TIMEOUT);
|
USB_CTRL_GET_TIMEOUT);
|
||||||
dev_dbg(dev, "result = %d\n", result);
|
dev_dbg(dev, "result = %d\n", result);
|
||||||
|
|
||||||
/* send 2st ctl cmd(CTL 21 22 03 00 00 00 00 00 ) */
|
/* send 2st ctl cmd(CTL 21 22 03 00 00 00 00 00 ) */
|
||||||
|
@ -186,7 +180,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
||||||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||||
0x22, 0x21,
|
0x22, 0x21,
|
||||||
0x0003, 0x0000, NULL, len,
|
0x0003, 0x0000, NULL, len,
|
||||||
HZ * USB_CTRL_GET_TIMEOUT);
|
USB_CTRL_GET_TIMEOUT);
|
||||||
dev_dbg(dev, "result = %d\n", result);
|
dev_dbg(dev, "result = %d\n", result);
|
||||||
|
|
||||||
/* send 3st cmd and recieve data */
|
/* send 3st cmd and recieve data */
|
||||||
|
@ -198,7 +192,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
||||||
result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
||||||
0x21, 0xa1,
|
0x21, 0xa1,
|
||||||
0x0000, 0x0000, buf, len,
|
0x0000, 0x0000, buf, len,
|
||||||
HZ * USB_CTRL_GET_TIMEOUT);
|
USB_CTRL_GET_TIMEOUT);
|
||||||
debug_data(dev, __func__, len, buf, result);
|
debug_data(dev, __func__, len, buf, result);
|
||||||
|
|
||||||
/* send 4 cmd */
|
/* send 4 cmd */
|
||||||
|
@ -217,7 +211,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
||||||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||||
0x20, 0x21,
|
0x20, 0x21,
|
||||||
0x0000, 0x0000, buf, len,
|
0x0000, 0x0000, buf, len,
|
||||||
HZ * USB_CTRL_GET_TIMEOUT);
|
USB_CTRL_GET_TIMEOUT);
|
||||||
debug_data(dev, __func__, len, buf, result);
|
debug_data(dev, __func__, len, buf, result);
|
||||||
|
|
||||||
/* send 5 cmd */
|
/* send 5 cmd */
|
||||||
|
@ -228,7 +222,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
||||||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||||
0x22, 0x21,
|
0x22, 0x21,
|
||||||
0x0003, 0x0000, NULL, len,
|
0x0003, 0x0000, NULL, len,
|
||||||
HZ * USB_CTRL_GET_TIMEOUT);
|
USB_CTRL_GET_TIMEOUT);
|
||||||
dev_dbg(dev, "result = %d\n", result);
|
dev_dbg(dev, "result = %d\n", result);
|
||||||
|
|
||||||
/* send 6 cmd */
|
/* send 6 cmd */
|
||||||
|
@ -240,7 +234,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
||||||
result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
||||||
0x21, 0xa1,
|
0x21, 0xa1,
|
||||||
0x0000, 0x0000, buf, len,
|
0x0000, 0x0000, buf, len,
|
||||||
HZ * USB_CTRL_GET_TIMEOUT);
|
USB_CTRL_GET_TIMEOUT);
|
||||||
debug_data(dev, __func__, len, buf, result);
|
debug_data(dev, __func__, len, buf, result);
|
||||||
|
|
||||||
/* send 7 cmd */
|
/* send 7 cmd */
|
||||||
|
@ -259,7 +253,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
||||||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||||
0x20, 0x21,
|
0x20, 0x21,
|
||||||
0x0000, 0x0000, buf, len,
|
0x0000, 0x0000, buf, len,
|
||||||
HZ * USB_CTRL_GET_TIMEOUT);
|
USB_CTRL_GET_TIMEOUT);
|
||||||
debug_data(dev, __func__, len, buf, result);
|
debug_data(dev, __func__, len, buf, result);
|
||||||
|
|
||||||
/* send 8 cmd */
|
/* send 8 cmd */
|
||||||
|
@ -270,7 +264,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
||||||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||||
0x22, 0x21,
|
0x22, 0x21,
|
||||||
0x0003, 0x0000, NULL, len,
|
0x0003, 0x0000, NULL, len,
|
||||||
HZ * USB_CTRL_GET_TIMEOUT);
|
USB_CTRL_GET_TIMEOUT);
|
||||||
dev_dbg(dev, "result = %d\n", result);
|
dev_dbg(dev, "result = %d\n", result);
|
||||||
|
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
|
@ -279,11 +273,29 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct usb_device_id id_table[] = {
|
static const struct usb_device_id id_table[] = {
|
||||||
{ USB_DEVICE(0x19d2, 0xffff) }, /* AC8700 */
|
/* AC8710, AC8710T */
|
||||||
{ USB_DEVICE(0x19d2, 0xfffe) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffff, 0xff, 0xff, 0xff) },
|
||||||
{ USB_DEVICE(0x19d2, 0xfffd) }, /* MG880 */
|
/* AC8700 */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfffe, 0xff, 0xff, 0xff) },
|
||||||
|
/* MG880 */
|
||||||
|
{ USB_DEVICE(0x19d2, 0xfffd) },
|
||||||
|
{ USB_DEVICE(0x19d2, 0xfffc) },
|
||||||
|
{ USB_DEVICE(0x19d2, 0xfffb) },
|
||||||
|
/* AC2726, AC8710_V3 */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfff1, 0xff, 0xff, 0xff) },
|
||||||
|
{ USB_DEVICE(0x19d2, 0xfff6) },
|
||||||
|
{ USB_DEVICE(0x19d2, 0xfff7) },
|
||||||
|
{ USB_DEVICE(0x19d2, 0xfff8) },
|
||||||
|
{ USB_DEVICE(0x19d2, 0xfff9) },
|
||||||
|
{ USB_DEVICE(0x19d2, 0xffee) },
|
||||||
|
/* AC2716, MC2716 */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffed, 0xff, 0xff, 0xff) },
|
||||||
|
/* AD3812 */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffeb, 0xff, 0xff, 0xff) },
|
||||||
|
{ USB_DEVICE(0x19d2, 0xffec) },
|
||||||
{ USB_DEVICE(0x05C6, 0x3197) },
|
{ USB_DEVICE(0x05C6, 0x3197) },
|
||||||
{ USB_DEVICE(0x05C6, 0x6000) },
|
{ USB_DEVICE(0x05C6, 0x6000) },
|
||||||
|
{ USB_DEVICE(0x05C6, 0x9008) },
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(usb, id_table);
|
MODULE_DEVICE_TABLE(usb, id_table);
|
||||||
|
|
Loading…
Add table
Reference in a new issue