* seconds), then it should assume that the there are
* larger problems with the xHC and assert HCRST.
*/
- ret = handshake(xhci, &xhci->op_regs->cmd_ring,
+ ret = xhci_handshake(xhci, &xhci->op_regs->cmd_ring,
CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
if (ret < 0) {
xhci_err(xhci, "Stopped the command ring failed, "
if (bogus_port_status)
return;
+ /*
+ * xHCI port-status-change events occur when the "or" of all the
+ * status-change bits in the portsc register changes from 0 to 1.
+ * New status changes won't cause an event if any other change
+ * bits are still set. When an event occurs, switch over to
+ * polling to avoid losing status changes.
+ */
+ xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
+ set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
spin_unlock(&xhci->lock);
/* Pass this up to the core */
usb_hcd_poll_rh_status(hcd);
}
/*
- * For xHCI 1.0 host controllers, TD size is the number of packets remaining in
- * the TD (*not* including this TRB).
+ * For xHCI 1.0 host controllers, TD size is the number of max packet sized
+ * packets remaining in the TD (*not* including this TRB).
*
* Total TD packet count = total_packet_count =
- * roundup(TD size in bytes / wMaxPacketSize)
+ * DIV_ROUND_UP(TD size in bytes / wMaxPacketSize)
*
* Packets transferred up to and including this TRB = packets_transferred =
* rounddown(total bytes transferred including this TRB / wMaxPacketSize)
* TD size = total_packet_count - packets_transferred
*
* It must fit in bits 21:17, so it can't be bigger than 31.
+ * The last TRB in a TD must have the TD size set to zero.
*/
-
static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
- unsigned int total_packet_count, struct urb *urb)
+ unsigned int total_packet_count, struct urb *urb,
+ unsigned int num_trbs_left)
{
int packets_transferred;
/* One TRB with a zero-length data packet. */
- if (running_total == 0 && trb_buff_len == 0)
+ if (num_trbs_left == 0 || (running_total == 0 && trb_buff_len == 0))
return 0;
/* All the TRB queueing functions don't count the current TRB in
packets_transferred = (running_total + trb_buff_len) /
usb_endpoint_maxp(&urb->ep->desc);
- return xhci_td_remainder(total_packet_count - packets_transferred);
+ if ((total_packet_count - packets_transferred) > 31)
+ return 31 << 17;
+ return (total_packet_count - packets_transferred) << 17;
}
static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
num_trbs = count_sg_trbs_needed(xhci, urb);
num_sgs = urb->num_mapped_sgs;
- total_packet_count = roundup(urb->transfer_buffer_length,
+ total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
usb_endpoint_maxp(&urb->ep->desc));
trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
running_total);
} else {
remainder = xhci_v1_0_td_remainder(running_total,
- trb_buff_len, total_packet_count, urb);
+ trb_buff_len, total_packet_count, urb,
+ num_trbs - 1);
}
length_field = TRB_LEN(trb_buff_len) |
remainder |
start_cycle = ep_ring->cycle_state;
running_total = 0;
- total_packet_count = roundup(urb->transfer_buffer_length,
+ total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
usb_endpoint_maxp(&urb->ep->desc));
/* How much data is in the first TRB? */
addr = (u64) urb->transfer_dma;
running_total);
} else {
remainder = xhci_v1_0_td_remainder(running_total,
- trb_buff_len, total_packet_count, urb);
+ trb_buff_len, total_packet_count, urb,
+ num_trbs - 1);
}
length_field = TRB_LEN(trb_buff_len) |
remainder |
addr = start_addr + urb->iso_frame_desc[i].offset;
td_len = urb->iso_frame_desc[i].length;
td_remain_len = td_len;
- total_packet_count = roundup(td_len,
+ total_packet_count = DIV_ROUND_UP(td_len,
usb_endpoint_maxp(&urb->ep->desc));
/* A zero-length transfer still involves at least one packet. */
if (total_packet_count == 0)
} else {
remainder = xhci_v1_0_td_remainder(
running_total, trb_buff_len,
- total_packet_count, urb);
+ total_packet_count, urb,
+ (trbs_per_td - j - 1));
}
length_field = TRB_LEN(trb_buff_len) |
remainder |