aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-hub.c')
-rw-r--r--drivers/usb/host/xhci-hub.c196
1 files changed, 195 insertions, 1 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 */
135static 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 */
159static 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
205command_cleanup:
206 xhci_free_command(xhci, cmd);
207 return ret;
208}
209
210/*
211 * Ring device, it rings the all doorbells unconditionally.
212 */
213static 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
132static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex, 225static 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: