Skip to content

Commit

Permalink
Merge tag 'usb-3.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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
  ...
  • Loading branch information
Linus Torvalds committed Jun 6, 2013
2 parents c51aa6d + 73228a0 commit c6d6b9d
Show file tree
Hide file tree
Showing 24 changed files with 187 additions and 106 deletions.
10 changes: 7 additions & 3 deletions drivers/usb/core/devio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1287,9 +1287,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
goto error;
}
for (totlen = u = 0; u < uurb->number_of_packets; u++) {
/* arbitrary limit,
* sufficient for USB 2.0 high-bandwidth iso */
if (isopkt[u].length > 8192) {
/*
* arbitrary limit need for USB 3.0
* 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;
goto error;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/dwc3/dwc3-exynos.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,9 @@ static int dwc3_exynos_remove(struct platform_device *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->usb3_phy);
device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child);

clk_disable_unprepare(exynos->clk);

Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/dwc3/dwc3-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@ static void dwc3_pci_remove(struct pci_dev *pci)
{
struct dwc3_pci *glue = pci_get_drvdata(pci);

platform_device_unregister(glue->dwc3);
platform_device_unregister(glue->usb2_phy);
platform_device_unregister(glue->usb3_phy);
platform_device_unregister(glue->dwc3);
pci_set_drvdata(pci, NULL);
pci_disable_device(pci);
}
Expand Down
16 changes: 12 additions & 4 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -1706,11 +1706,19 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc)
dep = dwc->eps[epnum];
if (!dep)
continue;

dwc3_free_trb_pool(dep);

if (epnum != 0 && epnum != 1)
/*
* 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);
list_del(&dep->endpoint.ep_list);
}

kfree(dep);
}
Expand Down
9 changes: 7 additions & 2 deletions drivers/usb/host/ehci-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask)
}

static const unsigned char
max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 };
max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 };

/* carryover low/fullspeed bandwidth that crosses uframe boundries */
static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
Expand Down Expand Up @@ -646,16 +646,21 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
/* reschedule QH iff another request is queued */
if (!list_empty(&qh->qtd_list) && ehci->rh_state == EHCI_RH_RUNNING) {
rc = qh_schedule(ehci, qh);
if (rc == 0) {
qh_refresh(ehci, qh);
qh_link_periodic(ehci, qh);
}

/* An error here likely indicates handshake failure
* or no space left in the schedule. Neither fault
* should happen often ...
*
* FIXME kill the now-dysfunctional queued urbs
*/
if (rc != 0)
else {
ehci_err(ehci, "can't reschedule qh %p, err %d\n",
qh, rc);
}
}

/* maybe turn off periodic schedule */
Expand Down
10 changes: 7 additions & 3 deletions drivers/usb/host/xhci-mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1827,6 +1827,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
}
spin_unlock_irqrestore(&xhci->lock, flags);

if (!xhci->rh_bw)
goto no_bw;

num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
for (i = 0; i < num_ports; i++) {
struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
Expand All @@ -1845,6 +1848,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
}
}

no_bw:
xhci->num_usb2_ports = 0;
xhci->num_usb3_ports = 0;
xhci->num_active_eps = 0;
Expand Down Expand Up @@ -2256,6 +2260,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
u32 page_size, temp;
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);
xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size);
for (i = 0; i < 16; i++) {
Expand Down Expand Up @@ -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);
if (!xhci->cmd_ring)
goto fail;
INIT_LIST_HEAD(&xhci->cancel_cmd_list);
xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring);
xhci_dbg(xhci, "First segment DMA is 0x%llx\n",
(unsigned long long)xhci->cmd_ring->first_seg->dma);
Expand Down Expand Up @@ -2445,8 +2451,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
if (xhci_setup_port_arrays(xhci, flags))
goto fail;

INIT_LIST_HEAD(&xhci->lpm_failed_devs);

/* Enable USB 3.0 device notifications for function remote wake, which
* is necessary for allowing USB 3.0 devices to do remote wakeup from
* U3 (device suspend).
Expand Down
8 changes: 8 additions & 0 deletions drivers/usb/host/xhci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
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);
}
Expand Down
16 changes: 13 additions & 3 deletions drivers/usb/host/xhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci)
* Systems:
* 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;

Expand Down Expand Up @@ -517,7 +517,7 @@ int xhci_init(struct usb_hcd *hcd)
xhci_dbg(xhci, "Finished xhci_init\n");

/* 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;
compliance_mode_recovery_timer_init(xhci);
}
Expand Down Expand Up @@ -956,6 +956,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
struct usb_hcd *hcd = xhci_to_hcd(xhci);
struct usb_hcd *secondary_hcd;
int retval = 0;
bool comp_timer_running = false;

/* Wait a bit if either of the roothubs need to settle from the
* transition into bus suspend.
Expand Down Expand Up @@ -993,6 +994,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)

/* If restore operation fails, re-initialize the HC during resume */
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. */
usb_root_hub_lost_power(xhci->main_hcd->self.root_hub);
usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub);
Expand Down Expand Up @@ -1035,6 +1043,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
retval = xhci_init(hcd->primary_hcd);
if (retval)
return retval;
comp_timer_running = true;

xhci_dbg(xhci, "Start the primary HCD\n");
retval = xhci_run(hcd->primary_hcd);
if (!retval) {
Expand Down Expand Up @@ -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
* 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);

/* Re-enable port polling. */
Expand Down
3 changes: 3 additions & 0 deletions drivers/usb/host/xhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_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 */
18 changes: 8 additions & 10 deletions drivers/usb/musb/musb_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -1232,7 +1232,6 @@ void musb_host_tx(struct musb *musb, u8 epnum)
void __iomem *mbase = musb->mregs;
struct dma_channel *dma;
bool transfer_pending = false;
static bool use_sg;

musb_ep_select(mbase, epnum);
tx_csr = musb_readw(epio, MUSB_TXCSR);
Expand Down Expand Up @@ -1463,9 +1462,9 @@ void musb_host_tx(struct musb *musb, u8 epnum)
* NULL.
*/
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 */
if (!sg_miter_next(&qh->sg_miter)) {
dev_err(musb->controller, "error: sg list empty\n");
Expand All @@ -1484,9 +1483,9 @@ void musb_host_tx(struct musb *musb, u8 epnum)

qh->segsize = length;

if (use_sg) {
if (qh->use_sg) {
if (offset + length >= urb->transfer_buffer_length)
use_sg = false;
qh->use_sg = false;
}

musb_ep_select(mbase, epnum);
Expand Down Expand Up @@ -1552,7 +1551,6 @@ void musb_host_rx(struct musb *musb, u8 epnum)
bool done = false;
u32 status;
struct dma_channel *dma;
static bool use_sg;
unsigned int sg_flags = SG_MITER_ATOMIC | SG_MITER_TO_SG;

musb_ep_select(mbase, epnum);
Expand Down Expand Up @@ -1878,12 +1876,12 @@ void musb_host_rx(struct musb *musb, u8 epnum)
* NULL.
*/
if (!urb->transfer_buffer) {
use_sg = true;
qh->use_sg = true;
sg_miter_start(&qh->sg_miter, urb->sg, 1,
sg_flags);
}

if (use_sg) {
if (qh->use_sg) {
if (!sg_miter_next(&qh->sg_miter)) {
dev_err(musb->controller, "error: sg list empty\n");
sg_miter_stop(&qh->sg_miter);
Expand Down Expand Up @@ -1913,8 +1911,8 @@ void musb_host_rx(struct musb *musb, u8 epnum)
urb->actual_length += xfer_len;
qh->offset += xfer_len;
if (done) {
if (use_sg)
use_sg = false;
if (qh->use_sg)
qh->use_sg = false;

if (urb->status == -EINPROGRESS)
urb->status = status;
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/musb/musb_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct musb_qh {
u16 frame; /* for periodic schedule */
unsigned iso_idx; /* in urb->iso_frame_desc[] */
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 */
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/serial/ark3116.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
#define DRIVER_NAME "ark3116"

/* usb timeout of 1 second */
#define ARK_TIMEOUT (1*HZ)
#define ARK_TIMEOUT 1000

static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x6547, 0x0232) },
Expand Down
18 changes: 17 additions & 1 deletion drivers/usb/serial/cypress_m8.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ static const struct usb_device_id id_table_earthmate[] = {
static const struct usb_device_id id_table_cyphidcomrs232[] = {
{ USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
{ USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
{ USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) },
{ } /* Terminating entry */
};

Expand All @@ -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_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
{ 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) },
{ } /* Terminating entry */
};
Expand Down Expand Up @@ -229,6 +231,12 @@ static struct usb_serial_driver * const serial_drivers[] = {
* 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)
{
Expand All @@ -238,6 +246,10 @@ static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
if (unstable_bauds)
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
* a maximum speed of 57600bps (I have no idea whether DeLorme
Expand Down Expand Up @@ -448,7 +460,11 @@ static int cypress_generic_port_probe(struct usb_serial_port *port)
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->line_control = 0;
Expand Down
4 changes: 4 additions & 0 deletions drivers/usb/serial/cypress_m8.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
#define VENDOR_ID_CYPRESS 0x04b4
#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 */
#define VENDOR_ID_POWERCOM 0x0d9f
#define PRODUCT_ID_UPS 0x0002
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/serial/iuu_phoenix.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
usb_bulk_msg(serial->dev,
usb_sndbulkpipe(serial->dev,
port->bulk_out_endpointAddress), buf,
count, &actual, HZ * 1);
count, &actual, 1000);

if (status != IUU_OPERATION_OK)
dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status);
Expand All @@ -307,7 +307,7 @@ static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
usb_bulk_msg(serial->dev,
usb_rcvbulkpipe(serial->dev,
port->bulk_in_endpointAddress), buf,
count, &actual, HZ * 1);
count, &actual, 1000);

if (status != IUU_OPERATION_OK)
dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status);
Expand Down
Loading

0 comments on commit c6d6b9d

Please sign in to comment.