Subversion Repositories freemyipod

Rev

Rev 881 | Rev 890 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 881 Rev 889
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
{