hc
2023-12-11 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4
kernel/drivers/usb/gadget/udc/aspeed-vhub/ep0.c
....@@ -105,18 +105,20 @@
105105 (crq.bRequestType & USB_DIR_IN) ? "in" : "out",
106106 ep->ep0.state);
107107
108
- /* Check our state, cancel pending requests if needed */
109
- if (ep->ep0.state != ep0_state_token) {
108
+ /*
109
+ * Check our state, cancel pending requests if needed
110
+ *
111
+ * Note: Under some circumstances, we can get a new setup
112
+ * packet while waiting for the stall ack, just accept it.
113
+ *
114
+ * In any case, a SETUP packet in wrong state should have
115
+ * reset the HW state machine, so let's just log, nuke
116
+ * requests, move on.
117
+ */
118
+ if (ep->ep0.state != ep0_state_token &&
119
+ ep->ep0.state != ep0_state_stall) {
110120 EPDBG(ep, "wrong state\n");
111121 ast_vhub_nuke(ep, -EIO);
112
-
113
- /*
114
- * Accept the packet regardless, this seems to happen
115
- * when stalling a SETUP packet that has an OUT data
116
- * phase.
117
- */
118
- ast_vhub_nuke(ep, 0);
119
- goto stall;
120122 }
121123
122124 /* Calculate next state for EP0 */
....@@ -165,7 +167,7 @@
165167 stall:
166168 EPDBG(ep, "stalling\n");
167169 writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat);
168
- ep->ep0.state = ep0_state_status;
170
+ ep->ep0.state = ep0_state_stall;
169171 ep->ep0.dir_in = false;
170172 return;
171173
....@@ -299,8 +301,8 @@
299301 if ((ep->ep0.dir_in && (stat & VHUB_EP0_TX_BUFF_RDY)) ||
300302 (!ep->ep0.dir_in && (stat & VHUB_EP0_RX_BUFF_RDY)) ||
301303 (ep->ep0.dir_in != in_ack)) {
304
+ /* In that case, ignore interrupt */
302305 dev_warn(dev, "irq state mismatch");
303
- stall = true;
304306 break;
305307 }
306308 /*
....@@ -335,12 +337,22 @@
335337 dev_warn(dev, "status direction mismatch\n");
336338 stall = true;
337339 }
340
+ break;
341
+ case ep0_state_stall:
342
+ /*
343
+ * There shouldn't be any request left, but nuke just in case
344
+ * otherwise the stale request will block subsequent ones
345
+ */
346
+ ast_vhub_nuke(ep, -EIO);
347
+ break;
338348 }
339349
340
- /* Reset to token state */
341
- ep->ep0.state = ep0_state_token;
342
- if (stall)
350
+ /* Reset to token state or stall */
351
+ if (stall) {
343352 writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat);
353
+ ep->ep0.state = ep0_state_stall;
354
+ } else
355
+ ep->ep0.state = ep0_state_token;
344356 }
345357
346358 static int ast_vhub_ep0_queue(struct usb_ep* u_ep, struct usb_request *u_req,
....@@ -367,7 +379,7 @@
367379 return -EINVAL;
368380
369381 /* Disabled device */
370
- if (ep->dev && (!ep->dev->enabled || ep->dev->suspended))
382
+ if (ep->dev && !ep->dev->enabled)
371383 return -ESHUTDOWN;
372384
373385 /* Data, no buffer and not internal ? */
....@@ -390,8 +402,12 @@
390402 spin_lock_irqsave(&vhub->lock, flags);
391403
392404 /* EP0 can only support a single request at a time */
393
- if (!list_empty(&ep->queue) || ep->ep0.state == ep0_state_token) {
405
+ if (!list_empty(&ep->queue) ||
406
+ ep->ep0.state == ep0_state_token ||
407
+ ep->ep0.state == ep0_state_stall) {
394408 dev_warn(dev, "EP0: Request in wrong state\n");
409
+ EPVDBG(ep, "EP0: list_empty=%d state=%d\n",
410
+ list_empty(&ep->queue), ep->ep0.state);
395411 spin_unlock_irqrestore(&vhub->lock, flags);
396412 return -EBUSY;
397413 }
....@@ -459,6 +475,15 @@
459475 .free_request = ast_vhub_free_request,
460476 };
461477
478
+void ast_vhub_reset_ep0(struct ast_vhub_dev *dev)
479
+{
480
+ struct ast_vhub_ep *ep = &dev->ep0;
481
+
482
+ ast_vhub_nuke(ep, -EIO);
483
+ ep->ep0.state = ep0_state_token;
484
+}
485
+
486
+
462487 void ast_vhub_init_ep0(struct ast_vhub *vhub, struct ast_vhub_ep *ep,
463488 struct ast_vhub_dev *dev)
464489 {