1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
16a17,36
> static void synopsysotg_flush_out_endpoint(const struct usb_instance* instance, int ep)
> {
>     const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config;
>     if (data->core->outep_regs[ep].doepctl.b.epena)
>     {
>         // We are waiting for an OUT packet on this endpoint, which might arrive any moment.
>         // Assert a global output NAK to avoid race conditions while shutting down the endpoint.
>         synopsysotg_target_disable_irq(instance);
>         data->core->dregs.dctl.b.sgoutnak = 1;
>         while (!(data->core->gregs.gintsts.b.goutnakeff));
>         union synopsysotg_depctl doepctl = { .b = { .snak = 1, .epdis = 1 } };
>         data->core->outep_regs[ep].doepctl = doepctl;
>         while (!(data->core->outep_regs[ep].doepint.b.epdisabled));
>         data->core->dregs.dctl.b.cgoutnak = 1;
>         synopsysotg_target_enable_irq(instance);
>     }
>     // Reset the transfer size register. Not strictly necessary, but can't hurt.
>     data->core->outep_regs[ep].doeptsiz.d32 = 0;
> }
> 
22,24c42,43
<         // Urgh, someone was still babbling on our IN pipe, and now we have some
<         // old crap in the FIFO. Disable the endpoint, to make sure nobody will
<         // fetch any more old crap while we're trying to get rid of it.
---
>         // We are shutting down an endpoint that might still have IN packets in the FIFO.
>         // Disable the endpoint, wait for things to settle, and flush the relevant FIFO.
29a49
>         if (ep) data->core->inep_regs[ep].diepctl.b.usbactep = 0;
38c58
<     // Reset the transfer size register. Not strictly neccessary, but can't hurt.
---
>     // Reset the transfer size register. Not strictly necessary, but can't hurt.
67c87
<     // Set up data desination
---
>     // Set up data destination
96c116
<     // Set up data desination
---
>     // Set up data source
132d151
<     union synopsysotg_depctl depctl = { .b = { .epdis = 1 } };
134a154
>         // Kill any outstanding IN transfers
136d155
<         data->core->inep_regs[ep.number].diepctl = depctl;
142,144c161,162
<         // We can't really do much about in-flight OUT requests except for ignoring them.
<         data->core->outep_regs[ep.number].doeptsiz.d32 = 0;
<         data->core->outep_regs[ep.number].doepctl = depctl;
---
>         // Kill any outstanding IN transfers
>         synopsysotg_flush_out_endpoint(instance, ep.number);
182c200
<     // Set up data desination
---
>     // Set up data destination
281c299
<                     if (!deptsiz.b.pktcnt) data->core->dregs.diepempmsk.ep.in &= ~(1 << ep);
---
>                     if (!deptsiz.b.xfersize) data->core->dregs.diepempmsk.ep.in &= ~(1 << ep);
388c406
<                                                    .rx_thr_len = SYNOPSYSOTG_AHB_THRESHOLD } };
---
>                                                      .rx_thr_len = SYNOPSYSOTG_AHB_THRESHOLD } };