diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/xhci.c | 26 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 3 |
2 files changed, 22 insertions, 7 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 3f0763d63598..b95e3e8a293e 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -2402,6 +2402,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
2402 | struct completion *cmd_completion; | 2402 | struct completion *cmd_completion; |
2403 | u32 *cmd_status; | 2403 | u32 *cmd_status; |
2404 | struct xhci_virt_device *virt_dev; | 2404 | struct xhci_virt_device *virt_dev; |
2405 | union xhci_trb *cmd_trb; | ||
2405 | 2406 | ||
2406 | spin_lock_irqsave(&xhci->lock, flags); | 2407 | spin_lock_irqsave(&xhci->lock, flags); |
2407 | virt_dev = xhci->devs[udev->slot_id]; | 2408 | virt_dev = xhci->devs[udev->slot_id]; |
@@ -2447,6 +2448,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
2447 | } | 2448 | } |
2448 | init_completion(cmd_completion); | 2449 | init_completion(cmd_completion); |
2449 | 2450 | ||
2451 | cmd_trb = xhci->cmd_ring->dequeue; | ||
2450 | if (!ctx_change) | 2452 | if (!ctx_change) |
2451 | ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, | 2453 | ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, |
2452 | udev->slot_id, must_succeed); | 2454 | udev->slot_id, must_succeed); |
@@ -2468,14 +2470,17 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
2468 | /* Wait for the configure endpoint command to complete */ | 2470 | /* Wait for the configure endpoint command to complete */ |
2469 | timeleft = wait_for_completion_interruptible_timeout( | 2471 | timeleft = wait_for_completion_interruptible_timeout( |
2470 | cmd_completion, | 2472 | cmd_completion, |
2471 | USB_CTRL_SET_TIMEOUT); | 2473 | XHCI_CMD_DEFAULT_TIMEOUT); |
2472 | if (timeleft <= 0) { | 2474 | if (timeleft <= 0) { |
2473 | xhci_warn(xhci, "%s while waiting for %s command\n", | 2475 | xhci_warn(xhci, "%s while waiting for %s command\n", |
2474 | timeleft == 0 ? "Timeout" : "Signal", | 2476 | timeleft == 0 ? "Timeout" : "Signal", |
2475 | ctx_change == 0 ? | 2477 | ctx_change == 0 ? |
2476 | "configure endpoint" : | 2478 | "configure endpoint" : |
2477 | "evaluate context"); | 2479 | "evaluate context"); |
2478 | /* FIXME cancel the configure endpoint command */ | 2480 | /* cancel the configure endpoint command */ |
2481 | ret = xhci_cancel_cmd(xhci, command, cmd_trb); | ||
2482 | if (ret < 0) | ||
2483 | return ret; | ||
2479 | return -ETIME; | 2484 | return -ETIME; |
2480 | } | 2485 | } |
2481 | 2486 | ||
@@ -3424,8 +3429,10 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
3424 | unsigned long flags; | 3429 | unsigned long flags; |
3425 | int timeleft; | 3430 | int timeleft; |
3426 | int ret; | 3431 | int ret; |
3432 | union xhci_trb *cmd_trb; | ||
3427 | 3433 | ||
3428 | spin_lock_irqsave(&xhci->lock, flags); | 3434 | spin_lock_irqsave(&xhci->lock, flags); |
3435 | cmd_trb = xhci->cmd_ring->dequeue; | ||
3429 | ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); | 3436 | ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); |
3430 | if (ret) { | 3437 | if (ret) { |
3431 | spin_unlock_irqrestore(&xhci->lock, flags); | 3438 | spin_unlock_irqrestore(&xhci->lock, flags); |
@@ -3437,12 +3444,12 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
3437 | 3444 | ||
3438 | /* XXX: how much time for xHC slot assignment? */ | 3445 | /* XXX: how much time for xHC slot assignment? */ |
3439 | timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, | 3446 | timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, |
3440 | USB_CTRL_SET_TIMEOUT); | 3447 | XHCI_CMD_DEFAULT_TIMEOUT); |
3441 | if (timeleft <= 0) { | 3448 | if (timeleft <= 0) { |
3442 | xhci_warn(xhci, "%s while waiting for a slot\n", | 3449 | xhci_warn(xhci, "%s while waiting for a slot\n", |
3443 | timeleft == 0 ? "Timeout" : "Signal"); | 3450 | timeleft == 0 ? "Timeout" : "Signal"); |
3444 | /* FIXME cancel the enable slot request */ | 3451 | /* cancel the enable slot request */ |
3445 | return 0; | 3452 | return xhci_cancel_cmd(xhci, NULL, cmd_trb); |
3446 | } | 3453 | } |
3447 | 3454 | ||
3448 | if (!xhci->slot_id) { | 3455 | if (!xhci->slot_id) { |
@@ -3503,6 +3510,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3503 | struct xhci_slot_ctx *slot_ctx; | 3510 | struct xhci_slot_ctx *slot_ctx; |
3504 | struct xhci_input_control_ctx *ctrl_ctx; | 3511 | struct xhci_input_control_ctx *ctrl_ctx; |
3505 | u64 temp_64; | 3512 | u64 temp_64; |
3513 | union xhci_trb *cmd_trb; | ||
3506 | 3514 | ||
3507 | if (!udev->slot_id) { | 3515 | if (!udev->slot_id) { |
3508 | xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id); | 3516 | xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id); |
@@ -3541,6 +3549,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3541 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); | 3549 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); |
3542 | 3550 | ||
3543 | spin_lock_irqsave(&xhci->lock, flags); | 3551 | spin_lock_irqsave(&xhci->lock, flags); |
3552 | cmd_trb = xhci->cmd_ring->dequeue; | ||
3544 | ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, | 3553 | ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, |
3545 | udev->slot_id); | 3554 | udev->slot_id); |
3546 | if (ret) { | 3555 | if (ret) { |
@@ -3553,7 +3562,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3553 | 3562 | ||
3554 | /* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */ | 3563 | /* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */ |
3555 | timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, | 3564 | timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, |
3556 | USB_CTRL_SET_TIMEOUT); | 3565 | XHCI_CMD_DEFAULT_TIMEOUT); |
3557 | /* FIXME: From section 4.3.4: "Software shall be responsible for timing | 3566 | /* FIXME: From section 4.3.4: "Software shall be responsible for timing |
3558 | * the SetAddress() "recovery interval" required by USB and aborting the | 3567 | * the SetAddress() "recovery interval" required by USB and aborting the |
3559 | * command on a timeout. | 3568 | * command on a timeout. |
@@ -3561,7 +3570,10 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3561 | if (timeleft <= 0) { | 3570 | if (timeleft <= 0) { |
3562 | xhci_warn(xhci, "%s while waiting for address device command\n", | 3571 | xhci_warn(xhci, "%s while waiting for address device command\n", |
3563 | timeleft == 0 ? "Timeout" : "Signal"); | 3572 | timeleft == 0 ? "Timeout" : "Signal"); |
3564 | /* FIXME cancel the address device command */ | 3573 | /* cancel the address device command */ |
3574 | ret = xhci_cancel_cmd(xhci, NULL, cmd_trb); | ||
3575 | if (ret < 0) | ||
3576 | return ret; | ||
3565 | return -ETIME; | 3577 | return -ETIME; |
3566 | } | 3578 | } |
3567 | 3579 | ||
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index fdfcebf342e8..e81ccfa3552f 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1256,6 +1256,9 @@ struct xhci_td { | |||
1256 | union xhci_trb *last_trb; | 1256 | union xhci_trb *last_trb; |
1257 | }; | 1257 | }; |
1258 | 1258 | ||
1259 | /* xHCI command default timeout value */ | ||
1260 | #define XHCI_CMD_DEFAULT_TIMEOUT (5 * HZ) | ||
1261 | |||
1259 | /* command descriptor */ | 1262 | /* command descriptor */ |
1260 | struct xhci_cd { | 1263 | struct xhci_cd { |
1261 | struct list_head cancel_cmd_list; | 1264 | struct list_head cancel_cmd_list; |