freemyipod r944 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r943‎ | r944 | r945 >
Date:12:38, 14 June 2014
Author:theseven
Status:new
Tags:
Comment:
emCORE: Rework USB core a bit (insights from the Rockbox USB fixes)
Modified paths:
  • /emcore/trunk/usb/synopsysotg.c (modified) (history)
  • /emcore/trunk/usb/usb.c (modified) (history)
  • /emcore/trunk/usb/usb.h (modified) (history)
  • /emcore/trunk/usb/usbdebug.c (modified) (history)

Diff [purge]

Index: emcore/trunk/usb/usb.h
@@ -235,8 +235,8 @@
236236
237237 struct __attribute__((packed,aligned(4))) usb_state
238238 {
239 - bool (*ep0_rx_callback)(const struct usb_instance* data, int bytesleft);
240 - bool (*ep0_tx_callback)(const struct usb_instance* data, int bytesleft);
 239+ bool (*ep0_rx_callback)(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft);
 240+ bool (*ep0_tx_callback)(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft);
241241 const void* ep0_tx_ptr;
242242 uint16_t ep0_tx_len;
243243 uint8_t current_address;
@@ -248,12 +248,12 @@
249249 {
250250 void (*init)(const struct usb_instance* data);
251251 void (*exit)(const struct usb_instance* data);
252 - void (*ep0_start_rx)(const struct usb_instance* data, int non_setup);
 252+ void (*ep0_start_rx)(const struct usb_instance* data, bool non_setup, int len);
253253 void (*ep0_start_tx)(const struct usb_instance* data, const void* buf, int len);
254254 void (*start_rx)(const struct usb_instance* data, union usb_endpoint_number ep, void* buf, int size);
255255 void (*start_tx)(const struct usb_instance* data, union usb_endpoint_number ep, const void* buf, int size);
256256 int (*get_stall)(const struct usb_instance* data, union usb_endpoint_number ep);
257 - void (*set_stall)(const struct usb_instance* data, union usb_endpoint_number ep, int stall);
 257+ void (*set_stall)(const struct usb_instance* data, union usb_endpoint_number ep, bool stall);
258258 void (*set_address)(const struct usb_instance* data, uint8_t address);
259259 void (*configure_ep)(const struct usb_instance* data, union usb_endpoint_number ep, enum usb_endpoint_type type, int maxpacket);
260260 void (*unconfigure_ep)(const struct usb_instance* data, union usb_endpoint_number ep);
@@ -285,15 +285,17 @@
286286 extern void usb_handle_timeout(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft);
287287 extern void usb_handle_xfer_complete(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft);
288288 extern void usb_handle_setup_received(const struct usb_instance* data, union usb_endpoint_number epnum);
289 -extern void usb_ep0_start_rx(const struct usb_instance* data, int non_setup, bool (*callback)(const struct usb_instance* data, int bytesleft));
290 -extern void usb_ep0_start_tx(const struct usb_instance* data, const void* buf, int len, bool last, bool (*callback)(const struct usb_instance* data, int bytesleft));
 289+extern void usb_ep0_start_rx(const struct usb_instance* data, bool non_setup, int len, bool (*callback)(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft));
 290+extern void usb_ep0_start_tx(const struct usb_instance* data, const void* buf, int len, bool (*callback)(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft));
291291 extern void usb_start_rx(const struct usb_instance* data, union usb_endpoint_number ep, void* buf, int size);
292292 extern void usb_start_tx(const struct usb_instance* data, union usb_endpoint_number ep, const void* buf, int size);
293 -extern void usb_set_stall(const struct usb_instance* data, union usb_endpoint_number ep, int stall);
 293+extern void usb_set_stall(const struct usb_instance* data, union usb_endpoint_number ep, bool stall);
294294 extern void usb_configure_ep(const struct usb_instance* data, union usb_endpoint_number ep, enum usb_endpoint_type type, int maxpacket);
295295 extern void usb_unconfigure_ep(const struct usb_instance* data, union usb_endpoint_number ep);
296296 extern int usb_get_max_transfer_size(const struct usb_instance* data, union usb_endpoint_number ep);
297 -extern bool usb_ep0_tx_callback(const struct usb_instance* data, int bytesleft);
 297+extern bool usb_ep0_tx_callback(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft);
 298+extern bool usb_ep0_short_tx_callback(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft);
 299+extern bool usb_ep0_ack_callback(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft);
298300
299301
300302 #endif
Index: emcore/trunk/usb/usbdebug.c
@@ -110,10 +110,12 @@
111111 dbgstate = DBGSTATE_IDLE;
112112 }
113113
114 -bool usbdebug_handle_data(const struct usb_instance* data, int bytesleft)
 114+bool usbdebug_handle_data(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
115115 {
 116+ union usb_endpoint_number ep0in = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN };
 117+ union usb_endpoint_number ep0out = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT };
116118 uint32_t* buf = (uint32_t*)data->buffer->raw;
117 - usb_ep0_start_rx(dbgusb, 0, NULL);
 119+ usb_ep0_start_rx(dbgusb, false, 0, NULL);
118120 switch (dbgstate)
119121 {
120122 case DBGSTATE_SETUP:
@@ -152,7 +154,7 @@
153155 {
154156 dbgmemaddr += len;
155157 dbgstate = DBGSTATE_WRITE_MEM;
156 - usb_ep0_start_rx(dbgusb, 1, usbdebug_handle_data);
 158+ usb_ep0_start_rx(dbgusb, true, MIN(64, dbgmemlen), usbdebug_handle_data);
157159 return true;
158160 }
159161 dbgbuf[0] = 1;
@@ -161,7 +163,8 @@
162164 case 10: // READ CONSOLE
163165 dbgmemaddr = (void*)buf[1];
164166 dbgstate = DBGSTATE_READ_CONSOLE;
165 - usb_ep0_start_tx(dbgusb, NULL, 0, true, NULL);
 167+ usb_set_stall(dbgusb, ep0out, true);
 168+ usb_ep0_start_tx(dbgusb, NULL, 0, NULL);
166169 return true;
167170 break;
168171 case 11: // WRITE CONSOLE
@@ -195,7 +198,7 @@
196199 {
197200 dbgmemlen = total - 48;
198201 dbgstate = DBGSTATE_WRITE_CONSOLE;
199 - usb_ep0_start_rx(dbgusb, 1, usbdebug_handle_data);
 202+ usb_ep0_start_rx(dbgusb, true, MIN(64, dbgmemlen), usbdebug_handle_data);
200203 return true;
201204 }
202205 dbgbuf[3] = dbgconrecvreadidx - dbgconrecvwriteidx - 1;
@@ -265,7 +268,7 @@
266269 if (dbgmemlen && !bytesleft)
267270 {
268271 dbgmemaddr += len;
269 - usb_ep0_start_rx(dbgusb, 1, usbdebug_handle_data);
 272+ usb_ep0_start_rx(dbgusb, true, MIN(64, dbgmemlen), usbdebug_handle_data);
270273 return true;
271274 }
272275 dbgbuf[0] = 1;
@@ -292,7 +295,7 @@
293296 wakeup_signal(&dbgconrecvwakeup);
294297 if (dbgmemlen && !bytesleft)
295298 {
296 - usb_ep0_start_rx(dbgusb, 1, usbdebug_handle_data);
 299+ usb_ep0_start_rx(dbgusb, true, MIN(64, dbgmemlen), usbdebug_handle_data);
297300 return true;
298301 }
299302 }
@@ -302,13 +305,20 @@
303306 default: break;
304307 }
305308 dbgstate = DBGSTATE_RESPOND;
306 - usb_ep0_start_tx(dbgusb, NULL, 0, true, NULL);
 309+ usb_set_stall(dbgusb, ep0out, true);
 310+ usb_ep0_start_tx(dbgusb, NULL, 0, NULL);
307311 return true;
308312 }
309313
310 -bool read_console_callback(const struct usb_instance* data, int bytesleft)
 314+bool read_console_callback(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
311315 {
312 - if (bytesleft || !dbgmemaddr) return false;
 316+ if (bytesleft || !dbgmemaddr)
 317+ {
 318+ usb_ep0_start_rx(dbgusb, true, 0, usb_ep0_ack_callback);
 319+ if (!dbgmemaddr) usb_ep0_start_tx(dbgusb, NULL, 0, usb_ep0_short_tx_callback);
 320+ dbgusb->state->ep0_tx_ptr = NULL;
 321+ return false;
 322+ }
313323 dbgconsoleattached = true;
314324 int bytes = MIN(64, dbgmemlen);
315325 if (bytes)
@@ -332,10 +342,10 @@
333343 dbgmemaddr -= bytes;
334344 if (dbgmemaddr)
335345 {
336 - usb_ep0_start_rx(dbgusb, 0, NULL);
337 - usb_ep0_start_tx(dbgusb, dbgbuf, bytes, false, read_console_callback);
 346+ usb_ep0_start_tx(dbgusb, dbgbuf, bytes,
 347+ bytes < 64 ? usb_ep0_short_tx_callback : read_console_callback);
338348 }
339 - else usb_ep0_start_tx(dbgusb, dbgbuf, bytes, true, NULL);
 349+ else usb_ep0_start_tx(dbgusb, dbgbuf, bytes, NULL);
340350 return true;
341351 }
342352
@@ -342,6 +352,7 @@
343353 int usbdebug_handle_setup(const struct usb_instance* data, int interface, union usb_ep0_buffer* request, const void** response)
344354 {
345355 int size = -1;
 356+ union usb_endpoint_number ep0out = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT };
346357 switch (request->setup.bmRequestType.type)
347358 {
348359 case USB_SETUP_BMREQUESTTYPE_TYPE_VENDOR:
@@ -353,7 +364,7 @@
354365 case USB_SETUP_BMREQUESTTYPE_DIRECTION_OUT:
355366 dbgstate = DBGSTATE_SETUP;
356367 dbgmemlen = 0;
357 - usb_ep0_start_rx(dbgusb, 1, usbdebug_handle_data);
 368+ usb_ep0_start_rx(dbgusb, true, 64, usbdebug_handle_data);
358369 return -3;
359370 case USB_SETUP_BMREQUESTTYPE_DIRECTION_IN:
360371 switch (dbgstate)
@@ -360,15 +371,17 @@
361372 {
362373 case DBGSTATE_RESPOND:
363374 {
 375+ dbgmemlen = MIN(dbgmemlen, data->buffer->setup.wLength - 16);
364376 int len = MIN(48, dbgmemlen);
365377 if (len) memcpy(&dbgbuf[4], dbgmemaddr, len);
366378 dbgmemlen -= len;
367379 if (dbgmemlen)
368380 {
369 - usb_ep0_start_rx(dbgusb, 0, NULL);
370 - data->state->ep0_tx_ptr = dbgmemaddr - 16;
371 - data->state->ep0_tx_len = dbgmemlen;
372 - usb_ep0_start_tx(dbgusb, dbgbuf, len + 16, false, usb_ep0_tx_callback);
 381+ usb_ep0_start_rx(dbgusb, false, 0, NULL);
 382+ dbgusb->state->ep0_tx_ptr = dbgmemaddr + 48;
 383+ dbgusb->state->ep0_tx_len = dbgmemlen;
 384+ usb_ep0_start_tx(dbgusb, dbgbuf, len + 16,
 385+ len < 48 ? usb_ep0_short_tx_callback : usb_ep0_tx_callback);
373386 return -3;
374387 }
375388 dbgstate = DBGSTATE_IDLE;
@@ -377,6 +390,7 @@
378391 }
379392 case DBGSTATE_READ_CONSOLE:
380393 {
 394+ dbgmemaddr = (void*)MIN((int)dbgmemaddr, data->buffer->setup.wLength - 16);
381395 dbgconsoleattached = true;
382396 dbgmemlen = dbgconsendwriteidx - dbgconsendreadidx;
383397 if (dbgmemlen < 0) dbgmemlen += sizeof(dbgconsendbuf);
@@ -408,8 +422,10 @@
409423 dbgmemaddr -= bytes;
410424 if (dbgmemaddr)
411425 {
412 - usb_ep0_start_rx(dbgusb, 0, NULL);
413 - usb_ep0_start_tx(dbgusb, dbgbuf, bytes + 16, false, read_console_callback);
 426+ dbgusb->state->ep0_tx_ptr = (void*)true;
 427+ usb_ep0_start_rx(dbgusb, false, 0, NULL);
 428+ usb_ep0_start_tx(dbgusb, dbgbuf, bytes + 16,
 429+ bytes < 48 ? usb_ep0_short_tx_callback : read_console_callback);
414430 return -3;
415431 }
416432 dbgstate = DBGSTATE_IDLE;
@@ -708,7 +724,7 @@
709725 mode = enter_critical_section();
710726 if (dbgstate == DBGSTATE_ASYNC)
711727 {
712 - usb_ep0_start_tx(dbgusb, NULL, 0, true, NULL);
 728+ usb_ep0_start_tx(dbgusb, NULL, 0, NULL);
713729 dbgstate = DBGSTATE_RESPOND;
714730 dbgmemaddr = addr;
715731 dbgmemlen = len;
Index: emcore/trunk/usb/synopsysotg.c
@@ -16,6 +16,7 @@
1717
1818 static void synopsysotg_flush_out_endpoint(const struct usb_instance* instance, int ep)
1919 {
 20+ if (!ep) return;
2021 const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config;
2122 if (data->core->outep_regs[ep].doepctl.b.epena)
2223 {
@@ -24,8 +25,8 @@
2526 synopsysotg_target_disable_irq(instance);
2627 data->core->dregs.dctl.b.sgoutnak = 1;
2728 while (!(data->core->gregs.gintsts.b.goutnakeff));
28 - union synopsysotg_depctl doepctl = { .b = { .snak = 1, .epdis = 1 } };
29 - data->core->outep_regs[ep].doepctl = doepctl;
 29+ data->core->outep_regs[ep].doepctl.b.snak = 1;
 30+ data->core->outep_regs[ep].doepctl.b.epdis = 1;
3031 while (!(data->core->outep_regs[ep].doepint.b.epdisabled));
3132 data->core->dregs.dctl.b.cgoutnak = 1;
3233 synopsysotg_target_enable_irq(instance);
@@ -37,6 +38,7 @@
3839
3940 static void synopsysotg_flush_in_endpoint(const struct usb_instance* instance, int ep)
4041 {
 42+ if (!ep) return;
4143 const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config;
4244 if (data->core->inep_regs[ep].diepctl.b.epena)
4345 {
@@ -47,7 +49,7 @@
4850 while (!(data->core->inep_regs[ep].diepint.b.inepnakeff));
4951 data->core->inep_regs[ep].diepctl.b.epdis = 1;
5052 while (!(data->core->inep_regs[ep].diepint.b.epdisabled));
51 - if (ep) data->core->inep_regs[ep].diepctl.b.usbactep = 0;
 53+ data->core->inep_regs[ep].diepctl.b.usbactep = 0;
5254 synopsysotg_target_enable_irq(instance);
5355 // Wait for any DMA activity to stop, to make sure nobody will touch the FIFO.
5456 while (!data->core->gregs.grstctl.b.ahbidle);
@@ -161,7 +163,7 @@
162164 return !!data->core->outep_regs[ep.number].doepctl.b.stall;
163165 }
164166
165 -void synopsysotg_set_stall(const struct usb_instance* instance, union usb_endpoint_number ep, int stall)
 167+void synopsysotg_set_stall(const struct usb_instance* instance, union usb_endpoint_number ep, bool stall)
166168 {
167169 const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config;
168170 if (ep.direction == USB_ENDPOINT_DIRECTION_IN)
@@ -224,7 +226,7 @@
225227 }
226228 }
227229
228 -void synopsysotg_ep0_start_rx(const struct usb_instance* instance, int non_setup)
 230+void synopsysotg_ep0_start_rx(const struct usb_instance* instance, bool non_setup, int len)
229231 {
230232 const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config;
231233 struct synopsysotg_state* state = (struct synopsysotg_state*)instance->driver_state;
@@ -232,16 +234,16 @@
233235 // Set up data destination
234236 if (data->use_dma) data->core->outep_regs[0].doepdma = instance->buffer;
235237 else state->endpoints[0].rxaddr = (uint32_t*)instance->buffer;
236 - union synopsysotg_dep0xfrsiz deptsiz = { .b = { .supcnt = 3, .pktcnt = !!non_setup, .xfersize = 64 } };
 238+ union synopsysotg_dep0xfrsiz deptsiz = { .b = { .supcnt = 3, .pktcnt = !!non_setup, .xfersize = len } };
237239 data->core->outep_regs[0].doeptsiz.d32 = deptsiz.d32;
238240
239241 // Flush CPU cache if necessary
240 - if (data->use_dma) invalidate_dcache(instance->buffer, sizeof(instance->buffer));
 242+ if (data->use_dma) invalidate_dcache(instance->buffer, len);
241243
242244 // Enable the endpoint
243245 union synopsysotg_depctl depctl = data->core->outep_regs[0].doepctl;
244246 depctl.b.epena = 1;
245 - depctl.b.cnak = non_setup;
 247+ depctl.b.cnak = !!non_setup;
246248 data->core->outep_regs[0].doepctl = depctl;
247249 }
248250
@@ -382,7 +384,7 @@
383385 union usb_endpoint_number epnum = { .direction = USB_ENDPOINT_DIRECTION_OUT, .number = ep };
384386 if (epints.b.setup)
385387 {
386 - if (data->use_dma) invalidate_dcache(instance->buffer, sizeof(instance->buffer));
 388+ if (data->use_dma) invalidate_dcache((const void*)data->core->inep_regs[ep].diepdma, 8);
387389 synopsysotg_flush_in_endpoint(instance, ep);
388390 usb_handle_setup_received(instance, epnum);
389391 }
@@ -458,11 +460,11 @@
459461 int addr = data->fifosize;
460462 for (i = 0; i < 16; i++)
461463 {
 464+ data->core->inep_regs[i].diepctl.b.nextep = (i + 1) & 0xf;
462465 int size = data->txfifosize[i];
463466 addr -= size;
464467 if (size)
465468 {
466 - data->core->inep_regs[i].diepctl.b.nextep = (i + 1) & 0xf;
467469 union synopsysotg_txfsiz fsiz = { .b = { .startaddr = addr, .depth = size } };
468470 if (!i) data->core->gregs.dieptxf0_hnptxfsiz = fsiz;
469471 else data->core->gregs.dieptxf[i - 1] = fsiz;
Index: emcore/trunk/usb/usb.c
@@ -12,28 +12,34 @@
1313 data->driver->start_tx(data, ep, buf, size);
1414 }
1515
16 -void usb_set_stall(const struct usb_instance* data, union usb_endpoint_number ep, int stall)
 16+void usb_set_stall(const struct usb_instance* data, union usb_endpoint_number ep, bool stall)
1717 {
1818 data->driver->set_stall(data, ep, stall);
1919 }
2020
21 -void usb_ep0_start_rx(const struct usb_instance* data, int non_setup, bool (*callback)(const struct usb_instance* data, int bytesleft))
 21+void usb_ep0_start_rx(const struct usb_instance* data, bool non_setup, int len, bool (*callback)(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft))
2222 {
2323 data->state->ep0_rx_callback = callback;
24 - data->driver->ep0_start_rx(data, non_setup);
 24+ data->driver->ep0_start_rx(data, non_setup, len);
2525 }
2626
27 -bool usb_ep0_rx_callback(const struct usb_instance* data, int bytesleft)
 27+bool usb_ep0_ack_callback(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
2828 {
29 - usb_ep0_start_rx(data, 0, NULL);
 29+ // This function is intended to eat zero-byte ACK packets,
 30+ // which are always the last packet of a transaction.
 31+ // At this point we can STALL all further packets.
 32+ union usb_endpoint_number ep = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT };
 33+ usb_set_stall(data, ep, true);
 34+ ep.direction = USB_ENDPOINT_DIRECTION_IN;
 35+ usb_set_stall(data, ep, true);
 36+ // If this is an IN endpoint, something else must already be
 37+ // waiting for a SETUP packet anyway, or there could be deadlocks.
 38+ if (epnum.direction == USB_ENDPOINT_DIRECTION_OUT) usb_ep0_start_rx(data, false, 0, NULL);
3039 return true;
3140 }
3241
33 -void usb_ep0_start_tx(const struct usb_instance* data, const void* buf, int len, bool last, bool (*callback)(const struct usb_instance* data, int bytesleft))
 42+void usb_ep0_start_tx(const struct usb_instance* data, const void* buf, int len, bool (*callback)(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft))
3443 {
35 - // Expect zero-length ACK if we are about to actually send data, otherwise expect SETUP.
36 - if (last) usb_ep0_start_rx(data, !!len, usb_ep0_rx_callback);
37 -
3844 if (((uint32_t)buf) & (CACHEALIGN_SIZE - 1))
3945 {
4046 memcpy(data->buffer->raw, buf, len);
@@ -44,13 +50,35 @@
4551 data->driver->ep0_start_tx(data, buf, len);
4652 }
4753
48 -bool usb_ep0_tx_callback(const struct usb_instance* data, int bytesleft)
 54+bool usb_ep0_short_tx_callback(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
4955 {
50 - if (bytesleft || !data->state->ep0_tx_len) return false;
 56+ // No more data to be sent after a short packet. STALL IN.
 57+ union usb_endpoint_number ep = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN };
 58+ usb_set_stall(data, ep, true);
 59+ // If this was the last regular packet, but a short one, expect zero-length ACK.
 60+ // Otherwise usb_ep0_tx_callback will have taken care of that already.
 61+ if (data->state->ep0_tx_ptr) usb_ep0_start_rx(data, true, 0, usb_ep0_ack_callback);
 62+ return false;
 63+}
 64+
 65+bool usb_ep0_tx_callback(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
 66+{
 67+ if (bytesleft || !data->state->ep0_tx_len)
 68+ {
 69+ // This was the last packet. Expect zero-length ACK.
 70+ usb_ep0_start_rx(data, true, 0, usb_ep0_ack_callback);
 71+ // If someone might expect to receive more data, send a zero-byte packet.
 72+ if (!data->state->ep0_tx_len) usb_ep0_start_tx(data, NULL, 0, usb_ep0_short_tx_callback);
 73+ // Abuse this as a marker for usb_ep0_short_tx_callback...
 74+ data->state->ep0_tx_ptr = NULL;
 75+ return false;
 76+ }
 77+
5178 int len = MIN(64, data->state->ep0_tx_len);
 79+ data->state->ep0_tx_len -= len;
 80+ usb_ep0_start_tx(data, data->state->ep0_tx_ptr, len,
 81+ len < 64 ? usb_ep0_short_tx_callback : usb_ep0_tx_callback);
5282 data->state->ep0_tx_ptr += 64;
53 - data->state->ep0_tx_len -= len;
54 - usb_ep0_start_tx(data, data->state->ep0_tx_ptr, len, !data->state->ep0_tx_len, usb_ep0_tx_callback);
5583 return true;
5684 }
5785
@@ -119,6 +147,7 @@
120148 static void usb_handle_ep0_setup(const struct usb_instance* data, union usb_ep0_buffer* buffer)
121149 {
122150 // size < -2: do nothing at all (dangerous, you need to take care of priming EP0 yourself!)
 151+ // (this case is required for requests that have an OUT data stage)
123152 // size == -2: send STALL
124153 // size == -1: try to run default handler, or send STALL if none exists
125154 // size == 0: send ACK
@@ -275,12 +304,12 @@
276305 break;
277306 case USB_SETUP_BREQUEST_CLEAR_FEATURE:
278307 if (buffer->setup.wLength || buffer->setup.wValue) break;
279 - data->driver->set_stall(data, ep, false);
 308+ usb_set_stall(data, ep, false);
280309 size = 0;
281310 break;
282311 case USB_SETUP_BREQUEST_SET_FEATURE:
283312 if (buffer->setup.wLength || buffer->setup.wValue) break;
284 - data->driver->set_stall(data, ep, true);
 313+ usb_set_stall(data, ep, true);
285314 size = 0;
286315 break;
287316 default: break;
@@ -293,22 +322,30 @@
294323 default: break;
295324 }
296325 }
297 - // See comment at the top of this function
298 - if (size == 0) usb_ep0_start_tx(data, NULL, 0, true, NULL);
 326+ union usb_endpoint_number ep0in = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN };
 327+ union usb_endpoint_number ep0out = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT };
 328+ // See comment at the top of this function for meanings of size.
 329+ if (size == 0)
 330+ {
 331+ // Send ACK. Stall OUT pipe. Accept SETUP packets though.
 332+ usb_set_stall(data, ep0out, true);
 333+ usb_ep0_start_rx(data, false, 0, NULL);
 334+ usb_ep0_start_tx(data, NULL, 0, usb_ep0_ack_callback);
 335+ }
299336 else if (size > 0)
300337 {
301 - usb_ep0_start_rx(data, 0, NULL);
302 - int len = MIN(64, size);
 338+ // Send a data stage. Expect to receive only SETUP until we're done. NAK everything else.
 339+ usb_ep0_start_rx(data, false, 0, NULL);
303340 data->state->ep0_tx_ptr = addr;
304 - data->state->ep0_tx_len = size - len;
305 - usb_ep0_start_tx(data, addr, len, !data->state->ep0_tx_len, usb_ep0_tx_callback);
 341+ data->state->ep0_tx_len = size;
 342+ usb_ep0_tx_callback(data, ep0in, 0); // A convenient way to start a transfer.
306343 }
307344 else if (size >= -2)
308345 {
309 - union usb_endpoint_number ep = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN };
310 - usb_set_stall(data, ep, 1);
311 - ep.direction = USB_ENDPOINT_DIRECTION_OUT;
312 - usb_set_stall(data, ep, 1);
 346+ // We have no handler, or the handler failed. STALL everything, accept only SETUP packets.
 347+ usb_set_stall(data, ep0in, true);
 348+ usb_set_stall(data, ep0out, true);
 349+ usb_ep0_start_rx(data, false, 0, NULL);
313350 }
314351 }
315352
@@ -329,7 +366,7 @@
330367 }
331368
332369 // Prime EP0 for the first setup packet.
333 - usb_ep0_start_rx(data, 0, NULL);
 370+ usb_ep0_start_rx(data, false, 0, NULL);
334371 }
335372
336373 void usb_handle_timeout(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
@@ -350,7 +387,7 @@
351388 {
352389 if (!epnum.number)
353390 {
354 - bool (*callback)(const struct usb_instance* data, int size);
 391+ bool (*callback)(const struct usb_instance* data, union usb_endpoint_number epnum, int size);
355392 if (epnum.direction == USB_ENDPOINT_DIRECTION_OUT)
356393 {
357394 callback = data->state->ep0_rx_callback;
@@ -361,7 +398,7 @@
362399 callback = data->state->ep0_tx_callback;
363400 data->state->ep0_tx_callback = NULL;
364401 }
365 - if (callback) callback(data, bytesleft);
 402+ if (callback) callback(data, epnum, bytesleft);
366403 }
367404 else
368405 {