aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-hcd.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-08-07 17:04:55 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 09:46:17 -0400
commitac9d8fe7c6a8041cca5a0738915d2c4e21381421 (patch)
tree6ac3db149d39a61900e6df41ab9424f933a51489 /drivers/usb/host/xhci-hcd.c
parent82d1009f537c2a43be0a410abd33521f76ee3a5a (diff)
USB: xhci: Add quirk for Fresco Logic xHCI hardware.
This Fresco Logic xHCI host controller chip revision puts bad data into the output endpoint context after a Reset Endpoint command. It needs a Configure Endpoint command (instead of a Set TR Dequeue Pointer command) after the reset endpoint command. Set up the input context before issuing the Reset Endpoint command so we don't copy bad data from the output endpoint context. The HW also can't handle two commands queued at once, so submit the TRB for the Configure Endpoint command in the event handler for the Reset Endpoint command. Devices that stall on control endpoints before a configuration is selected will not work under this Fresco Logic xHCI host controller revision. This patch is for prototype hardware that will be given to other companies for evaluation purposes only, and should not reach consumer hands. Fresco Logic's next chip rev should have this bug fixed. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci-hcd.c')
-rw-r--r--drivers/usb/host/xhci-hcd.c77
1 files changed, 68 insertions, 9 deletions
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
index 4353c1c7893..1d4a1e3f953 100644
--- a/drivers/usb/host/xhci-hcd.c
+++ b/drivers/usb/host/xhci-hcd.c
@@ -224,7 +224,7 @@ int xhci_init(struct usb_hcd *hcd)
224 xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n"); 224 xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n");
225 xhci->quirks |= XHCI_LINK_TRB_QUIRK; 225 xhci->quirks |= XHCI_LINK_TRB_QUIRK;
226 } else { 226 } else {
227 xhci_dbg(xhci, "xHCI has no QUIRKS\n"); 227 xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n");
228 } 228 }
229 retval = xhci_mem_init(xhci, GFP_KERNEL); 229 retval = xhci_mem_init(xhci, GFP_KERNEL);
230 xhci_dbg(xhci, "Finished xhci_init\n"); 230 xhci_dbg(xhci, "Finished xhci_init\n");
@@ -567,13 +567,22 @@ unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc)
567 return 1 << (xhci_get_endpoint_index(desc) + 1); 567 return 1 << (xhci_get_endpoint_index(desc) + 1);
568} 568}
569 569
570/* Find the flag for this endpoint (for use in the control context). Use the
571 * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is
572 * bit 1, etc.
573 */
574unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index)
575{
576 return 1 << (ep_index + 1);
577}
578
570/* Compute the last valid endpoint context index. Basically, this is the 579/* Compute the last valid endpoint context index. Basically, this is the
571 * endpoint index plus one. For slot contexts with more than valid endpoint, 580 * endpoint index plus one. For slot contexts with more than valid endpoint,
572 * we find the most significant bit set in the added contexts flags. 581 * we find the most significant bit set in the added contexts flags.
573 * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000 582 * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000
574 * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one. 583 * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one.
575 */ 584 */
576static inline unsigned int xhci_last_valid_endpoint(u32 added_ctxs) 585unsigned int xhci_last_valid_endpoint(u32 added_ctxs)
577{ 586{
578 return fls(added_ctxs) - 1; 587 return fls(added_ctxs) - 1;
579} 588}
@@ -1230,8 +1239,44 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
1230 xhci_zero_in_ctx(xhci, virt_dev); 1239 xhci_zero_in_ctx(xhci, virt_dev);
1231} 1240}
1232 1241
1242void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci,
1243 unsigned int slot_id, unsigned int ep_index,
1244 struct xhci_dequeue_state *deq_state)
1245{
1246 struct xhci_container_ctx *in_ctx;
1247 struct xhci_input_control_ctx *ctrl_ctx;
1248 struct xhci_ep_ctx *ep_ctx;
1249 u32 added_ctxs;
1250 dma_addr_t addr;
1251
1252 xhci_endpoint_copy(xhci, xhci->devs[slot_id], ep_index);
1253 in_ctx = xhci->devs[slot_id]->in_ctx;
1254 ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
1255 addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg,
1256 deq_state->new_deq_ptr);
1257 if (addr == 0) {
1258 xhci_warn(xhci, "WARN Cannot submit config ep after "
1259 "reset ep command\n");
1260 xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n",
1261 deq_state->new_deq_seg,
1262 deq_state->new_deq_ptr);
1263 return;
1264 }
1265 ep_ctx->deq = addr | deq_state->new_cycle_state;
1266
1267 xhci_slot_copy(xhci, xhci->devs[slot_id]);
1268
1269 ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
1270 added_ctxs = xhci_get_endpoint_flag_from_index(ep_index);
1271 ctrl_ctx->add_flags = added_ctxs | SLOT_FLAG;
1272 ctrl_ctx->drop_flags = added_ctxs;
1273
1274 xhci_dbg(xhci, "Slot ID %d Input Context:\n", slot_id);
1275 xhci_dbg_ctx(xhci, in_ctx, ep_index);
1276}
1277
1233void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, 1278void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
1234 struct usb_device *udev, struct usb_host_endpoint *ep, 1279 struct usb_device *udev,
1235 unsigned int ep_index, struct xhci_ring *ep_ring) 1280 unsigned int ep_index, struct xhci_ring *ep_ring)
1236{ 1281{
1237 struct xhci_dequeue_state deq_state; 1282 struct xhci_dequeue_state deq_state;
@@ -1241,12 +1286,26 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
1241 * or it will attempt to resend it on the next doorbell ring. 1286 * or it will attempt to resend it on the next doorbell ring.
1242 */ 1287 */
1243 xhci_find_new_dequeue_state(xhci, udev->slot_id, 1288 xhci_find_new_dequeue_state(xhci, udev->slot_id,
1244 ep_index, ep_ring->stopped_td, &deq_state); 1289 ep_index, ep_ring->stopped_td,
1290 &deq_state);
1245 1291
1246 xhci_dbg(xhci, "Queueing new dequeue state\n"); 1292 /* HW with the reset endpoint quirk will use the saved dequeue state to
1247 xhci_queue_new_dequeue_state(xhci, ep_ring, 1293 * issue a configure endpoint command later.
1248 udev->slot_id, 1294 */
1249 ep_index, &deq_state); 1295 if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) {
1296 xhci_dbg(xhci, "Queueing new dequeue state\n");
1297 xhci_queue_new_dequeue_state(xhci, ep_ring,
1298 udev->slot_id,
1299 ep_index, &deq_state);
1300 } else {
1301 /* Better hope no one uses the input context between now and the
1302 * reset endpoint completion!
1303 */
1304 xhci_dbg(xhci, "Setting up input context for "
1305 "configure endpoint command\n");
1306 xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id,
1307 ep_index, &deq_state);
1308 }
1250} 1309}
1251 1310
1252/* Deal with stalled endpoints. The core should have sent the control message 1311/* Deal with stalled endpoints. The core should have sent the control message
@@ -1293,7 +1352,7 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
1293 * command. Better hope that last command worked! 1352 * command. Better hope that last command worked!
1294 */ 1353 */
1295 if (!ret) { 1354 if (!ret) {
1296 xhci_cleanup_stalled_ring(xhci, udev, ep, ep_index, ep_ring); 1355 xhci_cleanup_stalled_ring(xhci, udev, ep_index, ep_ring);
1297 kfree(ep_ring->stopped_td); 1356 kfree(ep_ring->stopped_td);
1298 xhci_ring_cmd_db(xhci); 1357 xhci_ring_cmd_db(xhci);
1299 } 1358 }