diff options
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6c5e8133cf87..3915657e6078 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -68,6 +68,7 @@ #include <linux/slab.h> #include "xhci.h" #include "xhci-trace.h" +#include "xhci-mtk.h" /* * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA @@ -1583,7 +1584,8 @@ static void handle_port_status(struct xhci_hcd *xhci, */ bogus_port_status = true; goto cleanup; - } else { + } else if (!test_bit(faked_port_index, + &bus_state->resuming_ports)) { xhci_dbg(xhci, "resume HS port %d\n", port_id); bus_state->resume_done[faked_port_index] = jiffies + msecs_to_jiffies(USB_RESUME_TIMEOUT); @@ -2191,10 +2193,6 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, } /* Fast path - was this the last TRB in the TD for this URB? */ } else if (event_trb == td->last_trb) { - if (td->urb_length_set && trb_comp_code == COMP_SHORT_TX) - return finish_td(xhci, td, event_trb, event, ep, - status, false); - if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { td->urb->actual_length = td->urb->transfer_buffer_length - @@ -2246,12 +2244,6 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, td->urb->actual_length += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); - - if (trb_comp_code == COMP_SHORT_TX) { - xhci_dbg(xhci, "mid bulk/intr SP, wait for last TRB event\n"); - td->urb_length_set = true; - return 0; - } } return finish_td(xhci, td, event_trb, event, ep, status, false); @@ -3074,17 +3066,22 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred, { u32 maxp, total_packet_count; - if (xhci->hci_version < 0x100) + /* MTK xHCI is mostly 0.97 but contains some features from 1.0 */ + if (xhci->hci_version < 0x100 && !(xhci->quirks & XHCI_MTK_HOST)) return ((td_total_len - transferred) >> 10); - maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc)); - total_packet_count = DIV_ROUND_UP(td_total_len, maxp); - /* One TRB with a zero-length data packet. */ if (num_trbs_left == 0 || (transferred == 0 && trb_buff_len == 0) || trb_buff_len == td_total_len) return 0; + /* for MTK xHCI, TD size doesn't include this TRB */ + if (xhci->quirks & XHCI_MTK_HOST) + trb_buff_len = 0; + + maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc)); + total_packet_count = DIV_ROUND_UP(td_total_len, maxp); + /* Queueing functions don't count the current TRB into transferred */ return (total_packet_count - ((transferred + trb_buff_len) / maxp)); } @@ -3472,7 +3469,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, field |= 0x1; /* xHCI 1.0/1.1 6.4.1.2.1: Transfer Type field */ - if (xhci->hci_version >= 0x100) { + if ((xhci->hci_version >= 0x100) || (xhci->quirks & XHCI_MTK_HOST)) { if (urb->transfer_buffer_length > 0) { if (setup->bRequestType & USB_DIR_IN) field |= TRB_TX_TYPE(TRB_DATA_IN); |