Commit 7a54f5e1 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6

* 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (30 commits)
  USB: ftdi_sio: add Calao reference board support
  USB option driver K3765/K4505 avoid CDC_DATA interface
  USB: option: add YUGA device id to driver
  usb: s5p-ehci: fix a NULL pointer deference
  USB: EHCI: Do not rely on PORT_SUSPEND to stop USB resuming in ehci_bus_resume().
  USB option driver add PID of Huawei Vodafone K4605
  USB option driver add PID of Huawei Vodafone K3806
  xhci: Handle zero-length isochronous packets.
  USB: Avoid NULL pointer deref in usb_hcd_alloc_bandwidth.
  usb: musb: gadget: fix error path
  usb: gadget: f_phonet: unlock in error case
  usb: musb: blackfin: include prefetch head file
  usb: musb: tusb6010: fix compilation
  usb: gadget: renesas_usbhs: fix DMA build by including dma-mapping.h
  usb: musb: cppi: fix build errors due to DBG and missing musb variable
  usb: musb: ux500: replace missing DBG with dev_dbg
  usb: musb: ux500: set dma config for both src and dst
  usb: musb: fix oops on musb_gadget_pullup
  usb: host: ehci-omap: fix .remove and failure handling path of .probe(v1)
  usb: gadget: hid: don't STALL when processing a HID Descriptor request
  ...
parents efe45ab1 c96fbdd0
...@@ -1775,6 +1775,8 @@ int usb_hcd_alloc_bandwidth(struct usb_device *udev, ...@@ -1775,6 +1775,8 @@ int usb_hcd_alloc_bandwidth(struct usb_device *udev,
struct usb_interface *iface = usb_ifnum_to_if(udev, struct usb_interface *iface = usb_ifnum_to_if(udev,
cur_alt->desc.bInterfaceNumber); cur_alt->desc.bInterfaceNumber);
if (!iface)
return -EINVAL;
if (iface->resetting_device) { if (iface->resetting_device) {
/* /*
* The USB core just reset the device, so the xHCI host * The USB core just reset the device, so the xHCI host
......
...@@ -434,6 +434,7 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt) ...@@ -434,6 +434,7 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
config_ep_by_speed(gadget, f, fp->out_ep)) { config_ep_by_speed(gadget, f, fp->out_ep)) {
fp->in_ep->desc = NULL; fp->in_ep->desc = NULL;
fp->out_ep->desc = NULL; fp->out_ep->desc = NULL;
spin_unlock(&port->lock);
return -EINVAL; return -EINVAL;
} }
usb_ep_enable(fp->out_ep); usb_ep_enable(fp->out_ep);
......
...@@ -343,7 +343,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) ...@@ -343,7 +343,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
u32 temp; u32 temp;
u32 power_okay; u32 power_okay;
int i; int i;
u8 resume_needed = 0; unsigned long resume_needed = 0;
if (time_before (jiffies, ehci->next_statechange)) if (time_before (jiffies, ehci->next_statechange))
msleep(5); msleep(5);
...@@ -416,7 +416,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) ...@@ -416,7 +416,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
if (test_bit(i, &ehci->bus_suspended) && if (test_bit(i, &ehci->bus_suspended) &&
(temp & PORT_SUSPEND)) { (temp & PORT_SUSPEND)) {
temp |= PORT_RESUME; temp |= PORT_RESUME;
resume_needed = 1; set_bit(i, &resume_needed);
} }
ehci_writel(ehci, temp, &ehci->regs->port_status [i]); ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
} }
...@@ -431,8 +431,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) ...@@ -431,8 +431,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
i = HCS_N_PORTS (ehci->hcs_params); i = HCS_N_PORTS (ehci->hcs_params);
while (i--) { while (i--) {
temp = ehci_readl(ehci, &ehci->regs->port_status [i]); temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
if (test_bit(i, &ehci->bus_suspended) && if (test_bit(i, &resume_needed)) {
(temp & PORT_SUSPEND)) {
temp &= ~(PORT_RWC_BITS | PORT_RESUME); temp &= ~(PORT_RWC_BITS | PORT_RESUME);
ehci_writel(ehci, temp, &ehci->regs->port_status [i]); ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
ehci_vdbg (ehci, "resumed port %d\n", i + 1); ehci_vdbg (ehci, "resumed port %d\n", i + 1);
......
...@@ -86,6 +86,7 @@ static int __devinit s5p_ehci_probe(struct platform_device *pdev) ...@@ -86,6 +86,7 @@ static int __devinit s5p_ehci_probe(struct platform_device *pdev)
goto fail_hcd; goto fail_hcd;
} }
s5p_ehci->hcd = hcd;
s5p_ehci->clk = clk_get(&pdev->dev, "usbhost"); s5p_ehci->clk = clk_get(&pdev->dev, "usbhost");
if (IS_ERR(s5p_ehci->clk)) { if (IS_ERR(s5p_ehci->clk)) {
......
...@@ -463,10 +463,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -463,10 +463,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
&& (temp & PORT_POWER)) && (temp & PORT_POWER))
status |= USB_PORT_STAT_SUSPEND; status |= USB_PORT_STAT_SUSPEND;
} }
if ((temp & PORT_PLS_MASK) == XDEV_RESUME) { if ((temp & PORT_PLS_MASK) == XDEV_RESUME &&
!DEV_SUPERSPEED(temp)) {
if ((temp & PORT_RESET) || !(temp & PORT_PE)) if ((temp & PORT_RESET) || !(temp & PORT_PE))
goto error; goto error;
if (!DEV_SUPERSPEED(temp) && time_after_eq(jiffies, if (time_after_eq(jiffies,
bus_state->resume_done[wIndex])) { bus_state->resume_done[wIndex])) {
xhci_dbg(xhci, "Resume USB2 port %d\n", xhci_dbg(xhci, "Resume USB2 port %d\n",
wIndex + 1); wIndex + 1);
...@@ -487,6 +488,14 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -487,6 +488,14 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
xhci_ring_device(xhci, slot_id); xhci_ring_device(xhci, slot_id);
bus_state->port_c_suspend |= 1 << wIndex; bus_state->port_c_suspend |= 1 << wIndex;
bus_state->suspended_ports &= ~(1 << wIndex); bus_state->suspended_ports &= ~(1 << wIndex);
} else {
/*
* The resume has been signaling for less than
* 20ms. Report the port status as SUSPEND,
* let the usbcore check port status again
* and clear resume signaling later.
*/
status |= USB_PORT_STAT_SUSPEND;
} }
} }
if ((temp & PORT_PLS_MASK) == XDEV_U0 if ((temp & PORT_PLS_MASK) == XDEV_U0
...@@ -664,7 +673,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -664,7 +673,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
xhci_dbg(xhci, "PORTSC %04x\n", temp); xhci_dbg(xhci, "PORTSC %04x\n", temp);
if (temp & PORT_RESET) if (temp & PORT_RESET)
goto error; goto error;
if (temp & XDEV_U3) { if ((temp & PORT_PLS_MASK) == XDEV_U3) {
if ((temp & PORT_PE) == 0) if ((temp & PORT_PE) == 0)
goto error; goto error;
......
...@@ -514,8 +514,12 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, ...@@ -514,8 +514,12 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
(unsigned long long) addr); (unsigned long long) addr);
} }
/* flip_cycle means flip the cycle bit of all but the first and last TRB.
* (The last TRB actually points to the ring enqueue pointer, which is not part
* of this TD.) This is used to remove partially enqueued isoc TDs from a ring.
*/
static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
struct xhci_td *cur_td) struct xhci_td *cur_td, bool flip_cycle)
{ {
struct xhci_segment *cur_seg; struct xhci_segment *cur_seg;
union xhci_trb *cur_trb; union xhci_trb *cur_trb;
...@@ -528,6 +532,12 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, ...@@ -528,6 +532,12 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
* leave the pointers intact. * leave the pointers intact.
*/ */
cur_trb->generic.field[3] &= cpu_to_le32(~TRB_CHAIN); cur_trb->generic.field[3] &= cpu_to_le32(~TRB_CHAIN);
/* Flip the cycle bit (link TRBs can't be the first
* or last TRB).
*/
if (flip_cycle)
cur_trb->generic.field[3] ^=
cpu_to_le32(TRB_CYCLE);
xhci_dbg(xhci, "Cancel (unchain) link TRB\n"); xhci_dbg(xhci, "Cancel (unchain) link TRB\n");
xhci_dbg(xhci, "Address = %p (0x%llx dma); " xhci_dbg(xhci, "Address = %p (0x%llx dma); "
"in seg %p (0x%llx dma)\n", "in seg %p (0x%llx dma)\n",
...@@ -541,6 +551,11 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, ...@@ -541,6 +551,11 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
cur_trb->generic.field[2] = 0; cur_trb->generic.field[2] = 0;
/* Preserve only the cycle bit of this TRB */ /* Preserve only the cycle bit of this TRB */
cur_trb->generic.field[3] &= cpu_to_le32(TRB_CYCLE); cur_trb->generic.field[3] &= cpu_to_le32(TRB_CYCLE);
/* Flip the cycle bit except on the first or last TRB */
if (flip_cycle && cur_trb != cur_td->first_trb &&
cur_trb != cur_td->last_trb)
cur_trb->generic.field[3] ^=
cpu_to_le32(TRB_CYCLE);
cur_trb->generic.field[3] |= cpu_to_le32( cur_trb->generic.field[3] |= cpu_to_le32(
TRB_TYPE(TRB_TR_NOOP)); TRB_TYPE(TRB_TR_NOOP));
xhci_dbg(xhci, "Cancel TRB %p (0x%llx dma) " xhci_dbg(xhci, "Cancel TRB %p (0x%llx dma) "
...@@ -719,14 +734,14 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, ...@@ -719,14 +734,14 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
cur_td->urb->stream_id, cur_td->urb->stream_id,
cur_td, &deq_state); cur_td, &deq_state);
else else
td_to_noop(xhci, ep_ring, cur_td); td_to_noop(xhci, ep_ring, cur_td, false);
remove_finished_td: remove_finished_td:
/* /*
* The event handler won't see a completion for this TD anymore, * The event handler won't see a completion for this TD anymore,
* so remove it from the endpoint ring's TD list. Keep it in * so remove it from the endpoint ring's TD list. Keep it in
* the cancelled TD list for URB completion later. * the cancelled TD list for URB completion later.
*/ */
list_del(&cur_td->td_list); list_del_init(&cur_td->td_list);
} }
last_unlinked_td = cur_td; last_unlinked_td = cur_td;
xhci_stop_watchdog_timer_in_irq(xhci, ep); xhci_stop_watchdog_timer_in_irq(xhci, ep);
...@@ -754,7 +769,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, ...@@ -754,7 +769,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
do { do {
cur_td = list_entry(ep->cancelled_td_list.next, cur_td = list_entry(ep->cancelled_td_list.next,
struct xhci_td, cancelled_td_list); struct xhci_td, cancelled_td_list);
list_del(&cur_td->cancelled_td_list); list_del_init(&cur_td->cancelled_td_list);
/* Clean up the cancelled URB */ /* Clean up the cancelled URB */
/* Doesn't matter what we pass for status, since the core will /* Doesn't matter what we pass for status, since the core will
...@@ -862,9 +877,9 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) ...@@ -862,9 +877,9 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
cur_td = list_first_entry(&ring->td_list, cur_td = list_first_entry(&ring->td_list,
struct xhci_td, struct xhci_td,
td_list); td_list);
list_del(&cur_td->td_list); list_del_init(&cur_td->td_list);
if (!list_empty(&cur_td->cancelled_td_list)) if (!list_empty(&cur_td->cancelled_td_list))
list_del(&cur_td->cancelled_td_list); list_del_init(&cur_td->cancelled_td_list);
xhci_giveback_urb_in_irq(xhci, cur_td, xhci_giveback_urb_in_irq(xhci, cur_td,
-ESHUTDOWN, "killed"); -ESHUTDOWN, "killed");
} }
...@@ -873,7 +888,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) ...@@ -873,7 +888,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
&temp_ep->cancelled_td_list, &temp_ep->cancelled_td_list,
struct xhci_td, struct xhci_td,
cancelled_td_list); cancelled_td_list);
list_del(&cur_td->cancelled_td_list); list_del_init(&cur_td->cancelled_td_list);
xhci_giveback_urb_in_irq(xhci, cur_td, xhci_giveback_urb_in_irq(xhci, cur_td,
-ESHUTDOWN, "killed"); -ESHUTDOWN, "killed");
} }
...@@ -1565,10 +1580,10 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td, ...@@ -1565,10 +1580,10 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td,
else else
*status = 0; *status = 0;
} }
list_del(&td->td_list); list_del_init(&td->td_list);
/* Was this TD slated to be cancelled but completed anyway? */ /* Was this TD slated to be cancelled but completed anyway? */
if (!list_empty(&td->cancelled_td_list)) if (!list_empty(&td->cancelled_td_list))
list_del(&td->cancelled_td_list); list_del_init(&td->cancelled_td_list);
urb_priv->td_cnt++; urb_priv->td_cnt++;
/* Giveback the urb when all the tds are completed */ /* Giveback the urb when all the tds are completed */
...@@ -2500,12 +2515,9 @@ static int prepare_transfer(struct xhci_hcd *xhci, ...@@ -2500,12 +2515,9 @@ static int prepare_transfer(struct xhci_hcd *xhci,
if (td_index == 0) { if (td_index == 0) {
ret = usb_hcd_link_urb_to_ep(bus_to_hcd(urb->dev->bus), urb); ret = usb_hcd_link_urb_to_ep(bus_to_hcd(urb->dev->bus), urb);
if (unlikely(ret)) { if (unlikely(ret))
xhci_urb_free_priv(xhci, urb_priv);
urb->hcpriv = NULL;
return ret; return ret;
} }
}
td->urb = urb; td->urb = urb;
/* Add this TD to the tail of the endpoint ring's TD list */ /* Add this TD to the tail of the endpoint ring's TD list */
...@@ -2672,6 +2684,10 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len, ...@@ -2672,6 +2684,10 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
{ {
int packets_transferred; int packets_transferred;
/* One TRB with a zero-length data packet. */
if (running_total == 0 && trb_buff_len == 0)
return 0;
/* All the TRB queueing functions don't count the current TRB in /* All the TRB queueing functions don't count the current TRB in
* running_total. * running_total.
*/ */
...@@ -3113,20 +3129,15 @@ static int count_isoc_trbs_needed(struct xhci_hcd *xhci, ...@@ -3113,20 +3129,15 @@ static int count_isoc_trbs_needed(struct xhci_hcd *xhci,
struct urb *urb, int i) struct urb *urb, int i)
{ {
int num_trbs = 0; int num_trbs = 0;
u64 addr, td_len, running_total; u64 addr, td_len;
addr = (u64) (urb->transfer_dma + urb->iso_frame_desc[i].offset); addr = (u64) (urb->transfer_dma + urb->iso_frame_desc[i].offset);
td_len = urb->iso_frame_desc[i].length; td_len = urb->iso_frame_desc[i].length;
running_total = TRB_MAX_BUFF_SIZE - (addr & (TRB_MAX_BUFF_SIZE - 1)); num_trbs = DIV_ROUND_UP(td_len + (addr & (TRB_MAX_BUFF_SIZE - 1)),
running_total &= TRB_MAX_BUFF_SIZE - 1; TRB_MAX_BUFF_SIZE);
if (running_total != 0) if (num_trbs == 0)
num_trbs++;
while (running_total < td_len) {
num_trbs++; num_trbs++;
running_total += TRB_MAX_BUFF_SIZE;
}
return num_trbs; return num_trbs;
} }
...@@ -3226,6 +3237,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3226,6 +3237,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
start_trb = &ep_ring->enqueue->generic; start_trb = &ep_ring->enqueue->generic;
start_cycle = ep_ring->cycle_state; start_cycle = ep_ring->cycle_state;
urb_priv = urb->hcpriv;
/* Queue the first TRB, even if it's zero-length */ /* Queue the first TRB, even if it's zero-length */
for (i = 0; i < num_tds; i++) { for (i = 0; i < num_tds; i++) {
unsigned int total_packet_count; unsigned int total_packet_count;
...@@ -3237,9 +3249,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3237,9 +3249,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
addr = start_addr + urb->iso_frame_desc[i].offset; addr = start_addr + urb->iso_frame_desc[i].offset;
td_len = urb->iso_frame_desc[i].length; td_len = urb->iso_frame_desc[i].length;
td_remain_len = td_len; td_remain_len = td_len;
/* FIXME: Ignoring zero-length packets, can those happen? */
total_packet_count = roundup(td_len, total_packet_count = roundup(td_len,
le16_to_cpu(urb->ep->desc.wMaxPacketSize)); le16_to_cpu(urb->ep->desc.wMaxPacketSize));
/* A zero-length transfer still involves at least one packet. */
if (total_packet_count == 0)
total_packet_count++;
burst_count = xhci_get_burst_count(xhci, urb->dev, urb, burst_count = xhci_get_burst_count(xhci, urb->dev, urb,
total_packet_count); total_packet_count);
residue = xhci_get_last_burst_packet_count(xhci, residue = xhci_get_last_burst_packet_count(xhci,
...@@ -3249,12 +3263,13 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3249,12 +3263,13 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index, ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index,
urb->stream_id, trbs_per_td, urb, i, mem_flags); urb->stream_id, trbs_per_td, urb, i, mem_flags);
if (ret < 0) if (ret < 0) {
if (i == 0)
return ret; return ret;
goto cleanup;
}
urb_priv = urb->hcpriv;
td = urb_priv->td[i]; td = urb_priv->td[i];
for (j = 0; j < trbs_per_td; j++) { for (j = 0; j < trbs_per_td; j++) {
u32 remainder = 0; u32 remainder = 0;
field = TRB_TBC(burst_count) | TRB_TLBPC(residue); field = TRB_TBC(burst_count) | TRB_TLBPC(residue);
...@@ -3344,6 +3359,27 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3344,6 +3359,27 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
start_cycle, start_trb); start_cycle, start_trb);
return 0; return 0;
cleanup:
/* Clean up a partially enqueued isoc transfer. */
for (i--; i >= 0; i--)
list_del_init(&urb_priv->td[i]->td_list);
/* Use the first TD as a temporary variable to turn the TDs we've queued
* into No-ops with a software-owned cycle bit. That way the hardware
* won't accidentally start executing bogus TDs when we partially
* overwrite them. td->first_trb and td->start_seg are already set.
*/
urb_priv->td[0]->last_trb = ep_ring->enqueue;
/* Every TRB except the first & last will have its cycle bit flipped. */
td_to_noop(xhci, ep_ring, urb_priv->td[0], true);
/* Reset the ring enqueue back to the first TRB and its cycle bit. */
ep_ring->enqueue = urb_priv->td[0]->first_trb;
ep_ring->enq_seg = urb_priv->td[0]->start_seg;
ep_ring->cycle_state = start_cycle;
usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);
return ret;
} }
/* /*
......
...@@ -1085,9 +1085,12 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ...@@ -1085,9 +1085,12 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
if (urb->dev->speed == USB_SPEED_FULL) { if (urb->dev->speed == USB_SPEED_FULL) {
ret = xhci_check_maxpacket(xhci, slot_id, ret = xhci_check_maxpacket(xhci, slot_id,
ep_index, urb); ep_index, urb);
if (ret < 0) if (ret < 0) {
xhci_urb_free_priv(xhci, urb_priv);
urb->hcpriv = NULL;
return ret; return ret;
} }
}
/* We have a spinlock and interrupts disabled, so we must pass /* We have a spinlock and interrupts disabled, so we must pass
* atomic context to this function, which may allocate memory. * atomic context to this function, which may allocate memory.
...@@ -1097,6 +1100,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ...@@ -1097,6 +1100,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
goto dying; goto dying;
ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
slot_id, ep_index); slot_id, ep_index);
if (ret)
goto free_priv;
spin_unlock_irqrestore(&xhci->lock, flags); spin_unlock_irqrestore(&xhci->lock, flags);
} else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) {
spin_lock_irqsave(&xhci->lock, flags); spin_lock_irqsave(&xhci->lock, flags);
...@@ -1117,6 +1122,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ...@@ -1117,6 +1122,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
slot_id, ep_index); slot_id, ep_index);
} }
if (ret)
goto free_priv;
spin_unlock_irqrestore(&xhci->lock, flags); spin_unlock_irqrestore(&xhci->lock, flags);
} else if (usb_endpoint_xfer_int(&urb->ep->desc)) { } else if (usb_endpoint_xfer_int(&urb->ep->desc)) {
spin_lock_irqsave(&xhci->lock, flags); spin_lock_irqsave(&xhci->lock, flags);
...@@ -1124,6 +1131,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ...@@ -1124,6 +1131,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
goto dying; goto dying;
ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb,
slot_id, ep_index); slot_id, ep_index);
if (ret)
goto free_priv;
spin_unlock_irqrestore(&xhci->lock, flags); spin_unlock_irqrestore(&xhci->lock, flags);
} else { } else {
spin_lock_irqsave(&xhci->lock, flags); spin_lock_irqsave(&xhci->lock, flags);
...@@ -1131,18 +1140,22 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ...@@ -1131,18 +1140,22 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
goto dying; goto dying;
ret = xhci_queue_isoc_tx_prepare(xhci, GFP_ATOMIC, urb, ret = xhci_queue_isoc_tx_prepare(xhci, GFP_ATOMIC, urb,
slot_id, ep_index); slot_id, ep_index);
if (ret)
goto free_priv;
spin_unlock_irqrestore(&xhci->lock, flags); spin_unlock_irqrestore(&xhci->lock, flags);
} }
exit: exit:
return ret; return ret;
dying: dying:
xhci_urb_free_priv(xhci, urb_priv);
urb->hcpriv = NULL;
xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for " xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for "
"non-responsive xHCI host.\n", "non-responsive xHCI host.\n",
urb->ep->desc.bEndpointAddress, urb); urb->ep->desc.bEndpointAddress, urb);
ret = -ESHUTDOWN;
free_priv:
xhci_urb_free_priv(xhci, urb_priv);
urb->hcpriv = NULL;
spin_unlock_irqrestore(&xhci->lock, flags); spin_unlock_irqrestore(&xhci->lock, flags);
return -ESHUTDOWN; return ret;
} }
/* Get the right ring for the given URB. /* Get the right ring for the given URB.
...@@ -1239,6 +1252,13 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) ...@@ -1239,6 +1252,13 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) { if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) {
xhci_dbg(xhci, "HW died, freeing TD.\n"); xhci_dbg(xhci, "HW died, freeing TD.\n");
urb_priv = urb->hcpriv; urb_priv = urb->hcpriv;
for (i = urb_priv->td_cnt; i < urb_priv->length; i++) {
td = urb_priv->td[i];
if (!list_empty(&td->td_list))
list_del_init(&td->td_list);
if (!list_empty(&td->cancelled_td_list))
list_del_init(&td->cancelled_td_list);
}
usb_hcd_unlink_urb_from_ep(hcd, urb); usb_hcd_unlink_urb_from_ep(hcd, urb);
spin_unlock_irqrestore(&xhci->lock, flags); spin_unlock_irqrestore(&xhci->lock, flags);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/prefetch.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
......
...@@ -226,8 +226,10 @@ static int cppi_controller_stop(struct dma_controller *c) ...@@ -226,8 +226,10 @@ static int cppi_controller_stop(struct dma_controller *c)
struct cppi *controller; struct cppi *controller;
void __iomem *tibase; void __iomem *tibase;
int i; int i;
struct musb *musb;
controller = container_of(c, struct cppi, controller); controller = container_of(c, struct cppi, controller);
musb = controller->musb;
tibase = controller->tibase; tibase = controller->tibase;
/* DISABLE INDIVIDUAL CHANNEL Interrupts */ /* DISABLE INDIVIDUAL CHANNEL Interrupts */
...@@ -289,9 +291,11 @@ cppi_channel_allocate(struct dma_controller *c, ...@@ -289,9 +291,11 @@ cppi_channel_allocate(struct dma_controller *c,
u8 index; u8 index;
struct cppi_channel *cppi_ch; struct cppi_channel *cppi_ch;
void __iomem *tibase; void __iomem *tibase;
struct musb *musb;
controller = container_of(c, struct cppi, controller); controller = container_of(c, struct cppi, controller);
tibase = controller->tibase; tibase = controller->tibase;
musb = controller->musb;
/* ep0 doesn't use DMA; remember cppi indices are 0..N-1 */ /* ep0 doesn't use DMA; remember cppi indices are 0..N-1 */
index = ep->epnum - 1; index = ep->epnum - 1;
...@@ -339,7 +343,8 @@ static void cppi_channel_release(struct dma_channel *channel) ...@@ -339,7 +343,8 @@ static void cppi_channel_release(struct dma_channel *channel)
c = container_of(channel, struct cppi_channel, channel); c = container_of(channel, struct cppi_channel, channel);
tibase = c->controller->tibase; tibase = c->controller->tibase;
if (!c->hw_ep) if (!c->hw_ep)
dev_dbg(musb->controller, "releasing idle DMA channel %p\n", c); dev_dbg(c->controller->musb->controller,
"releasing idle DMA channel %p\n", c);
else if (!c->transmit) else if (!c->transmit)
core_rxirq_enable(tibase, c->index + 1); core_rxirq_enable(tibase, c->index + 1);
...@@ -357,7 +362,8 @@ cppi_dump_rx(int level, struct cppi_channel *c, const char *tag) ...@@ -357,7 +362,8 @@ cppi_dump_rx(int level, struct cppi_channel *c, const char *tag)
musb_ep_select(base, c->index + 1); musb_ep_select(base, c->index + 1);
DBG(level, "RX DMA%d%s: %d left, csr %04x, " dev_dbg(c->controller->musb->controller,
"RX DMA%d%s: %d left, csr %04x, "
"%08x H%08x S%08x C%08x, " "%08x H%08x S%08x C%08x, "
"B%08x L%08x %08x .. %08x" "B%08x L%08x %08x .. %08x"
"\n", "\n",
...@@ -387,7 +393,8 @@ cppi_dump_tx(int level, struct cppi_channel *c, const char *tag) ...@@ -387,7 +393,8 @@ cppi_dump_tx(int level, struct cppi_channel *c, const char *tag)
musb_ep_select(base, c->index + 1); musb_ep_select(base, c->index + 1);
DBG(level, "TX DMA%d%s: csr %04x, " dev_dbg(c->controller->musb->controller,
"TX DMA%d%s: csr %04x, "
"H%08x S%08x C%08x %08x, " "H%08x S%08x C%08x %08x, "
"F%08x L%08x .. %08x" "F%08x L%08x .. %08x"
"\n", "\n",
...@@ -1022,6 +1029,7 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch) ...@@ -1022,6 +1029,7 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch)
int i; int i;
dma_addr_t safe2ack; dma_addr_t safe2ack;
void __iomem *regs = rx->hw_ep->regs; void __iomem *regs = rx->hw_ep->regs;
struct musb *musb = cppi->musb;
cppi_dump_rx(6, rx, "/K"); cppi_dump_rx(6, rx, "/K");
......
...@@ -172,7 +172,8 @@ enum musb_g_ep0_state { ...@@ -172,7 +172,8 @@ enum musb_g_ep0_state {
#endif #endif
/* TUSB mapping: "flat" plus ep0 special cases */ /* TUSB mapping: "flat" plus ep0 special cases */
#if defined(CONFIG_USB_MUSB_TUSB6010) #if defined(CONFIG_USB_MUSB_TUSB6010) || \
defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
#define musb_ep_select(_mbase, _epnum) \ #define musb_ep_select(_mbase, _epnum) \
musb_writeb((_mbase), MUSB_INDEX, (_epnum)) musb_writeb((_mbase), MUSB_INDEX, (_epnum))
#define MUSB_EP_OFFSET MUSB_TUSB_OFFSET #define MUSB_EP_OFFSET MUSB_TUSB_OFFSET
...@@ -241,7 +242,8 @@ struct musb_hw_ep { ...@@ -241,7 +242,8 @@ struct musb_hw_ep {
void __iomem *fifo; void __iomem *fifo;
void __iomem *regs; void __iomem *regs;
#ifdef CONFIG_USB_MUSB_TUSB6010 #if defined(CONFIG_USB_MUSB_TUSB6010) || \
defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
void __iomem *conf; void __iomem *conf;
#endif #endif
...@@ -258,7 +260,8 @@ struct musb_hw_ep { ...@@ -258,7 +260,8 @@ struct musb_hw_ep {
struct dma_channel *tx_channel; struct dma_channel *tx_channel;
struct dma_channel *rx_channel; struct dma_channel *rx_channel;
#ifdef CONFIG_USB_MUSB_TUSB6010 #if defined(CONFIG_USB_MUSB_TUSB6010) || \
defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
/* TUSB has "asynchronous" and "synchronous" dma modes */ /* TUSB has "asynchronous" and "synchronous" dma modes */
dma_addr_t fifo_async; dma_addr_t fifo_async;
dma_addr_t fifo_sync; dma_addr_t fifo_sync;
...@@ -356,7 +359,8 @@ struct musb { ...@@ -356,7 +359,8 @@ struct musb {
void __iomem *ctrl_base; void __iomem *ctrl_base;
void __iomem *mregs; void __iomem *mregs;
#ifdef CONFIG_USB_MUSB_TUSB6010 #if defined(CONFIG_USB_MUSB_TUSB6010) || \
defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
dma_addr_t async; dma_addr_t async;
dma_addr_t sync; dma_addr_t sync;
void __iomem *sync_va; void __iomem *sync_va;
......
...@@ -1856,6 +1856,7 @@ int __init musb_gadget_setup(struct musb *musb) ...@@ -1856,6 +1856,7 @@ int __init musb_gadget_setup(struct musb *musb)
return 0; return 0;
err: err:
musb->g.dev.parent = NULL;
device_unregister(&musb->g.dev); device_unregister(&musb->g.dev);
return status; return status;
} }
...@@ -1863,6 +1864,7 @@ int __init musb_gadget_setup(struct musb *musb) ...@@ -1863,6 +1864,7 @@ int __init musb_gadget_setup(struct musb *musb)
void musb_gadget_cleanup(struct musb *musb) void musb_gadget_cleanup(struct musb *musb)
{ {
usb_del_gadget_udc(&musb->g); usb_del_gadget_udc(&musb->g);
if (musb->g.dev.parent)
device_unregister(&musb->g.dev); device_unregister(&musb->g.dev);
} }
......
...@@ -234,7 +234,8 @@ ...@@ -234,7 +234,8 @@
#define MUSB_TESTMODE 0x0F /* 8 bit */ #define MUSB_TESTMODE 0x0F /* 8 bit */
/* Get offset for a given FIFO from musb->mregs */ /* Get offset for a given FIFO from musb->mregs */
#ifdef CONFIG_USB_MUSB_TUSB6010 #if defined(CONFIG_USB_MUSB_TUSB6010) || \
defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
#define MUSB_FIFO_OFFSET(epnum) (0x200 + ((epnum) * 0x20)) #define MUSB_FIFO_OFFSET(epnum) (0x200 + ((epnum) * 0x20))
#else #else
#define MUSB_FIFO_OFFSET(epnum) (0x20 + ((epnum) * 4)) #define MUSB_FIFO_OFFSET(epnum) (0x20 + ((epnum) * 4))
...@@ -295,7 +296,8 @@ ...@@ -295,7 +296,8 @@
#define MUSB_FLAT_OFFSET(_epnum, _offset) \ #define MUSB_FLAT_OFFSET(_epnum, _offset) \
(0x100 + (0x10*(_epnum)) + (_offset)) (0x100 + (0x10*(_epnum)) + (_offset))
#ifdef CONFIG_USB_MUSB_TUSB6010 #if defined(CONFIG_USB_MUSB_TUSB6010) || \
defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
/* TUSB6010 EP0 configuration register is special */ /* TUSB6010 EP0 configuration register is special */
#define MUSB_TUSB_OFFSET(_epnum, _offset) \ #define MUSB_TUSB_OFFSET(_epnum, _offset) \
(0x10 + _offset) (0x10 + _offset)
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/prefetch.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <plat/mux.h> #include <plat/mux.h>
#include "musb_core.h" #include "musb_core.h"
#include "tusb6010.h"
#define to_chdat(c) ((struct tusb_omap_dma_ch *)(c)->private_data) #define to_chdat(c) ((struct tusb_omap_dma_ch *)(c)->private_data)
......
...@@ -65,7 +65,8 @@ static void ux500_tx_work(struct work_struct *data) ...@@ -65,7 +65,8 @@ static void ux500_tx_work(struct work_struct *data)
struct musb *musb = hw_ep->musb; struct musb *musb = hw_ep->musb;
unsigned long flags; unsigned long flags;
DBG(4, "DMA tx transfer done on hw_ep=%d\n", hw_ep->epnum); dev_dbg(musb->controller, "DMA tx transfer done on hw_ep=%d\n",
hw_ep->epnum);
spin_lock_irqsave(&musb->lock, flags); spin_lock_irqsave(&musb->lock, flags);
ux500_channel->channel.actual_len = ux500_channel->cur_len; ux500_channel->channel.actual_len = ux500_channel->cur_len;
...@@ -84,7 +85,8 @@ static void ux500_rx_work(struct work_struct *data) ...@@ -84,7 +85,8 @@ static void ux500_rx_work(struct work_struct *data)
struct musb *musb = hw_ep->musb; struct musb *musb = hw_ep->musb;
unsigned long flags; unsigned long flags;
DBG(4, "DMA rx transfer done on hw_ep=%d\n", hw_ep->epnum); dev_dbg(musb->controller, "DMA rx transfer done on hw_ep=%d\n",
hw_ep->epnum);
spin_lock_irqsave(&musb->lock, flags); spin_lock_irqsave(&musb->lock, flags);
ux500_channel->channel.actual_len = ux500_channel->cur_len; ux500_channel->channel.actual_len = ux500_channel->cur_len;
...@@ -116,8 +118,10 @@ static bool ux500_configure_channel(struct dma_channel *channel, ...@@ -116,8 +118,10 @@ static bool ux500_configure_channel(struct dma_channel *channel,
enum dma_slave_buswidth addr_width; enum dma_slave_buswidth addr_width;
dma_addr_t usb_fifo_addr = (MUSB_FIFO_OFFSET(hw_ep->epnum) + dma_addr_t usb_fifo_addr = (MUSB_FIFO_OFFSET(hw_ep->epnum) +
ux500_channel->controller->phy_base); ux500_channel->controller->phy_base);
struct musb *musb = ux500_channel->controller->private_data;
DBG(4, "packet_sz=%d, mode=%d, dma_addr=0x%x, len=%d is_tx=%d\n", dev_dbg(musb->controller,
"packet_sz=%d, mode=%d, dma_addr=0x%x, len=%d is_tx=%d\n",
packet_sz, mode, dma_addr, len, ux500_channel->is_tx); packet_sz, mode, dma_addr, len, ux500_channel->is_tx);
ux500_channel->cur_len = len; ux500_channel->cur_len = len;
...@@ -133,15 +137,13 @@ static bool ux500_configure_channel(struct dma_channel *channel, ...@@ -133,15 +137,13 @@ static bool ux500_configure_channel(struct dma_channel *channel,
DMA_SLAVE_BUSWIDTH_4_BYTES; DMA_SLAVE_BUSWIDTH_4_BYTES;
slave_conf.direction = direction; slave_conf.direction = direction;
if (direction == DMA_FROM_DEVICE) {
slave_conf.src_addr = usb_fifo_addr; slave_conf.src_addr = usb_fifo_addr;
slave_conf.src_addr_width = addr_width; slave_conf.src_addr_width = addr_width;
slave_conf.src_maxburst = 16; slave_conf.src_maxburst = 16;
} else {
slave_conf.dst_addr = usb_fifo_addr; slave_conf.dst_addr = usb_fifo_addr;
slave_conf.dst_addr_width = addr_width; slave_conf.dst_addr_width = addr_width;
slave_conf.dst_maxburst = 16; slave_conf.dst_maxburst = 16;
}
dma_chan->device->device_control(dma_chan, DMA_SLAVE_CONFIG, dma_chan->device->device_control(dma_chan, DMA_SLAVE_CONFIG,
(unsigned long) &slave_conf); (unsigned long) &slave_conf);
...@@ -166,6 +168,7 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c, ...@@ -166,6 +168,7 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c,
struct ux500_dma_controller *controller = container_of(c, struct ux500_dma_controller *controller = container_of(c,
struct ux500_dma_controller, controller); struct ux500_dma_controller, controller);
struct ux500_dma_channel *ux500_channel = NULL; struct ux500_dma_channel *ux500_channel = NULL;
struct musb *musb = controller->private_data;
u8 ch_num = hw_ep->epnum - 1; u8 ch_num = hw_ep->epnum - 1;
u32 max_ch; u32 max_ch;
...@@ -192,7 +195,7 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c, ...@@ -192,7 +195,7 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c,
ux500_channel->hw_ep = hw_ep; ux500_channel->hw_ep = hw_ep;
ux500_channel->is_allocated = 1; ux500_channel->is_allocated = 1;
DBG(7, "hw_ep=%d, is_tx=0x%x, channel=%d\n", dev_dbg(musb->controller, "hw_ep=%d, is_tx=0x%x, channel=%d\n",
hw_ep->epnum, is_tx, ch_num); hw_ep->epnum, is_tx, ch_num);
return &(ux500_channel->channel); return &(ux500_channel->channel);
...@@ -201,8 +204,9 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c, ...@@ -201,8 +204,9 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c,
static void ux500_dma_channel_release(struct dma_channel *channel) static void ux500_dma_channel_release(struct dma_channel *channel)
{ {
struct ux500_dma_channel *ux500_channel = channel->private_data; struct ux500_dma_channel *ux500_channel = channel->private_data;
struct musb *musb = ux500_channel->controller->private_data;
DBG(7, "channel=%d\n", ux500_channel->ch_num); dev_dbg(musb->controller, "channel=%d\n", ux500_channel->ch_num);
if (ux500_channel->is_allocated) { if (ux500_channel->is_allocated) {
ux500_channel->is_allocated = 0; ux500_channel->is_allocated = 0;
...@@ -252,8 +256,8 @@ static int ux500_dma_channel_abort(struct dma_channel *channel) ...@@ -252,8 +256,8 @@ static int ux500_dma_channel_abort(struct dma_channel *channel)
void __iomem *epio = musb->endpoints[ux500_channel->hw_ep->epnum].regs; void __iomem *epio = musb->endpoints[ux500_channel->hw_ep->epnum].regs;
u16 csr; u16 csr;
DBG(4, "channel=%d, is_tx=%d\n", ux500_channel->ch_num, dev_dbg(musb->controller, "channel=%d, is_tx=%d\n",
ux500_channel->is_tx); ux500_channel->ch_num, ux500_channel->is_tx);
if (channel->status == MUSB_DMA_STATUS_BUSY) { if (channel->status == MUSB_DMA_STATUS_BUSY) {
if (ux500_channel->is_tx) { if (ux500_channel->is_tx) {
......
...@@ -101,6 +101,7 @@ static int ftdi_jtag_probe(struct usb_serial *serial); ...@@ -101,6 +101,7 @@ static int ftdi_jtag_probe(struct usb_serial *serial);
static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); static int ftdi_mtxorb_hack_setup(struct usb_serial *serial);
static int ftdi_NDI_device_setup(struct usb_serial *serial); static int ftdi_NDI_device_setup(struct usb_serial *serial);
static int ftdi_stmclite_probe(struct usb_serial *serial); static int ftdi_stmclite_probe(struct usb_serial *serial);
static int ftdi_8u2232c_probe(struct usb_serial *serial);
static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); static void ftdi_USB_UIRT_setup(struct ftdi_private *priv);
static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
...@@ -128,6 +129,10 @@ static struct ftdi_sio_quirk ftdi_stmclite_quirk = { ...@@ -128,6 +129,10 @@ static struct ftdi_sio_quirk ftdi_stmclite_quirk = {
.probe = ftdi_stmclite_probe, .probe = ftdi_stmclite_probe,
}; };
static struct ftdi_sio_quirk ftdi_8u2232c_quirk = {
.probe = ftdi_8u2232c_probe,
};
/* /*
* The 8U232AM has the same API as the sio except for: * The 8U232AM has the same API as the sio except for:
* - it can support MUCH higher baudrates; up to: * - it can support MUCH higher baudrates; up to:
...@@ -178,7 +183,8 @@ static struct usb_device_id id_table_combined [] = { ...@@ -178,7 +183,8 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) ,
.driver_info = (kernel_ulong_t)&ftdi_8u2232c_quirk },
{ USB_DEVICE(FTDI_VID, FTDI_4232H_PID) }, { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_232H_PID) }, { USB_DEVICE(FTDI_VID, FTDI_232H_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
...@@ -1737,6 +1743,18 @@ static int ftdi_jtag_probe(struct usb_serial *serial) ...@@ -1737,6 +1743,18 @@ static int ftdi_jtag_probe(struct usb_serial *serial)
return 0; return 0;
} }
static int ftdi_8u2232c_probe(struct usb_serial *serial)
{
struct usb_device *udev = serial->dev;
dbg("%s", __func__);
if (strcmp(udev->manufacturer, "CALAO Systems") == 0)
return ftdi_jtag_probe(serial);
return 0;
}
/* /*
* First and second port on STMCLiteadaptors is reserved for JTAG interface * First and second port on STMCLiteadaptors is reserved for JTAG interface
* and the forth port for pio * and the forth port for pio
......
...@@ -148,6 +148,8 @@ static void option_instat_callback(struct urb *urb); ...@@ -148,6 +148,8 @@ static void option_instat_callback(struct urb *urb);
#define HUAWEI_PRODUCT_K4505 0x1464 #define HUAWEI_PRODUCT_K4505 0x1464
#define HUAWEI_PRODUCT_K3765 0x1465 #define HUAWEI_PRODUCT_K3765 0x1465
#define HUAWEI_PRODUCT_E14AC 0x14AC #define HUAWEI_PRODUCT_E14AC 0x14AC
#define HUAWEI_PRODUCT_K3806 0x14AE
#define HUAWEI_PRODUCT_K4605 0x14C6
#define HUAWEI_PRODUCT_K3770 0x14C9 #define HUAWEI_PRODUCT_K3770 0x14C9
#define HUAWEI_PRODUCT_K3771 0x14CA #define HUAWEI_PRODUCT_K3771 0x14CA
#define HUAWEI_PRODUCT_K4510 0x14CB #define HUAWEI_PRODUCT_K4510 0x14CB
...@@ -416,6 +418,56 @@ static void option_instat_callback(struct urb *urb); ...@@ -416,6 +418,56 @@ static void option_instat_callback(struct urb *urb);
#define SAMSUNG_VENDOR_ID 0x04e8 #define SAMSUNG_VENDOR_ID 0x04e8
#define SAMSUNG_PRODUCT_GT_B3730 0x6889 #define SAMSUNG_PRODUCT_GT_B3730 0x6889
/* YUGA products www.yuga-info.com*/
#define YUGA_VENDOR_ID 0x257A
#define YUGA_PRODUCT_CEM600 0x1601
#define YUGA_PRODUCT_CEM610 0x1602
#define YUGA_PRODUCT_CEM500 0x1603
#define YUGA_PRODUCT_CEM510 0x1604
#define YUGA_PRODUCT_CEM800 0x1605
#define YUGA_PRODUCT_CEM900 0x1606
#define YUGA_PRODUCT_CEU818 0x1607
#define YUGA_PRODUCT_CEU816 0x1608
#define YUGA_PRODUCT_CEU828 0x1609
#define YUGA_PRODUCT_CEU826 0x160A
#define YUGA_PRODUCT_CEU518 0x160B
#define YUGA_PRODUCT_CEU516 0x160C
#define YUGA_PRODUCT_CEU528 0x160D
#define YUGA_PRODUCT_CEU526 0x160F
#define YUGA_PRODUCT_CWM600 0x2601
#define YUGA_PRODUCT_CWM610 0x2602
#define YUGA_PRODUCT_CWM500 0x2603
#define YUGA_PRODUCT_CWM510 0x2604
#define YUGA_PRODUCT_CWM800 0x2605
#define YUGA_PRODUCT_CWM900 0x2606
#define YUGA_PRODUCT_CWU718 0x2607
#define YUGA_PRODUCT_CWU716 0x2608
#define YUGA_PRODUCT_CWU728 0x2609
#define YUGA_PRODUCT_CWU726 0x260A
#define YUGA_PRODUCT_CWU518 0x260B
#define YUGA_PRODUCT_CWU516 0x260C
#define YUGA_PRODUCT_CWU528 0x260D
#define YUGA_PRODUCT_CWU526 0x260F
#define YUGA_PRODUCT_CLM600 0x2601
#define YUGA_PRODUCT_CLM610 0x2602
#define YUGA_PRODUCT_CLM500 0x2603
#define YUGA_PRODUCT_CLM510 0x2604
#define YUGA_PRODUCT_CLM800 0x2605
#define YUGA_PRODUCT_CLM900 0x2606
#define YUGA_PRODUCT_CLU718 0x2607
#define YUGA_PRODUCT_CLU716 0x2608
#define YUGA_PRODUCT_CLU728 0x2609
#define YUGA_PRODUCT_CLU726 0x260A
#define YUGA_PRODUCT_CLU518 0x260B
#define YUGA_PRODUCT_CLU516 0x260C
#define YUGA_PRODUCT_CLU528 0x260D
#define YUGA_PRODUCT_CLU526 0x260F
/* some devices interfaces need special handling due to a number of reasons */ /* some devices interfaces need special handling due to a number of reasons */
enum option_blacklist_reason { enum option_blacklist_reason {
OPTION_BLACKLIST_NONE = 0, OPTION_BLACKLIST_NONE = 0,
...@@ -551,6 +603,8 @@ static const struct usb_device_id option_ids[] = { ...@@ -551,6 +603,8 @@ static const struct usb_device_id option_ids[] = {
{ 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) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) },
...@@ -1005,6 +1059,48 @@ static const struct usb_device_id option_ids[] = { ...@@ -1005,6 +1059,48 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
{ USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */
{ USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM610) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM500) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM510) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM800) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM900) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU818) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU816) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU828) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU826) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU518) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU516) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU528) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU526) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM600) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM610) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM500) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM510) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM800) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM900) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU718) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU716) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU728) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU726) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU518) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU516) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU528) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU526) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM600) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM610) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM500) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM510) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM800) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM900) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU718) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU716) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU728) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU726) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU518) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) },
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
MODULE_DEVICE_TABLE(usb, option_ids); MODULE_DEVICE_TABLE(usb, option_ids);
...@@ -1134,11 +1230,13 @@ static int option_probe(struct usb_serial *serial, ...@@ -1134,11 +1230,13 @@ static int option_probe(struct usb_serial *serial,
serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff)
return -ENODEV; return -ENODEV;
/* Don't bind network interfaces on Huawei K3765 & K4505 */ /* Don't bind network interfaces on Huawei K3765, K4505 & K4605 */
if (serial->dev->descriptor.idVendor == HUAWEI_VENDOR_ID && if (serial->dev->descriptor.idVendor == HUAWEI_VENDOR_ID &&
(serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K3765 || (serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K3765 ||
serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4505) && serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4505 ||
serial->interface->cur_altsetting->desc.bInterfaceNumber == 1) serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4605) &&
(serial->interface->cur_altsetting->desc.bInterfaceNumber == 1 ||
serial->interface->cur_altsetting->desc.bInterfaceNumber == 2))
return -ENODEV; return -ENODEV;
/* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */ /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */
......
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