diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-05-10 17:11:19 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-05-10 17:11:32 -0400 |
commit | 8eadef1526886db2a471c432d2c3d154de46f5c6 (patch) | |
tree | c11c8c634f172fd234bba68865baf5c48a365551 | |
parent | 8a1629c771b1a60bc6d73394d869fe69b13200dc (diff) | |
parent | 1bb73a88839d473f4f2c529ecf453029439aa837 (diff) |
Merge branch 'for-usb-next' of git+ssh://master.kernel.org/pub/scm/linux/kernel/git/sarah/xhci into usb-next
* 'for-usb-next' of git+ssh://master.kernel.org/pub/scm/linux/kernel/git/sarah/xhci:
xHCI 1.0: Max Exit Latency Too Large Error
xHCI 1.0: TT_THINK_TIME set
xHCI 1.0: Block Interrupts for Isoch transfer
xHCI 1.0: Isoch endpoint CErr field set
xHCI 1.0: Control endpoint average TRB length field set
xHCI 1.0: Setup Stage TRB Transfer Type flag
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 13 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 16 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 12 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 9 |
4 files changed, 45 insertions, 5 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index a4fc4d929385..04145740686c 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -1190,12 +1190,12 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, | |||
1190 | /* FIXME dig Mult and streams info out of ep companion desc */ | 1190 | /* FIXME dig Mult and streams info out of ep companion desc */ |
1191 | 1191 | ||
1192 | /* Allow 3 retries for everything but isoc; | 1192 | /* Allow 3 retries for everything but isoc; |
1193 | * error count = 0 means infinite retries. | 1193 | * CErr shall be set to 0 for Isoch endpoints. |
1194 | */ | 1194 | */ |
1195 | if (!usb_endpoint_xfer_isoc(&ep->desc)) | 1195 | if (!usb_endpoint_xfer_isoc(&ep->desc)) |
1196 | ep_ctx->ep_info2 = cpu_to_le32(ERROR_COUNT(3)); | 1196 | ep_ctx->ep_info2 = cpu_to_le32(ERROR_COUNT(3)); |
1197 | else | 1197 | else |
1198 | ep_ctx->ep_info2 = cpu_to_le32(ERROR_COUNT(1)); | 1198 | ep_ctx->ep_info2 = cpu_to_le32(ERROR_COUNT(0)); |
1199 | 1199 | ||
1200 | ep_ctx->ep_info2 |= cpu_to_le32(xhci_get_endpoint_type(udev, ep)); | 1200 | ep_ctx->ep_info2 |= cpu_to_le32(xhci_get_endpoint_type(udev, ep)); |
1201 | 1201 | ||
@@ -1246,8 +1246,15 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, | |||
1246 | * including link TRBs, No-op TRBs, and Event data TRBs. Since we don't | 1246 | * including link TRBs, No-op TRBs, and Event data TRBs. Since we don't |
1247 | * use Event Data TRBs, and we don't chain in a link TRB on short | 1247 | * use Event Data TRBs, and we don't chain in a link TRB on short |
1248 | * transfers, we're basically dividing by 1. | 1248 | * transfers, we're basically dividing by 1. |
1249 | * | ||
1250 | * xHCI 1.0 specification indicates that the Average TRB Length should | ||
1251 | * be set to 8 for control endpoints. | ||
1249 | */ | 1252 | */ |
1250 | ep_ctx->tx_info |= cpu_to_le32(AVG_TRB_LENGTH_FOR_EP(max_esit_payload)); | 1253 | if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version == 0x100) |
1254 | ep_ctx->tx_info |= cpu_to_le32(AVG_TRB_LENGTH_FOR_EP(8)); | ||
1255 | else | ||
1256 | ep_ctx->tx_info |= | ||
1257 | cpu_to_le32(AVG_TRB_LENGTH_FOR_EP(max_esit_payload)); | ||
1251 | 1258 | ||
1252 | /* FIXME Debug endpoint context */ | 1259 | /* FIXME Debug endpoint context */ |
1253 | return 0; | 1260 | return 0; |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 396f8d2a2e8d..c35058b94de6 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -3053,6 +3053,17 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
3053 | field |= TRB_IDT | TRB_TYPE(TRB_SETUP); | 3053 | field |= TRB_IDT | TRB_TYPE(TRB_SETUP); |
3054 | if (start_cycle == 0) | 3054 | if (start_cycle == 0) |
3055 | field |= 0x1; | 3055 | field |= 0x1; |
3056 | |||
3057 | /* xHCI 1.0 6.4.1.2.1: Transfer Type field */ | ||
3058 | if (xhci->hci_version == 0x100) { | ||
3059 | if (urb->transfer_buffer_length > 0) { | ||
3060 | if (setup->bRequestType & USB_DIR_IN) | ||
3061 | field |= TRB_TX_TYPE(TRB_DATA_IN); | ||
3062 | else | ||
3063 | field |= TRB_TX_TYPE(TRB_DATA_OUT); | ||
3064 | } | ||
3065 | } | ||
3066 | |||
3056 | queue_trb(xhci, ep_ring, false, true, | 3067 | queue_trb(xhci, ep_ring, false, true, |
3057 | setup->bRequestType | setup->bRequest << 8 | le16_to_cpu(setup->wValue) << 16, | 3068 | setup->bRequestType | setup->bRequest << 8 | le16_to_cpu(setup->wValue) << 16, |
3058 | le16_to_cpu(setup->wIndex) | le16_to_cpu(setup->wLength) << 16, | 3069 | le16_to_cpu(setup->wIndex) | le16_to_cpu(setup->wLength) << 16, |
@@ -3282,6 +3293,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
3282 | } else { | 3293 | } else { |
3283 | td->last_trb = ep_ring->enqueue; | 3294 | td->last_trb = ep_ring->enqueue; |
3284 | field |= TRB_IOC; | 3295 | field |= TRB_IOC; |
3296 | if (xhci->hci_version == 0x100) { | ||
3297 | /* Set BEI bit except for the last td */ | ||
3298 | if (i < num_tds - 1) | ||
3299 | field |= TRB_BEI; | ||
3300 | } | ||
3285 | more_trbs_coming = false; | 3301 | more_trbs_coming = false; |
3286 | } | 3302 | } |
3287 | 3303 | ||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 6864759c8d1a..013e113b818a 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -1560,6 +1560,11 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci, | |||
1560 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); | 1560 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); |
1561 | ret = -EINVAL; | 1561 | ret = -EINVAL; |
1562 | break; | 1562 | break; |
1563 | case COMP_MEL_ERR: | ||
1564 | /* Max Exit Latency too large error */ | ||
1565 | dev_warn(&udev->dev, "WARN: Max Exit Latency too large\n"); | ||
1566 | ret = -EINVAL; | ||
1567 | break; | ||
1563 | case COMP_SUCCESS: | 1568 | case COMP_SUCCESS: |
1564 | dev_dbg(&udev->dev, "Successful evaluate context command\n"); | 1569 | dev_dbg(&udev->dev, "Successful evaluate context command\n"); |
1565 | ret = 0; | 1570 | ret = 0; |
@@ -2699,11 +2704,16 @@ int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, | |||
2699 | /* Set TT think time - convert from ns to FS bit times. | 2704 | /* Set TT think time - convert from ns to FS bit times. |
2700 | * 0 = 8 FS bit times, 1 = 16 FS bit times, | 2705 | * 0 = 8 FS bit times, 1 = 16 FS bit times, |
2701 | * 2 = 24 FS bit times, 3 = 32 FS bit times. | 2706 | * 2 = 24 FS bit times, 3 = 32 FS bit times. |
2707 | * | ||
2708 | * xHCI 1.0: this field shall be 0 if the device is not a | ||
2709 | * High-spped hub. | ||
2702 | */ | 2710 | */ |
2703 | think_time = tt->think_time; | 2711 | think_time = tt->think_time; |
2704 | if (think_time != 0) | 2712 | if (think_time != 0) |
2705 | think_time = (think_time / 666) - 1; | 2713 | think_time = (think_time / 666) - 1; |
2706 | slot_ctx->tt_info |= cpu_to_le32(TT_THINK_TIME(think_time)); | 2714 | if (xhci->hci_version < 0x100 || hdev->speed == USB_SPEED_HIGH) |
2715 | slot_ctx->tt_info |= | ||
2716 | cpu_to_le32(TT_THINK_TIME(think_time)); | ||
2707 | } else { | 2717 | } else { |
2708 | xhci_dbg(xhci, "xHCI version %x doesn't need hub " | 2718 | xhci_dbg(xhci, "xHCI version %x doesn't need hub " |
2709 | "TT think time or number of ports\n", | 2719 | "TT think time or number of ports\n", |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index db661543a805..e12db7cfb9bb 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -881,7 +881,9 @@ struct xhci_transfer_event { | |||
881 | #define COMP_STOP_INVAL 27 | 881 | #define COMP_STOP_INVAL 27 |
882 | /* Control Abort Error - Debug Capability - control pipe aborted */ | 882 | /* Control Abort Error - Debug Capability - control pipe aborted */ |
883 | #define COMP_DBG_ABORT 28 | 883 | #define COMP_DBG_ABORT 28 |
884 | /* TRB type 29 and 30 reserved */ | 884 | /* Max Exit Latency Too Large Error */ |
885 | #define COMP_MEL_ERR 29 | ||
886 | /* TRB type 30 reserved */ | ||
885 | /* Isoc Buffer Overrun - an isoc IN ep sent more data than could fit in TD */ | 887 | /* Isoc Buffer Overrun - an isoc IN ep sent more data than could fit in TD */ |
886 | #define COMP_BUFF_OVER 31 | 888 | #define COMP_BUFF_OVER 31 |
887 | /* Event Lost Error - xHC has an "internal event overrun condition" */ | 889 | /* Event Lost Error - xHC has an "internal event overrun condition" */ |
@@ -964,9 +966,14 @@ struct xhci_event_cmd { | |||
964 | /* The buffer pointer contains immediate data */ | 966 | /* The buffer pointer contains immediate data */ |
965 | #define TRB_IDT (1<<6) | 967 | #define TRB_IDT (1<<6) |
966 | 968 | ||
969 | /* Block Event Interrupt */ | ||
970 | #define TRB_BEI (1<<9) | ||
967 | 971 | ||
968 | /* Control transfer TRB specific fields */ | 972 | /* Control transfer TRB specific fields */ |
969 | #define TRB_DIR_IN (1<<16) | 973 | #define TRB_DIR_IN (1<<16) |
974 | #define TRB_TX_TYPE(p) ((p) << 16) | ||
975 | #define TRB_DATA_OUT 2 | ||
976 | #define TRB_DATA_IN 3 | ||
970 | 977 | ||
971 | /* Isochronous TRB specific fields */ | 978 | /* Isochronous TRB specific fields */ |
972 | #define TRB_SIA (1<<31) | 979 | #define TRB_SIA (1<<31) |