freemyipod r945 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r944‎ | r945 | r946 >
Date:12:38, 14 June 2014
Author:theseven
Status:new
Tags:
Comment:
UMSboot: Port over emCORE USB changes
Modified paths:
  • /umsboot/src/app/umsboot/usbglue.c (modified) (history)
  • /umsboot/src/core/synopsysotg/synopsysotg.c (modified) (history)
  • /umsboot/src/protocol/usb/usb.c (modified) (history)
  • /umsboot/src/protocol/usb/usb.h (modified) (history)

Diff [purge]

Index: umsboot/src/core/synopsysotg/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
@@ -364,9 +366,9 @@
365367 }
366368 union usb_endpoint_number epnum = { .direction = USB_ENDPOINT_DIRECTION_IN, .number = ep };
367369 int bytesleft = data->core->inep_regs[ep].dieptsiz.b.xfersize;
 370+ data->core->inep_regs[ep].diepint = epints;
368371 if (epints.b.timeout) usb_handle_timeout(instance, epnum, bytesleft);
369372 if (epints.b.xfercompl) usb_handle_xfer_complete(instance, epnum, bytesleft);
370 - data->core->inep_regs[ep].diepint = epints;
371373 }
372374 }
373375
@@ -378,10 +380,11 @@
379381 if (daint.ep.out & (1 << ep))
380382 {
381383 union synopsysotg_doepintn epints = data->core->outep_regs[ep].doepint;
 384+ data->core->outep_regs[ep].doepint = epints;
382385 union usb_endpoint_number epnum = { .direction = USB_ENDPOINT_DIRECTION_OUT, .number = ep };
383386 if (epints.b.setup)
384387 {
385 - 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);
386389 synopsysotg_flush_in_endpoint(instance, ep);
387390 usb_handle_setup_received(instance, epnum);
388391 }
@@ -390,7 +393,6 @@
391394 int bytesleft = data->core->inep_regs[ep].dieptsiz.b.xfersize;
392395 usb_handle_xfer_complete(instance, epnum, bytesleft);
393396 }
394 - data->core->outep_regs[ep].doepint = epints;
395397 }
396398 }
397399
@@ -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;
@@ -526,3 +528,4 @@
527529 .unconfigure_ep = synopsysotg_unconfigure_ep,
528530 .get_max_transfer_size = synopsysotg_get_max_transfer_size,
529531 };
 532+
Index: umsboot/src/app/umsboot/usbglue.c
@@ -188,3 +188,4 @@
189189 &usb_c1,
190190 },
191191 };
 192+
Index: umsboot/src/protocol/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));
291 -extern void usb_ep0_expect_setup(const struct usb_instance* data);
 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));
292291 extern void usb_start_rx(const struct usb_instance* data, union usb_endpoint_number ep, void* buf, int size);
293292 extern void usb_start_tx(const struct usb_instance* data, union usb_endpoint_number ep, const void* buf, int size);
294 -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);
295294 extern void usb_configure_ep(const struct usb_instance* data, union usb_endpoint_number ep, enum usb_endpoint_type type, int maxpacket);
296295 extern void usb_unconfigure_ep(const struct usb_instance* data, union usb_endpoint_number ep);
297296 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, 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: umsboot/src/protocol/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 {