diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/xhci-hub.c | 196 | ||||
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 44 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 17 |
5 files changed, 248 insertions, 12 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index a1a7a9795536..14b48b261e06 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -129,6 +129,99 @@ static u32 xhci_port_state_to_neutral(u32 state) | |||
129 | return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS); | 129 | return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS); |
130 | } | 130 | } |
131 | 131 | ||
132 | /* | ||
133 | * find slot id based on port number. | ||
134 | */ | ||
135 | static int xhci_find_slot_id_by_port(struct xhci_hcd *xhci, u16 port) | ||
136 | { | ||
137 | int slot_id; | ||
138 | int i; | ||
139 | |||
140 | slot_id = 0; | ||
141 | for (i = 0; i < MAX_HC_SLOTS; i++) { | ||
142 | if (!xhci->devs[i]) | ||
143 | continue; | ||
144 | if (xhci->devs[i]->port == port) { | ||
145 | slot_id = i; | ||
146 | break; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | return slot_id; | ||
151 | } | ||
152 | |||
153 | /* | ||
154 | * Stop device | ||
155 | * It issues stop endpoint command for EP 0 to 30. And wait the last command | ||
156 | * to complete. | ||
157 | * suspend will set to 1, if suspend bit need to set in command. | ||
158 | */ | ||
159 | static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) | ||
160 | { | ||
161 | struct xhci_virt_device *virt_dev; | ||
162 | struct xhci_command *cmd; | ||
163 | unsigned long flags; | ||
164 | int timeleft; | ||
165 | int ret; | ||
166 | int i; | ||
167 | |||
168 | ret = 0; | ||
169 | virt_dev = xhci->devs[slot_id]; | ||
170 | cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO); | ||
171 | if (!cmd) { | ||
172 | xhci_dbg(xhci, "Couldn't allocate command structure.\n"); | ||
173 | return -ENOMEM; | ||
174 | } | ||
175 | |||
176 | spin_lock_irqsave(&xhci->lock, flags); | ||
177 | for (i = LAST_EP_INDEX; i > 0; i--) { | ||
178 | if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) | ||
179 | xhci_queue_stop_endpoint(xhci, slot_id, i, suspend); | ||
180 | } | ||
181 | cmd->command_trb = xhci->cmd_ring->enqueue; | ||
182 | list_add_tail(&cmd->cmd_list, &virt_dev->cmd_list); | ||
183 | xhci_queue_stop_endpoint(xhci, slot_id, 0, suspend); | ||
184 | xhci_ring_cmd_db(xhci); | ||
185 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
186 | |||
187 | /* Wait for last stop endpoint command to finish */ | ||
188 | timeleft = wait_for_completion_interruptible_timeout( | ||
189 | cmd->completion, | ||
190 | USB_CTRL_SET_TIMEOUT); | ||
191 | if (timeleft <= 0) { | ||
192 | xhci_warn(xhci, "%s while waiting for stop endpoint command\n", | ||
193 | timeleft == 0 ? "Timeout" : "Signal"); | ||
194 | spin_lock_irqsave(&xhci->lock, flags); | ||
195 | /* The timeout might have raced with the event ring handler, so | ||
196 | * only delete from the list if the item isn't poisoned. | ||
197 | */ | ||
198 | if (cmd->cmd_list.next != LIST_POISON1) | ||
199 | list_del(&cmd->cmd_list); | ||
200 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
201 | ret = -ETIME; | ||
202 | goto command_cleanup; | ||
203 | } | ||
204 | |||
205 | command_cleanup: | ||
206 | xhci_free_command(xhci, cmd); | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | /* | ||
211 | * Ring device, it rings the all doorbells unconditionally. | ||
212 | */ | ||
213 | static void xhci_ring_device(struct xhci_hcd *xhci, int slot_id) | ||
214 | { | ||
215 | int i; | ||
216 | |||
217 | for (i = 0; i < LAST_EP_INDEX + 1; i++) | ||
218 | if (xhci->devs[slot_id]->eps[i].ring && | ||
219 | xhci->devs[slot_id]->eps[i].ring->dequeue) | ||
220 | xhci_ring_ep_doorbell(xhci, slot_id, i, 0); | ||
221 | |||
222 | return; | ||
223 | } | ||
224 | |||
132 | static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex, | 225 | static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex, |
133 | u32 __iomem *addr, u32 port_status) | 226 | u32 __iomem *addr, u32 port_status) |
134 | { | 227 | { |
@@ -162,6 +255,10 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, | |||
162 | status = PORT_PEC; | 255 | status = PORT_PEC; |
163 | port_change_bit = "enable/disable"; | 256 | port_change_bit = "enable/disable"; |
164 | break; | 257 | break; |
258 | case USB_PORT_FEAT_C_SUSPEND: | ||
259 | status = PORT_PLC; | ||
260 | port_change_bit = "suspend/resume"; | ||
261 | break; | ||
165 | default: | 262 | default: |
166 | /* Should never happen */ | 263 | /* Should never happen */ |
167 | return; | 264 | return; |
@@ -182,6 +279,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
182 | u32 temp, status; | 279 | u32 temp, status; |
183 | int retval = 0; | 280 | int retval = 0; |
184 | u32 __iomem *addr; | 281 | u32 __iomem *addr; |
282 | int slot_id; | ||
185 | 283 | ||
186 | ports = HCS_MAX_PORTS(xhci->hcs_params1); | 284 | ports = HCS_MAX_PORTS(xhci->hcs_params1); |
187 | 285 | ||
@@ -211,9 +309,21 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
211 | if ((temp & PORT_OCC)) | 309 | if ((temp & PORT_OCC)) |
212 | status |= USB_PORT_STAT_C_OVERCURRENT << 16; | 310 | status |= USB_PORT_STAT_C_OVERCURRENT << 16; |
213 | /* | 311 | /* |
214 | * FIXME ignoring suspend, reset, and USB 2.1/3.0 specific | 312 | * FIXME ignoring reset and USB 2.1/3.0 specific |
215 | * changes | 313 | * changes |
216 | */ | 314 | */ |
315 | if ((temp & PORT_PLS_MASK) == XDEV_U3 | ||
316 | && (temp & PORT_POWER)) | ||
317 | status |= 1 << USB_PORT_FEAT_SUSPEND; | ||
318 | if ((temp & PORT_PLS_MASK) == XDEV_U0 | ||
319 | && (temp & PORT_POWER) | ||
320 | && (xhci->suspended_ports[wIndex >> 5] & | ||
321 | (1 << (wIndex & 31)))) { | ||
322 | xhci->suspended_ports[wIndex >> 5] &= | ||
323 | ~(1 << (wIndex & 31)); | ||
324 | xhci->port_c_suspend[wIndex >> 5] |= | ||
325 | 1 << (wIndex & 31); | ||
326 | } | ||
217 | if (temp & PORT_CONNECT) { | 327 | if (temp & PORT_CONNECT) { |
218 | status |= USB_PORT_STAT_CONNECTION; | 328 | status |= USB_PORT_STAT_CONNECTION; |
219 | status |= xhci_port_speed(temp); | 329 | status |= xhci_port_speed(temp); |
@@ -226,6 +336,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
226 | status |= USB_PORT_STAT_RESET; | 336 | status |= USB_PORT_STAT_RESET; |
227 | if (temp & PORT_POWER) | 337 | if (temp & PORT_POWER) |
228 | status |= USB_PORT_STAT_POWER; | 338 | status |= USB_PORT_STAT_POWER; |
339 | if (xhci->port_c_suspend[wIndex >> 5] & (1 << (wIndex & 31))) | ||
340 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | ||
229 | xhci_dbg(xhci, "Get port status returned 0x%x\n", status); | 341 | xhci_dbg(xhci, "Get port status returned 0x%x\n", status); |
230 | put_unaligned(cpu_to_le32(status), (__le32 *) buf); | 342 | put_unaligned(cpu_to_le32(status), (__le32 *) buf); |
231 | break; | 343 | break; |
@@ -238,6 +350,42 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
238 | temp = xhci_readl(xhci, addr); | 350 | temp = xhci_readl(xhci, addr); |
239 | temp = xhci_port_state_to_neutral(temp); | 351 | temp = xhci_port_state_to_neutral(temp); |
240 | switch (wValue) { | 352 | switch (wValue) { |
353 | case USB_PORT_FEAT_SUSPEND: | ||
354 | temp = xhci_readl(xhci, addr); | ||
355 | /* In spec software should not attempt to suspend | ||
356 | * a port unless the port reports that it is in the | ||
357 | * enabled (PED = ‘1’,PLS < ‘3’) state. | ||
358 | */ | ||
359 | if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) | ||
360 | || (temp & PORT_PLS_MASK) >= XDEV_U3) { | ||
361 | xhci_warn(xhci, "USB core suspending device " | ||
362 | "not in U0/U1/U2.\n"); | ||
363 | goto error; | ||
364 | } | ||
365 | |||
366 | slot_id = xhci_find_slot_id_by_port(xhci, wIndex + 1); | ||
367 | if (!slot_id) { | ||
368 | xhci_warn(xhci, "slot_id is zero\n"); | ||
369 | goto error; | ||
370 | } | ||
371 | /* unlock to execute stop endpoint commands */ | ||
372 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
373 | xhci_stop_device(xhci, slot_id, 1); | ||
374 | spin_lock_irqsave(&xhci->lock, flags); | ||
375 | |||
376 | temp = xhci_port_state_to_neutral(temp); | ||
377 | temp &= ~PORT_PLS_MASK; | ||
378 | temp |= PORT_LINK_STROBE | XDEV_U3; | ||
379 | xhci_writel(xhci, temp, addr); | ||
380 | |||
381 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
382 | msleep(10); /* wait device to enter */ | ||
383 | spin_lock_irqsave(&xhci->lock, flags); | ||
384 | |||
385 | temp = xhci_readl(xhci, addr); | ||
386 | xhci->suspended_ports[wIndex >> 5] |= | ||
387 | 1 << (wIndex & (31)); | ||
388 | break; | ||
241 | case USB_PORT_FEAT_POWER: | 389 | case USB_PORT_FEAT_POWER: |
242 | /* | 390 | /* |
243 | * Turn on ports, even if there isn't per-port switching. | 391 | * Turn on ports, even if there isn't per-port switching. |
@@ -271,6 +419,52 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
271 | temp = xhci_readl(xhci, addr); | 419 | temp = xhci_readl(xhci, addr); |
272 | temp = xhci_port_state_to_neutral(temp); | 420 | temp = xhci_port_state_to_neutral(temp); |
273 | switch (wValue) { | 421 | switch (wValue) { |
422 | case USB_PORT_FEAT_SUSPEND: | ||
423 | temp = xhci_readl(xhci, addr); | ||
424 | xhci_dbg(xhci, "clear USB_PORT_FEAT_SUSPEND\n"); | ||
425 | xhci_dbg(xhci, "PORTSC %04x\n", temp); | ||
426 | if (temp & PORT_RESET) | ||
427 | goto error; | ||
428 | if (temp & XDEV_U3) { | ||
429 | if ((temp & PORT_PE) == 0) | ||
430 | goto error; | ||
431 | if (DEV_SUPERSPEED(temp)) { | ||
432 | temp = xhci_port_state_to_neutral(temp); | ||
433 | temp &= ~PORT_PLS_MASK; | ||
434 | temp |= PORT_LINK_STROBE | XDEV_U0; | ||
435 | xhci_writel(xhci, temp, addr); | ||
436 | xhci_readl(xhci, addr); | ||
437 | } else { | ||
438 | temp = xhci_port_state_to_neutral(temp); | ||
439 | temp &= ~PORT_PLS_MASK; | ||
440 | temp |= PORT_LINK_STROBE | XDEV_RESUME; | ||
441 | xhci_writel(xhci, temp, addr); | ||
442 | |||
443 | spin_unlock_irqrestore(&xhci->lock, | ||
444 | flags); | ||
445 | msleep(20); | ||
446 | spin_lock_irqsave(&xhci->lock, flags); | ||
447 | |||
448 | temp = xhci_readl(xhci, addr); | ||
449 | temp = xhci_port_state_to_neutral(temp); | ||
450 | temp &= ~PORT_PLS_MASK; | ||
451 | temp |= PORT_LINK_STROBE | XDEV_U0; | ||
452 | xhci_writel(xhci, temp, addr); | ||
453 | } | ||
454 | xhci->port_c_suspend[wIndex >> 5] |= | ||
455 | 1 << (wIndex & 31); | ||
456 | } | ||
457 | |||
458 | slot_id = xhci_find_slot_id_by_port(xhci, wIndex + 1); | ||
459 | if (!slot_id) { | ||
460 | xhci_dbg(xhci, "slot_id is zero\n"); | ||
461 | goto error; | ||
462 | } | ||
463 | xhci_ring_device(xhci, slot_id); | ||
464 | break; | ||
465 | case USB_PORT_FEAT_C_SUSPEND: | ||
466 | xhci->port_c_suspend[wIndex >> 5] &= | ||
467 | ~(1 << (wIndex & 31)); | ||
274 | case USB_PORT_FEAT_C_RESET: | 468 | case USB_PORT_FEAT_C_RESET: |
275 | case USB_PORT_FEAT_C_CONNECTION: | 469 | case USB_PORT_FEAT_C_CONNECTION: |
276 | case USB_PORT_FEAT_C_OVER_CURRENT: | 470 | case USB_PORT_FEAT_C_OVER_CURRENT: |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index be901808e474..858a82867e1d 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -867,6 +867,7 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
867 | top_dev = top_dev->parent) | 867 | top_dev = top_dev->parent) |
868 | /* Found device below root hub */; | 868 | /* Found device below root hub */; |
869 | slot_ctx->dev_info2 |= (u32) ROOT_HUB_PORT(top_dev->portnum); | 869 | slot_ctx->dev_info2 |= (u32) ROOT_HUB_PORT(top_dev->portnum); |
870 | dev->port = top_dev->portnum; | ||
870 | xhci_dbg(xhci, "Set root hub portnum to %d\n", top_dev->portnum); | 871 | xhci_dbg(xhci, "Set root hub portnum to %d\n", top_dev->portnum); |
871 | 872 | ||
872 | /* Is this a LS/FS device under a HS hub? */ | 873 | /* Is this a LS/FS device under a HS hub? */ |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 48e60d166ff0..b18e00ecb468 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -68,6 +68,10 @@ | |||
68 | #include <linux/slab.h> | 68 | #include <linux/slab.h> |
69 | #include "xhci.h" | 69 | #include "xhci.h" |
70 | 70 | ||
71 | static int handle_cmd_in_cmd_wait_list(struct xhci_hcd *xhci, | ||
72 | struct xhci_virt_device *virt_dev, | ||
73 | struct xhci_event_cmd *event); | ||
74 | |||
71 | /* | 75 | /* |
72 | * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA | 76 | * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA |
73 | * address of the TRB. | 77 | * address of the TRB. |
@@ -313,7 +317,7 @@ void xhci_ring_cmd_db(struct xhci_hcd *xhci) | |||
313 | xhci_readl(xhci, &xhci->dba->doorbell[0]); | 317 | xhci_readl(xhci, &xhci->dba->doorbell[0]); |
314 | } | 318 | } |
315 | 319 | ||
316 | static void ring_ep_doorbell(struct xhci_hcd *xhci, | 320 | void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, |
317 | unsigned int slot_id, | 321 | unsigned int slot_id, |
318 | unsigned int ep_index, | 322 | unsigned int ep_index, |
319 | unsigned int stream_id) | 323 | unsigned int stream_id) |
@@ -353,7 +357,7 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci, | |||
353 | /* A ring has pending URBs if its TD list is not empty */ | 357 | /* A ring has pending URBs if its TD list is not empty */ |
354 | if (!(ep->ep_state & EP_HAS_STREAMS)) { | 358 | if (!(ep->ep_state & EP_HAS_STREAMS)) { |
355 | if (!(list_empty(&ep->ring->td_list))) | 359 | if (!(list_empty(&ep->ring->td_list))) |
356 | ring_ep_doorbell(xhci, slot_id, ep_index, 0); | 360 | xhci_ring_ep_doorbell(xhci, slot_id, ep_index, 0); |
357 | return; | 361 | return; |
358 | } | 362 | } |
359 | 363 | ||
@@ -361,7 +365,8 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci, | |||
361 | stream_id++) { | 365 | stream_id++) { |
362 | struct xhci_stream_info *stream_info = ep->stream_info; | 366 | struct xhci_stream_info *stream_info = ep->stream_info; |
363 | if (!list_empty(&stream_info->stream_rings[stream_id]->td_list)) | 367 | if (!list_empty(&stream_info->stream_rings[stream_id]->td_list)) |
364 | ring_ep_doorbell(xhci, slot_id, ep_index, stream_id); | 368 | xhci_ring_ep_doorbell(xhci, slot_id, ep_index, |
369 | stream_id); | ||
365 | } | 370 | } |
366 | } | 371 | } |
367 | 372 | ||
@@ -626,10 +631,11 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, | |||
626 | * bit cleared) so that the HW will skip over them. | 631 | * bit cleared) so that the HW will skip over them. |
627 | */ | 632 | */ |
628 | static void handle_stopped_endpoint(struct xhci_hcd *xhci, | 633 | static void handle_stopped_endpoint(struct xhci_hcd *xhci, |
629 | union xhci_trb *trb) | 634 | union xhci_trb *trb, struct xhci_event_cmd *event) |
630 | { | 635 | { |
631 | unsigned int slot_id; | 636 | unsigned int slot_id; |
632 | unsigned int ep_index; | 637 | unsigned int ep_index; |
638 | struct xhci_virt_device *virt_dev; | ||
633 | struct xhci_ring *ep_ring; | 639 | struct xhci_ring *ep_ring; |
634 | struct xhci_virt_ep *ep; | 640 | struct xhci_virt_ep *ep; |
635 | struct list_head *entry; | 641 | struct list_head *entry; |
@@ -638,6 +644,21 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, | |||
638 | 644 | ||
639 | struct xhci_dequeue_state deq_state; | 645 | struct xhci_dequeue_state deq_state; |
640 | 646 | ||
647 | if (unlikely(TRB_TO_SUSPEND_PORT( | ||
648 | xhci->cmd_ring->dequeue->generic.field[3]))) { | ||
649 | slot_id = TRB_TO_SLOT_ID( | ||
650 | xhci->cmd_ring->dequeue->generic.field[3]); | ||
651 | virt_dev = xhci->devs[slot_id]; | ||
652 | if (virt_dev) | ||
653 | handle_cmd_in_cmd_wait_list(xhci, virt_dev, | ||
654 | event); | ||
655 | else | ||
656 | xhci_warn(xhci, "Stop endpoint command " | ||
657 | "completion for disabled slot %u\n", | ||
658 | slot_id); | ||
659 | return; | ||
660 | } | ||
661 | |||
641 | memset(&deq_state, 0, sizeof(deq_state)); | 662 | memset(&deq_state, 0, sizeof(deq_state)); |
642 | slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]); | 663 | slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]); |
643 | ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]); | 664 | ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]); |
@@ -1091,7 +1112,7 @@ bandwidth_change: | |||
1091 | complete(&xhci->addr_dev); | 1112 | complete(&xhci->addr_dev); |
1092 | break; | 1113 | break; |
1093 | case TRB_TYPE(TRB_STOP_RING): | 1114 | case TRB_TYPE(TRB_STOP_RING): |
1094 | handle_stopped_endpoint(xhci, xhci->cmd_ring->dequeue); | 1115 | handle_stopped_endpoint(xhci, xhci->cmd_ring->dequeue, event); |
1095 | break; | 1116 | break; |
1096 | case TRB_TYPE(TRB_SET_DEQ): | 1117 | case TRB_TYPE(TRB_SET_DEQ): |
1097 | handle_set_deq_completion(xhci, event, xhci->cmd_ring->dequeue); | 1118 | handle_set_deq_completion(xhci, event, xhci->cmd_ring->dequeue); |
@@ -2347,7 +2368,7 @@ static void giveback_first_trb(struct xhci_hcd *xhci, int slot_id, | |||
2347 | */ | 2368 | */ |
2348 | wmb(); | 2369 | wmb(); |
2349 | start_trb->field[3] |= start_cycle; | 2370 | start_trb->field[3] |= start_cycle; |
2350 | ring_ep_doorbell(xhci, slot_id, ep_index, stream_id); | 2371 | xhci_ring_ep_doorbell(xhci, slot_id, ep_index, stream_id); |
2351 | } | 2372 | } |
2352 | 2373 | ||
2353 | /* | 2374 | /* |
@@ -2931,7 +2952,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
2931 | wmb(); | 2952 | wmb(); |
2932 | start_trb->field[3] |= start_cycle; | 2953 | start_trb->field[3] |= start_cycle; |
2933 | 2954 | ||
2934 | ring_ep_doorbell(xhci, slot_id, ep_index, urb->stream_id); | 2955 | xhci_ring_ep_doorbell(xhci, slot_id, ep_index, urb->stream_id); |
2935 | return 0; | 2956 | return 0; |
2936 | } | 2957 | } |
2937 | 2958 | ||
@@ -3108,15 +3129,20 @@ int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | |||
3108 | false); | 3129 | false); |
3109 | } | 3130 | } |
3110 | 3131 | ||
3132 | /* | ||
3133 | * Suspend is set to indicate "Stop Endpoint Command" is being issued to stop | ||
3134 | * activity on an endpoint that is about to be suspended. | ||
3135 | */ | ||
3111 | int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, | 3136 | int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, |
3112 | unsigned int ep_index) | 3137 | unsigned int ep_index, int suspend) |
3113 | { | 3138 | { |
3114 | u32 trb_slot_id = SLOT_ID_FOR_TRB(slot_id); | 3139 | u32 trb_slot_id = SLOT_ID_FOR_TRB(slot_id); |
3115 | u32 trb_ep_index = EP_ID_FOR_TRB(ep_index); | 3140 | u32 trb_ep_index = EP_ID_FOR_TRB(ep_index); |
3116 | u32 type = TRB_TYPE(TRB_STOP_RING); | 3141 | u32 type = TRB_TYPE(TRB_STOP_RING); |
3142 | u32 trb_suspend = SUSPEND_PORT_FOR_TRB(suspend); | ||
3117 | 3143 | ||
3118 | return queue_command(xhci, 0, 0, 0, | 3144 | return queue_command(xhci, 0, 0, 0, |
3119 | trb_slot_id | trb_ep_index | type, false); | 3145 | trb_slot_id | trb_ep_index | type | trb_suspend, false); |
3120 | } | 3146 | } |
3121 | 3147 | ||
3122 | /* Set Transfer Ring Dequeue Pointer command. | 3148 | /* Set Transfer Ring Dequeue Pointer command. |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index caccecb7368e..3d2af688157a 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -968,7 +968,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
968 | ep->stop_cmd_timer.expires = jiffies + | 968 | ep->stop_cmd_timer.expires = jiffies + |
969 | XHCI_STOP_EP_CMD_TIMEOUT * HZ; | 969 | XHCI_STOP_EP_CMD_TIMEOUT * HZ; |
970 | add_timer(&ep->stop_cmd_timer); | 970 | add_timer(&ep->stop_cmd_timer); |
971 | xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index); | 971 | xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index, 0); |
972 | xhci_ring_cmd_db(xhci); | 972 | xhci_ring_cmd_db(xhci); |
973 | } | 973 | } |
974 | done: | 974 | done: |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index a7181b491e67..73e5db3e89c9 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -269,6 +269,10 @@ struct xhci_op_regs { | |||
269 | * A read gives the current link PM state of the port, | 269 | * A read gives the current link PM state of the port, |
270 | * a write with Link State Write Strobe set sets the link state. | 270 | * a write with Link State Write Strobe set sets the link state. |
271 | */ | 271 | */ |
272 | #define PORT_PLS_MASK (0xf << 5) | ||
273 | #define XDEV_U0 (0x0 << 5) | ||
274 | #define XDEV_U3 (0x3 << 5) | ||
275 | #define XDEV_RESUME (0xf << 5) | ||
272 | /* true: port has power (see HCC_PPC) */ | 276 | /* true: port has power (see HCC_PPC) */ |
273 | #define PORT_POWER (1 << 9) | 277 | #define PORT_POWER (1 << 9) |
274 | /* bits 10:13 indicate device speed: | 278 | /* bits 10:13 indicate device speed: |
@@ -510,6 +514,7 @@ struct xhci_slot_ctx { | |||
510 | #define MAX_EXIT (0xffff) | 514 | #define MAX_EXIT (0xffff) |
511 | /* Root hub port number that is needed to access the USB device */ | 515 | /* Root hub port number that is needed to access the USB device */ |
512 | #define ROOT_HUB_PORT(p) (((p) & 0xff) << 16) | 516 | #define ROOT_HUB_PORT(p) (((p) & 0xff) << 16) |
517 | #define DEVINFO_TO_ROOT_HUB_PORT(p) (((p) >> 16) & 0xff) | ||
513 | /* Maximum number of ports under a hub device */ | 518 | /* Maximum number of ports under a hub device */ |
514 | #define XHCI_MAX_PORTS(p) (((p) & 0xff) << 24) | 519 | #define XHCI_MAX_PORTS(p) (((p) & 0xff) << 24) |
515 | 520 | ||
@@ -754,6 +759,7 @@ struct xhci_virt_device { | |||
754 | /* Status of the last command issued for this device */ | 759 | /* Status of the last command issued for this device */ |
755 | u32 cmd_status; | 760 | u32 cmd_status; |
756 | struct list_head cmd_list; | 761 | struct list_head cmd_list; |
762 | u8 port; | ||
757 | }; | 763 | }; |
758 | 764 | ||
759 | 765 | ||
@@ -884,6 +890,10 @@ struct xhci_event_cmd { | |||
884 | #define TRB_TO_EP_INDEX(p) ((((p) & (0x1f << 16)) >> 16) - 1) | 890 | #define TRB_TO_EP_INDEX(p) ((((p) & (0x1f << 16)) >> 16) - 1) |
885 | #define EP_ID_FOR_TRB(p) ((((p) + 1) & 0x1f) << 16) | 891 | #define EP_ID_FOR_TRB(p) ((((p) + 1) & 0x1f) << 16) |
886 | 892 | ||
893 | #define SUSPEND_PORT_FOR_TRB(p) (((p) & 1) << 23) | ||
894 | #define TRB_TO_SUSPEND_PORT(p) (((p) & (1 << 23)) >> 23) | ||
895 | #define LAST_EP_INDEX 30 | ||
896 | |||
887 | /* Set TR Dequeue Pointer command TRB fields */ | 897 | /* Set TR Dequeue Pointer command TRB fields */ |
888 | #define TRB_TO_STREAM_ID(p) ((((p) & (0xffff << 16)) >> 16)) | 898 | #define TRB_TO_STREAM_ID(p) ((((p) & (0xffff << 16)) >> 16)) |
889 | #define STREAM_ID_FOR_TRB(p) ((((p)) & 0xffff) << 16) | 899 | #define STREAM_ID_FOR_TRB(p) ((((p)) & 0xffff) << 16) |
@@ -1202,6 +1212,9 @@ struct xhci_hcd { | |||
1202 | #define XHCI_LINK_TRB_QUIRK (1 << 0) | 1212 | #define XHCI_LINK_TRB_QUIRK (1 << 0) |
1203 | #define XHCI_RESET_EP_QUIRK (1 << 1) | 1213 | #define XHCI_RESET_EP_QUIRK (1 << 1) |
1204 | #define XHCI_NEC_HOST (1 << 2) | 1214 | #define XHCI_NEC_HOST (1 << 2) |
1215 | u32 port_c_suspend[8]; /* port suspend change*/ | ||
1216 | u32 suspended_ports[8]; /* which ports are | ||
1217 | suspended */ | ||
1205 | }; | 1218 | }; |
1206 | 1219 | ||
1207 | /* For testing purposes */ | 1220 | /* For testing purposes */ |
@@ -1409,7 +1422,7 @@ int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | |||
1409 | int xhci_queue_vendor_command(struct xhci_hcd *xhci, | 1422 | int xhci_queue_vendor_command(struct xhci_hcd *xhci, |
1410 | u32 field1, u32 field2, u32 field3, u32 field4); | 1423 | u32 field1, u32 field2, u32 field3, u32 field4); |
1411 | int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, | 1424 | int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, |
1412 | unsigned int ep_index); | 1425 | unsigned int ep_index, int suspend); |
1413 | int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, | 1426 | int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, |
1414 | int slot_id, unsigned int ep_index); | 1427 | int slot_id, unsigned int ep_index); |
1415 | int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, | 1428 | int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, |
@@ -1439,6 +1452,8 @@ void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci, | |||
1439 | unsigned int slot_id, unsigned int ep_index, | 1452 | unsigned int slot_id, unsigned int ep_index, |
1440 | struct xhci_dequeue_state *deq_state); | 1453 | struct xhci_dequeue_state *deq_state); |
1441 | void xhci_stop_endpoint_command_watchdog(unsigned long arg); | 1454 | void xhci_stop_endpoint_command_watchdog(unsigned long arg); |
1455 | void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, | ||
1456 | unsigned int ep_index, unsigned int stream_id); | ||
1442 | 1457 | ||
1443 | /* xHCI roothub code */ | 1458 | /* xHCI roothub code */ |
1444 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, | 1459 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, |