Sections 7.1.7.5 and 9.2.6.2 of the USB 2.0 spec say the a host has
to wait for at least 10 ms (Trstrcy) after reset before it can expect
a device to be able to receive data.
In Linux drivers/usb/core/hub.c:hub_port_reset we find this:
/* TRSTRCY = 10 ms; plus some extra */
msleep(10 + 40);
So let's use 50 ms.
---
softusb-input/main.c | 28 +++++++++++++++++++---------
1 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/softusb-input/main.c b/softusb-input/main.c
index 0f58ebd..1f76353 100644
--- a/softusb-input/main.c
+++ b/softusb-input/main.c
@@ -40,6 +40,7 @@ enum {
enum {
PORT_STATE_DISCONNECTED = 0,
PORT_STATE_BUS_RESET,
+ PORT_STATE_RESET_WAIT,
PORT_STATE_SET_ADDRESS,
PORT_STATE_GET_DEVICE_DESCRIPTOR,
PORT_STATE_GET_CONFIGURATION_DESCRIPTOR,
@@ -48,6 +49,8 @@ enum {
PORT_STATE_UNSUPPORTED
};
+#define RESET_RECOVERY_MS 50 /* USB 2.0, 7.1.7.5: >= 10 ms */
+
struct ep_status {
char ep;
unsigned char expected_data;
@@ -446,7 +449,7 @@ static void port_service(struct port_status *p, char name)
wio8(SIE_TX_LOW_SPEED, 0);
else
wio8(SIE_TX_LOW_SPEED, 1);
- if((p->full_speed) && (p->state > PORT_STATE_BUS_RESET)) {
+ if((p->full_speed) && (p->state > PORT_STATE_RESET_WAIT)) {
/* send SOF */
unsigned char usb_buffer[3];
make_usb_token(USB_PID_SOF, frame_nr, usb_buffer);
@@ -478,14 +481,21 @@ static void port_service(struct port_status *p, char name)
break;
}
case PORT_STATE_BUS_RESET:
- if(frame_nr == p->unreset_frame) {
- if(name == 'A')
- wio8(SIE_TX_BUSRESET,
rio8(SIE_TX_BUSRESET) & 0x02);
- else
- wio8(SIE_TX_BUSRESET,
rio8(SIE_TX_BUSRESET) & 0x01);
- p->state = PORT_STATE_SET_ADDRESS;
- p->retry_count = 0;
- }
+ if(frame_nr != p->unreset_frame)
+ break;
+ if(name == 'A')
+ wio8(SIE_TX_BUSRESET, rio8(SIE_TX_BUSRESET) &
0x02);
+ else
+ wio8(SIE_TX_BUSRESET, rio8(SIE_TX_BUSRESET) &
0x01);
+ p->state = PORT_STATE_RESET_WAIT;
+ p->unreset_frame =
+ (frame_nr + RESET_RECOVERY_MS) & 0x7ff;
+ break;
+ case PORT_STATE_RESET_WAIT:
+ if(frame_nr != p->unreset_frame)
+ break;
+ p->state = PORT_STATE_SET_ADDRESS;
+ p->retry_count = 0;
break;
case PORT_STATE_SET_ADDRESS: {
struct setup_packet packet;
--
1.7.0.4
_______________________________________________
http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org
IRC: #milkymist@Freenode