Commit c6d6b9d1 authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents c51aa6db 73228a05
...@@ -1287,9 +1287,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
/*
* Physical endpoints 0 and 1 are special; they form the
* bi-directional USB endpoint 0.
*
* 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); dwc3_free_trb_pool(dep);
if (epnum != 0 && epnum != 1)
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) ...@@ -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) ...@@ -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,10 +657,11 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh) ...@@ -653,10 +657,11 @@ 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 */
--ehci->intr_count; --ehci->intr_count;
......
...@@ -1827,6 +1827,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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 @@ void musb_host_tx(struct musb *musb, u8 epnum) ...@@ -1463,9 +1462,9 @@ void musb_host_tx(struct musb *musb, u8 epnum)
* 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 @@ void musb_host_tx(struct musb *musb, u8 epnum) ...@@ -1484,9 +1483,9 @@ void musb_host_tx(struct musb *musb, u8 epnum)
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) ...@@ -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) ...@@ -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 @@ void musb_host_rx(struct musb *musb, u8 epnum) ...@@ -1913,8 +1911,8 @@ void musb_host_rx(struct musb *musb, u8 epnum)
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 { ...@@ -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 @@ ...@@ -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[] = { ...@@ -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[] = { ...@@ -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[] = { ...@@ -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) ...@@ -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,6 +460,10 @@ static int cypress_generic_port_probe(struct usb_serial_port *port) ...@@ -448,6 +460,10 @@ static int cypress_generic_port_probe(struct usb_serial_port *port)
return -ENOMEM; return -ENOMEM;
} }
/* 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); usb_reset_configuration(serial->dev);
priv->cmd_ctrl = 0; priv->cmd_ctrl = 0;
......
...@@ -24,6 +24,10 @@ ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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,
MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT); 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) ...@@ -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) ...@@ -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;
buf = kzalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
if (buf) {
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data, MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT); 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); ...@@ -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 = { ...@@ -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[] = { ...@@ -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[] = { ...@@ -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[] = { ...@@ -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[] = { ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment