| Line 1... |
Line 1... |
| 1 |
#include "global.h"
|
1 |
#include "global.h"
|
| 2 |
#include "protocol/usb/usb.h"
|
2 |
#include "protocol/usb/usb.h"
|
| - |
|
3 |
#include "sys/util.h"
|
| 3 |
|
4 |
|
| 4 |
void usb_start_rx(const struct usb_instance* data, union usb_endpoint_number ep, void* buf, int size)
|
5 |
void usb_start_rx(const struct usb_instance* data, union usb_endpoint_number ep, void* buf, int size)
|
| 5 |
{
|
6 |
{
|
| 6 |
data->driver->start_rx(data, ep, buf, size);
|
7 |
data->driver->start_rx(data, ep, buf, size);
|
| 7 |
}
|
8 |
}
|
| Line 14... |
Line 15... |
| 14 |
void usb_set_stall(const struct usb_instance* data, union usb_endpoint_number ep, int stall)
|
15 |
void usb_set_stall(const struct usb_instance* data, union usb_endpoint_number ep, int stall)
|
| 15 |
{
|
16 |
{
|
| 16 |
data->driver->set_stall(data, ep, stall);
|
17 |
data->driver->set_stall(data, ep, stall);
|
| 17 |
}
|
18 |
}
|
| 18 |
|
19 |
|
| 19 |
void usb_ep0_start_rx(const struct usb_instance* data, int non_setup)
|
20 |
void usb_ep0_start_rx(const struct usb_instance* data, int non_setup, bool (*callback)(const struct usb_instance* data, int bytesleft))
|
| 20 |
{
|
21 |
{
|
| - |
|
22 |
data->state->ep0_rx_callback = callback;
|
| 21 |
data->driver->ep0_start_rx(data, non_setup);
|
23 |
data->driver->ep0_start_rx(data, non_setup);
|
| 22 |
}
|
24 |
}
|
| 23 |
|
25 |
|
| 24 |
void usb_ep0_start_tx(const struct usb_instance* data, const void* buf, int len)
|
26 |
bool usb_ep0_rx_callback(const struct usb_instance* data, int bytesleft)
|
| - |
|
27 |
{
|
| - |
|
28 |
usb_ep0_start_rx(data, 0, NULL);
|
| - |
|
29 |
return true;
|
| - |
|
30 |
}
|
| - |
|
31 |
|
| - |
|
32 |
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))
|
| 25 |
{
|
33 |
{
|
| 26 |
// Expect zero-length ACK if we are about to actually send data, otherwise expect SETUP.
|
34 |
// Expect zero-length ACK if we are about to actually send data, otherwise expect SETUP.
|
| 27 |
usb_ep0_start_rx(data, !!len);
|
35 |
if (last) usb_ep0_start_rx(data, !!len, usb_ep0_rx_callback);
|
| 28 |
|
36 |
|
| - |
|
37 |
data->state->ep0_tx_callback = callback;
|
| 29 |
data->driver->ep0_start_tx(data, buf, len);
|
38 |
data->driver->ep0_start_tx(data, buf, len);
|
| 30 |
}
|
39 |
}
|
| 31 |
|
40 |
|
| 32 |
void usb_ep0_expect_setup(const struct usb_instance* data)
|
41 |
bool usb_ep0_tx_callback(const struct usb_instance* data, int bytesleft)
|
| 33 |
{
|
42 |
{
|
| 34 |
// The next packet needs to be a SETUP, so lock out everything on the IN pipe.
|
43 |
if (bytesleft || !data->state->ep0_tx_len) return false;
|
| 35 |
union usb_endpoint_number ep = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN };
|
44 |
int len = MIN(64, data->state->ep0_tx_len);
|
| - |
|
45 |
data->state->ep0_tx_ptr += 64;
|
| 36 |
usb_set_stall(data, ep, 1);
|
46 |
data->state->ep0_tx_len -= len;
|
| 37 |
|
- |
|
| 38 |
// Set up the OUT pipe for the SETUP packet, STALLing everything else.
|
47 |
usb_ep0_start_tx(data, data->state->ep0_tx_ptr, len, !!data->state->ep0_tx_len, usb_ep0_tx_callback);
|
| 39 |
usb_ep0_start_rx(data, 0);
|
48 |
return true;
|
| 40 |
}
|
49 |
}
|
| 41 |
|
50 |
|
| 42 |
void usb_unconfigure_ep(const struct usb_instance* data, union usb_endpoint_number ep)
|
51 |
void usb_unconfigure_ep(const struct usb_instance* data, union usb_endpoint_number ep)
|
| 43 |
{
|
52 |
{
|
| 44 |
data->driver->unconfigure_ep(data, ep);
|
53 |
data->driver->unconfigure_ep(data, ep);
|
| Line 66... |
Line 75... |
| 66 |
if (!configid) return;
|
75 |
if (!configid) return;
|
| 67 |
const struct usb_configuration* configuration = data->configurations[configid - 1];
|
76 |
const struct usb_configuration* configuration = data->configurations[configid - 1];
|
| 68 |
int i;
|
77 |
int i;
|
| 69 |
for (i = 0; i < configuration->interface_count; i++)
|
78 |
for (i = 0; i < configuration->interface_count; i++)
|
| 70 |
{
|
79 |
{
|
| 71 |
struct usb_interface* interface = configuration->interfaces[i];
|
80 |
const struct usb_interface* interface = configuration->interfaces[i];
|
| 72 |
const struct usb_altsetting* altsetting = interface->altsettings[interface->current_altsetting];
|
81 |
const struct usb_altsetting* altsetting = interface->altsettings[data->state->interface_altsetting[i]];
|
| 73 |
if (altsetting->unset_altsetting)
|
82 |
if (altsetting->unset_altsetting)
|
| 74 |
altsetting->unset_altsetting(data, i, interface->current_altsetting);
|
83 |
altsetting->unset_altsetting(data, i, data->state->interface_altsetting[i]);
|
| 75 |
}
|
84 |
}
|
| 76 |
if (configuration->unset_configuration)
|
85 |
if (configuration->unset_configuration)
|
| 77 |
configuration->unset_configuration(data, configid);
|
86 |
configuration->unset_configuration(data, configid);
|
| 78 |
data->state->current_configuration = 0;
|
87 |
data->state->current_configuration = 0;
|
| 79 |
}
|
88 |
}
|
| Line 89... |
Line 98... |
| 89 |
if (!configid) return NULL;
|
98 |
if (!configid) return NULL;
|
| 90 |
const struct usb_configuration* configuration = data->configurations[configid - 1];
|
99 |
const struct usb_configuration* configuration = data->configurations[configid - 1];
|
| 91 |
for (*ifidx = 0; *ifidx < configuration->interface_count; (*ifidx)++)
|
100 |
for (*ifidx = 0; *ifidx < configuration->interface_count; (*ifidx)++)
|
| 92 |
{
|
101 |
{
|
| 93 |
const struct usb_interface* interface = configuration->interfaces[*ifidx];
|
102 |
const struct usb_interface* interface = configuration->interfaces[*ifidx];
|
| 94 |
const struct usb_altsetting* altsetting = interface->altsettings[interface->current_altsetting];
|
103 |
const struct usb_altsetting* altsetting = interface->altsettings[data->state->interface_altsetting[*ifidx]];
|
| 95 |
for (*epidx = 0; *epidx < altsetting->endpoint_count; (*epidx)++)
|
104 |
for (*epidx = 0; *epidx < altsetting->endpoint_count; (*epidx)++)
|
| 96 |
{
|
105 |
{
|
| 97 |
const struct usb_endpoint* endpoint = altsetting->endpoints[*epidx];
|
106 |
const struct usb_endpoint* endpoint = altsetting->endpoints[*epidx];
|
| 98 |
if (endpoint->number.byte == ep.byte) return endpoint;
|
107 |
if (endpoint->number.byte == ep.byte) return endpoint;
|
| 99 |
}
|
108 |
}
|
| Line 106... |
Line 115... |
| 106 |
// size < -2: do nothing at all (dangerous, you need to take care of priming EP0 yourself!)
|
115 |
// size < -2: do nothing at all (dangerous, you need to take care of priming EP0 yourself!)
|
| 107 |
// size == -2: send STALL
|
116 |
// size == -2: send STALL
|
| 108 |
// size == -1: try to run default handler, or send STALL if none exists
|
117 |
// size == -1: try to run default handler, or send STALL if none exists
|
| 109 |
// size == 0: send ACK
|
118 |
// size == 0: send ACK
|
| 110 |
// size > 0: send <size> bytes at <addr>, then expect ACK
|
119 |
// size > 0: send <size> bytes at <addr>, then expect ACK
|
| 111 |
const void* addr = NULL;
|
120 |
const void* addr = data->buffer;
|
| 112 |
int size = -1;
|
121 |
int size = -1;
|
| 113 |
switch (buffer->setup.bmRequestType.recipient)
|
122 |
switch (buffer->setup.bmRequestType.recipient)
|
| 114 |
{
|
123 |
{
|
| 115 |
case USB_SETUP_BMREQUESTTYPE_RECIPIENT_DEVICE:
|
124 |
case USB_SETUP_BMREQUESTTYPE_RECIPIENT_DEVICE:
|
| 116 |
if (data->ctrl_request) size = data->ctrl_request(data, buffer, &addr);
|
125 |
if (data->ctrl_request) size = data->ctrl_request(data, buffer, &addr);
|
| Line 123... |
Line 132... |
| 123 |
case USB_SETUP_BREQUEST_GET_STATUS:
|
132 |
case USB_SETUP_BREQUEST_GET_STATUS:
|
| 124 |
if (buffer->setup.wLength != 2 || buffer->setup.wIndex
|
133 |
if (buffer->setup.wLength != 2 || buffer->setup.wIndex
|
| 125 |
|| !data->state->current_address || buffer->setup.wValue) break;
|
134 |
|| !data->state->current_address || buffer->setup.wValue) break;
|
| 126 |
data->buffer->raw[0] = 0;
|
135 |
data->buffer->raw[0] = 0;
|
| 127 |
data->buffer->raw[1] = 1;
|
136 |
data->buffer->raw[1] = 1;
|
| 128 |
addr = data->buffer;
|
- |
|
| 129 |
size = 2;
|
137 |
size = 2;
|
| 130 |
break;
|
138 |
break;
|
| 131 |
case USB_SETUP_BREQUEST_SET_ADDRESS:
|
139 |
case USB_SETUP_BREQUEST_SET_ADDRESS:
|
| 132 |
if (buffer->setup.wLength || buffer->setup.wIndex || buffer->setup.wValue > 127) break;
|
140 |
if (buffer->setup.wLength || buffer->setup.wIndex || buffer->setup.wValue > 127) break;
|
| 133 |
data->state->current_address = buffer->setup.wValue;
|
141 |
data->state->current_address = buffer->setup.wValue;
|
| Line 160... |
Line 168... |
| 160 |
break;
|
168 |
break;
|
| 161 |
case USB_SETUP_BREQUEST_GET_CONFIGURATION:
|
169 |
case USB_SETUP_BREQUEST_GET_CONFIGURATION:
|
| 162 |
if (buffer->setup.wLength != 1 || buffer->setup.wIndex
|
170 |
if (buffer->setup.wLength != 1 || buffer->setup.wIndex
|
| 163 |
|| !data->state->current_address || buffer->setup.wValue) break;
|
171 |
|| !data->state->current_address || buffer->setup.wValue) break;
|
| 164 |
data->buffer->raw[0] = data->state->current_configuration;
|
172 |
data->buffer->raw[0] = data->state->current_configuration;
|
| 165 |
addr = data->buffer;
|
- |
|
| 166 |
size = 1;
|
173 |
size = 1;
|
| 167 |
break;
|
174 |
break;
|
| 168 |
case USB_SETUP_BREQUEST_SET_CONFIGURATION:
|
175 |
case USB_SETUP_BREQUEST_SET_CONFIGURATION:
|
| 169 |
if (buffer->setup.wLength || buffer->setup.wIndex || !data->state->current_address
|
176 |
if (buffer->setup.wLength || buffer->setup.wIndex || !data->state->current_address
|
| 170 |
|| buffer->setup.wValue > data->configuration_count) break;
|
177 |
|| buffer->setup.wValue > data->configuration_count) break;
|
| Line 178... |
Line 185... |
| 178 |
if (configuration->set_configuration)
|
185 |
if (configuration->set_configuration)
|
| 179 |
configuration->set_configuration(data, configid);
|
186 |
configuration->set_configuration(data, configid);
|
| 180 |
int i;
|
187 |
int i;
|
| 181 |
for (i = 0; i < configuration->interface_count; i++)
|
188 |
for (i = 0; i < configuration->interface_count; i++)
|
| 182 |
{
|
189 |
{
|
| 183 |
struct usb_interface* interface = configuration->interfaces[i];
|
190 |
const struct usb_interface* interface = configuration->interfaces[i];
|
| 184 |
interface->current_altsetting = 0;
|
191 |
data->state->interface_altsetting[i] = 0;
|
| 185 |
const struct usb_altsetting* altsetting = interface->altsettings[0];
|
192 |
const struct usb_altsetting* altsetting = interface->altsettings[0];
|
| 186 |
if (altsetting->set_altsetting) altsetting->set_altsetting(data, i, 0);
|
193 |
if (altsetting->set_altsetting) altsetting->set_altsetting(data, i, 0);
|
| 187 |
}
|
194 |
}
|
| 188 |
}
|
195 |
}
|
| 189 |
size = 0;
|
196 |
size = 0;
|
| Line 196... |
Line 203... |
| 196 |
case USB_SETUP_BMREQUESTTYPE_RECIPIENT_INTERFACE:
|
203 |
case USB_SETUP_BMREQUESTTYPE_RECIPIENT_INTERFACE:
|
| 197 |
{
|
204 |
{
|
| 198 |
if (!data->state->current_configuration) break;
|
205 |
if (!data->state->current_configuration) break;
|
| 199 |
int configid = data->state->current_configuration;
|
206 |
int configid = data->state->current_configuration;
|
| 200 |
const struct usb_configuration* configuration = data->configurations[configid - 1];
|
207 |
const struct usb_configuration* configuration = data->configurations[configid - 1];
|
| 201 |
if (buffer->setup.wIndex >= configuration->interface_count) break;
|
- |
|
| 202 |
int intfid = buffer->setup.wIndex;
|
208 |
int intfid = buffer->setup.wIndex;
|
| - |
|
209 |
if (intfid >= configuration->interface_count) break;
|
| 203 |
struct usb_interface* interface = configuration->interfaces[intfid];
|
210 |
const struct usb_interface* interface = configuration->interfaces[intfid];
|
| 204 |
if (interface->ctrl_request) size = interface->ctrl_request(data, intfid, buffer, &addr);
|
211 |
if (interface->ctrl_request) size = interface->ctrl_request(data, intfid, buffer, &addr);
|
| 205 |
if (size != -1) break;
|
212 |
if (size != -1) break;
|
| 206 |
switch (buffer->setup.bmRequestType.type)
|
213 |
switch (buffer->setup.bmRequestType.type)
|
| 207 |
{
|
214 |
{
|
| 208 |
case USB_SETUP_BMREQUESTTYPE_TYPE_STANDARD:
|
215 |
case USB_SETUP_BMREQUESTTYPE_TYPE_STANDARD:
|
| Line 210... |
Line 217... |
| 210 |
{
|
217 |
{
|
| 211 |
case USB_SETUP_BREQUEST_GET_STATUS:
|
218 |
case USB_SETUP_BREQUEST_GET_STATUS:
|
| 212 |
if (buffer->setup.wLength != 2 || buffer->setup.wValue) break;
|
219 |
if (buffer->setup.wLength != 2 || buffer->setup.wValue) break;
|
| 213 |
data->buffer->raw[0] = 0;
|
220 |
data->buffer->raw[0] = 0;
|
| 214 |
data->buffer->raw[1] = 0;
|
221 |
data->buffer->raw[1] = 0;
|
| 215 |
addr = data->buffer;
|
- |
|
| 216 |
size = 2;
|
222 |
size = 2;
|
| 217 |
break;
|
223 |
break;
|
| 218 |
case USB_SETUP_BREQUEST_GET_INTERFACE:
|
224 |
case USB_SETUP_BREQUEST_GET_INTERFACE:
|
| 219 |
if (buffer->setup.wLength != 1 || buffer->setup.wValue) break;
|
225 |
if (buffer->setup.wLength != 1 || buffer->setup.wValue) break;
|
| 220 |
data->buffer->raw[0] = interface->current_altsetting;
|
226 |
data->buffer->raw[0] = data->state->interface_altsetting[intfid];
|
| 221 |
addr = data->buffer;
|
- |
|
| 222 |
size = 1;
|
227 |
size = 1;
|
| 223 |
break;
|
228 |
break;
|
| 224 |
case USB_SETUP_BREQUEST_SET_INTERFACE:
|
229 |
case USB_SETUP_BREQUEST_SET_INTERFACE:
|
| 225 |
{
|
230 |
{
|
| 226 |
if (buffer->setup.wLength
|
231 |
if (buffer->setup.wLength
|
| 227 |
|| buffer->setup.wValue > interface->altsetting_count) break;
|
232 |
|| buffer->setup.wValue > interface->altsetting_count) break;
|
| 228 |
const struct usb_altsetting* altsetting = interface->altsettings[interface->current_altsetting];
|
233 |
const struct usb_altsetting* altsetting = interface->altsettings[data->state->interface_altsetting[intfid]];
|
| 229 |
if (altsetting->unset_altsetting)
|
234 |
if (altsetting->unset_altsetting)
|
| 230 |
altsetting->unset_altsetting(data, intfid, interface->current_altsetting);
|
235 |
altsetting->unset_altsetting(data, intfid, data->state->interface_altsetting[intfid]);
|
| 231 |
interface->current_altsetting = buffer->setup.wValue;
|
236 |
data->state->interface_altsetting[intfid] = buffer->setup.wValue;
|
| 232 |
altsetting = interface->altsettings[interface->current_altsetting];
|
237 |
altsetting = interface->altsettings[data->state->interface_altsetting[intfid]];
|
| 233 |
if (altsetting->set_altsetting)
|
238 |
if (altsetting->set_altsetting)
|
| 234 |
altsetting->set_altsetting(data, intfid, interface->current_altsetting);
|
239 |
altsetting->set_altsetting(data, intfid, data->state->interface_altsetting[intfid]);
|
| 235 |
break;
|
240 |
break;
|
| 236 |
}
|
241 |
}
|
| 237 |
default: break;
|
242 |
default: break;
|
| 238 |
}
|
243 |
}
|
| 239 |
break;
|
244 |
break;
|
| Line 281... |
Line 286... |
| 281 |
}
|
286 |
}
|
| 282 |
default: break;
|
287 |
default: break;
|
| 283 |
}
|
288 |
}
|
| 284 |
}
|
289 |
}
|
| 285 |
// See comment at the top of this function
|
290 |
// See comment at the top of this function
|
| 286 |
if (size == 0) usb_ep0_start_tx(data, NULL, 0);
|
291 |
if (size == 0) usb_ep0_start_tx(data, NULL, 0, true, NULL);
|
| - |
|
292 |
else if (size > 0)
|
| - |
|
293 |
{
|
| 287 |
else if (size > 0) usb_ep0_start_tx(data, addr, size);
|
294 |
usb_ep0_start_rx(data, 0, NULL);
|
| - |
|
295 |
int len = MIN(64, size);
|
| 288 |
else if (size >= -2) usb_ep0_expect_setup(data);
|
296 |
data->state->ep0_tx_ptr = addr;
|
| - |
|
297 |
data->state->ep0_tx_len = size - len;
|
| - |
|
298 |
usb_ep0_start_tx(data, addr, len, !data->state->ep0_tx_len, usb_ep0_tx_callback);
|
| 289 |
}
|
299 |
}
|
| 290 |
|
- |
|
| 291 |
static void usb_handle_ep0_data(const struct usb_instance* data, union usb_ep0_buffer* buffer, int size)
|
300 |
else if (size >= -2)
|
| 292 |
{
|
301 |
{
|
| 293 |
// We don't accept any commands that have an OUT payload. Just STALL it, no matter what it was.
|
302 |
union usb_endpoint_number ep = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN };
|
| - |
|
303 |
usb_set_stall(data, ep, 1);
|
| - |
|
304 |
ep.direction = USB_ENDPOINT_DIRECTION_OUT;
|
| 294 |
usb_ep0_expect_setup(data);
|
305 |
usb_set_stall(data, ep, 1);
|
| - |
|
306 |
}
|
| 295 |
}
|
307 |
}
|
| 296 |
|
308 |
|
| 297 |
void usb_handle_bus_reset(const struct usb_instance* data, int highspeed)
|
309 |
void usb_handle_bus_reset(const struct usb_instance* data, int highspeed)
|
| 298 |
{
|
310 |
{
|
| 299 |
data->state->current_address = 0;
|
311 |
data->state->current_address = 0;
|
| Line 303... |
Line 315... |
| 303 |
for (c = 0; c < data->configuration_count; c++)
|
315 |
for (c = 0; c < data->configuration_count; c++)
|
| 304 |
{
|
316 |
{
|
| 305 |
const struct usb_configuration* configuration = data->configurations[c];
|
317 |
const struct usb_configuration* configuration = data->configurations[c];
|
| 306 |
for (i = 0; i < configuration->interface_count; i++)
|
318 |
for (i = 0; i < configuration->interface_count; i++)
|
| 307 |
{
|
319 |
{
|
| 308 |
struct usb_interface* interface = configuration->interfaces[i];
|
320 |
const struct usb_interface* interface = configuration->interfaces[i];
|
| 309 |
if (interface->bus_reset) interface->bus_reset(data, c, i, highspeed);
|
321 |
if (interface->bus_reset) interface->bus_reset(data, c, i, highspeed);
|
| 310 |
}
|
322 |
}
|
| 311 |
}
|
323 |
}
|
| - |
|
324 |
|
| - |
|
325 |
// Prime EP0 for the first setup packet.
|
| - |
|
326 |
usb_ep0_start_rx(data, 0, NULL);
|
| 312 |
}
|
327 |
}
|
| 313 |
|
328 |
|
| 314 |
void usb_handle_timeout(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
|
329 |
void usb_handle_timeout(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
|
| 315 |
{
|
330 |
{
|
| 316 |
// Hm, the host didn't fetch our EP0 IN packet, so we feel a bit offended.
|
331 |
// If the host doesn't fetch an EP0 IN packet, we can't do much about it.
|
| 317 |
// Refuse to accept any transfers, until we get a new SETUP token.
|
332 |
// This will be recovered by the next SETUP packet.
|
| 318 |
if (!epnum.number) usb_ep0_expect_setup(data);
|
333 |
if (epnum.number)
|
| 319 |
else
|
- |
|
| 320 |
{
|
334 |
{
|
| 321 |
int epidx;
|
335 |
int epidx;
|
| 322 |
int ifidx;
|
336 |
int ifidx;
|
| 323 |
const struct usb_endpoint* endpoint = usb_find_endpoint(data, epnum, &epidx, &ifidx);
|
337 |
const struct usb_endpoint* endpoint = usb_find_endpoint(data, epnum, &epidx, &ifidx);
|
| 324 |
if (!endpoint) data->driver->unconfigure_ep(data, epnum);
|
338 |
if (!endpoint) data->driver->unconfigure_ep(data, epnum);
|
| Line 328... |
Line 342... |
| 328 |
|
342 |
|
| 329 |
void usb_handle_xfer_complete(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
|
343 |
void usb_handle_xfer_complete(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
|
| 330 |
{
|
344 |
{
|
| 331 |
if (!epnum.number)
|
345 |
if (!epnum.number)
|
| 332 |
{
|
346 |
{
|
| 333 |
// If this was EP0 IN, stall the pipe. There will only ever be one transfer for each
|
347 |
bool (*callback)(const struct usb_instance* data, int size);
|
| 334 |
// SETUP transaction, and the next SETUP packet will clear the stall.
|
348 |
if (epnum.direction == USB_ENDPOINT_DIRECTION_OUT)
|
| - |
|
349 |
{
|
| - |
|
350 |
callback = data->state->ep0_rx_callback;
|
| - |
|
351 |
data->state->ep0_rx_callback = NULL;
|
| - |
|
352 |
}
|
| - |
|
353 |
else
|
| - |
|
354 |
{
|
| 335 |
if (epnum.direction == USB_ENDPOINT_DIRECTION_IN) usb_set_stall(data, epnum, 1);
|
355 |
callback = data->state->ep0_tx_callback;
|
| 336 |
else if (!data->ep0_data_hook || !data->ep0_data_hook(data, data->buffer, 64 - bytesleft))
|
356 |
data->state->ep0_tx_callback = NULL;
|
| - |
|
357 |
}
|
| 337 |
usb_handle_ep0_data(data, data->buffer, 64 - bytesleft);
|
358 |
if (callback) callback(data, bytesleft);
|
| 338 |
}
|
359 |
}
|
| 339 |
else
|
360 |
else
|
| 340 |
{
|
361 |
{
|
| 341 |
int epidx;
|
362 |
int epidx;
|
| 342 |
int ifidx;
|
363 |
int ifidx;
|
| Line 344... |
Line 365... |
| 344 |
if (!endpoint) usb_unconfigure_ep(data, epnum);
|
365 |
if (!endpoint) usb_unconfigure_ep(data, epnum);
|
| 345 |
else if (endpoint->xfer_complete) endpoint->xfer_complete(data, ifidx, epidx, bytesleft);
|
366 |
else if (endpoint->xfer_complete) endpoint->xfer_complete(data, ifidx, epidx, bytesleft);
|
| 346 |
}
|
367 |
}
|
| 347 |
}
|
368 |
}
|
| 348 |
|
369 |
|
| 349 |
void usb_handle_setup_received(const struct usb_instance* data, union usb_endpoint_number epnum, int back2back)
|
370 |
void usb_handle_setup_received(const struct usb_instance* data, union usb_endpoint_number epnum)
|
| 350 |
{
|
371 |
{
|
| 351 |
if (!epnum.number)
|
372 |
if (!epnum.number)
|
| 352 |
{
|
373 |
{
|
| 353 |
// Figure out the location of the newest SETUP packet if there were
|
- |
|
| 354 |
// multiple back to back ones. If there were more than 3 SETUP packets
|
- |
|
| 355 |
// in a row, the OTG will take care of it, so we're on the safe side here.
|
- |
|
| 356 |
void* addr = &data->buffer->raw[8 * (back2back - 1)];
|
- |
|
| 357 |
union usb_ep0_buffer* buffer = (union usb_ep0_buffer*)addr;
|
- |
|
| 358 |
if (!data->ep0_setup_hook || !data->ep0_setup_hook(data, buffer)) usb_handle_ep0_setup(data, buffer);
|
374 |
if (!data->ep0_setup_hook || !data->ep0_setup_hook(data, data->buffer)) usb_handle_ep0_setup(data, data->buffer);
|
| 359 |
}
|
375 |
}
|
| 360 |
else
|
376 |
else
|
| 361 |
{
|
377 |
{
|
| 362 |
int epidx;
|
378 |
int epidx;
|
| 363 |
int ifidx;
|
379 |
int ifidx;
|
| 364 |
const struct usb_endpoint* endpoint = usb_find_endpoint(data, epnum, &epidx, &ifidx);
|
380 |
const struct usb_endpoint* endpoint = usb_find_endpoint(data, epnum, &epidx, &ifidx);
|
| 365 |
if (!endpoint) usb_unconfigure_ep(data, epnum);
|
381 |
if (!endpoint) usb_unconfigure_ep(data, epnum);
|
| 366 |
else if (endpoint->setup_received) endpoint->setup_received(data, ifidx, epidx, back2back);
|
382 |
else if (endpoint->setup_received) endpoint->setup_received(data, ifidx, epidx);
|
| 367 |
}
|
383 |
}
|
| 368 |
}
|
384 |
}
|
| 369 |
|
385 |
|
| 370 |
void usb_init(const struct usb_instance* data)
|
386 |
void usb_init(const struct usb_instance* data)
|
| 371 |
{
|
387 |
{
|