Subversion Repositories freemyipod

Rev

Rev 924 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
924 theseven 1
//
2
//
3
//    Copyright 2013 TheSeven
4
//    Copyright 2014 user890104
5
//
6
//
7
//    This file is part of emCORE.
8
//
9
//    emCORE is free software: you can redistribute it and/or
10
//    modify it under the terms of the GNU General Public License as
11
//    published by the Free Software Foundation, either version 2 of the
12
//    License, or (at your option) any later version.
13
//
14
//    emCORE is distributed in the hope that it will be useful,
15
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
//    See the GNU General Public License for more details.
18
//
19
//    You should have received a copy of the GNU General Public License along
20
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
21
//
22
//
23
 
24
 
25
#include "emcoreapp.h"
26
#include "usb.h"
27
#include "ums.h"
28
 
29
 
30
int usb_maxlen;
31
 
32
static const struct usb_instance* usb_handle;
33
static union usb_endpoint_number usb_outep = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT };
34
static union usb_endpoint_number usb_inep = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN };
35
static int maxpacket = 512;
36
static struct wakeup mainloop_wakeup;
967 theseven 37
static char* error = NULL;
924 theseven 38
 
39
 
40
static const struct usb_devicedescriptor usb_devicedescriptor =
41
{
42
    .bLength = sizeof(struct usb_devicedescriptor),
43
    .bDescriptorType = USB_DESCRIPTOR_TYPE_DEVICE,
44
    .bcdUSB = 0x0200,
45
    .bDeviceClass = 0,
46
    .bDeviceSubClass = 0,
47
    .bDeviceProtocol = 0,
48
    .bMaxPacketSize0 = 64,
49
    .idVendor = 0xffff,
50
    .idProduct = 0xe001,
51
    .bcdDevice = 2,
52
    .iManufacturer = 1,
53
    .iProduct = 2,
54
    .iSerialNumber = 0,
55
    .bNumConfigurations = 1,
56
};
57
 
58
 
59
static struct __attribute__((packed)) _usb_config1_descriptors
60
{
61
    struct usb_configurationdescriptor c1;
62
    struct usb_interfacedescriptor c1_i0_a0;
63
    struct usb_endpointdescriptor c1_i0_a0_e1out;
64
    struct usb_endpointdescriptor c1_i0_a0_e1in;
65
} usb_config1_descriptors =
66
{
67
    .c1 =
68
    {
69
        .bLength = sizeof(struct usb_configurationdescriptor),
70
        .bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION,
71
        .wTotalLength = sizeof(struct _usb_config1_descriptors),
72
        .bNumInterfaces = 1,
73
        .bConfigurationValue = 1,
74
        .iConfiguration = 0,
75
        .bmAttributes = { .buspowered = 1, .selfpowered = 1 },
76
        .bMaxPower = 100 / 2,
77
    },
78
    .c1_i0_a0 =
79
    {
80
        .bLength = sizeof(struct usb_interfacedescriptor),
81
        .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
82
        .bInterfaceNumber = 0,
83
        .bAlternateSetting = 0,
84
        .bNumEndpoints = 2,
85
        .bInterfaceClass = 0x08,
86
        .bInterfaceSubClass = 0x06,
87
        .bInterfaceProtocol = 0x50,
88
        .iInterface = 0,
89
    },
90
    .c1_i0_a0_e1out =
91
    {
92
        .bLength = sizeof(struct usb_endpointdescriptor),
93
        .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
94
        .bEndpointAddress = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT },
95
        .bmAttributes = { .type = USB_ENDPOINT_ATTRIBUTE_TYPE_BULK },
96
        .wMaxPacketSize = 512,
97
        .bInterval = 1,
98
    },
99
    .c1_i0_a0_e1in =
100
    {
101
        .bLength = sizeof(struct usb_endpointdescriptor),
102
        .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
103
        .bEndpointAddress = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN },
104
        .bmAttributes = { .type = USB_ENDPOINT_ATTRIBUTE_TYPE_BULK },
105
        .wMaxPacketSize = 512,
106
        .bInterval = 1,
107
    },
108
};
109
 
110
 
111
static const struct usb_stringdescriptor usb_string_language =
112
{
113
    .bLength = sizeof(usb_string_language) + sizeof(*usb_string_language.wString),
114
    .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
115
    .wString = { 0x0409 },
116
};
117
 
118
 
119
static const struct usb_stringdescriptor usb_string_vendor =
120
{
121
    .bLength = sizeof(usb_string_vendor) + sizeof(*usb_string_vendor.wString) * 14,
122
    .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
123
    .wString = { 'f', 'r', 'e', 'e', 'm', 'y', 'i', 'p', 'o', 'd', '.', 'o', 'r', 'g' },
124
};
125
 
126
 
127
static const struct usb_stringdescriptor usb_string_product =
128
{
129
    .bLength = sizeof(usb_string_product) + sizeof(*usb_string_product.wString) * 16,
130
    .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
131
    .wString = { 'e', 'm', 'C', 'O', 'R', 'E', ' ', 'D', 'i', 's', 'k', ' ', 'M', 'o', 'd', 'e' },
132
};
133
 
134
 
135
static const struct usb_stringdescriptor* usb_stringdescriptors[] =
136
{
137
    &usb_string_language,
138
    &usb_string_vendor,
139
    &usb_string_product,
140
};
141
 
142
 
143
int handle_ctrl_request(const struct usb_instance* data, int interface, union usb_ep0_buffer* request, const void** response)
144
{
145
    int size = -1;
146
    switch (request->setup.bmRequestType.type)
147
    {
148
    case USB_SETUP_BMREQUESTTYPE_TYPE_CLASS:
149
        switch (request->setup.bRequest.raw)
150
        {
151
        case 0xfe:  // GET_MAX_LUN
152
            data->buffer->raw[0] = 0;
153
            size = 1;
154
            break;
155
        case 0xff:  // STORAGE_RESET
156
            size = 0;
157
            break;
158
        default: break;
159
        }
160
        break;
161
        default: break;
162
    }
163
    return size;
164
}
165
 
166
 
167
void handle_set_altsetting(const struct usb_instance* data, int interface, int altsetting)
168
{
169
    usb_handle = data;
170
    usb_maxlen = maxpacket * MIN(usb_get_max_transfer_size(usb_handle, usb_outep),
171
                                 usb_get_max_transfer_size(usb_handle, usb_inep));
172
    usb_configure_ep(usb_handle, usb_outep, USB_ENDPOINT_TYPE_BULK, maxpacket);
173
    usb_configure_ep(usb_handle, usb_inep, USB_ENDPOINT_TYPE_BULK, maxpacket);
174
    ums_listen();
175
}
176
 
177
 
178
void handle_unset_altsetting(const struct usb_instance* data, int interface, int altsetting)
179
{
180
    usb_unconfigure_ep(usb_handle, usb_outep);
181
    usb_unconfigure_ep(usb_handle, usb_inep);
182
}
183
 
184
 
185
int handle_ep_ctrl_request(const struct usb_instance* data, int interface, int endpoint, union usb_ep0_buffer* request, const void** response)
186
{
187
    int size = -1;
188
    switch (request->setup.bmRequestType.type)
189
    {
190
    case USB_SETUP_BMREQUESTTYPE_TYPE_STANDARD:
191
        switch (request->setup.bRequest.req)
192
        {
193
        case USB_SETUP_BREQUEST_CLEAR_FEATURE:
194
            if (request->setup.wLength || request->setup.wValue) break;
195
            ums_listen();
196
            break;
197
        default: break;
198
        }
199
        break;
200
        default: break;
201
    }
202
    return size;
203
}
204
 
205
 
206
void handle_xfer_complete(const struct usb_instance* data, int ifnum, int epnum, int bytesleft)
207
{
967 theseven 208
    ums_xfer_complete(epnum, bytesleft);
924 theseven 209
}
210
 
211
 
212
void handle_timeout(const struct usb_instance* data, int interface, int endpoint, int bytesleft)
213
{
214
    usb_set_stall(usb_handle, usb_outep, true);
215
    usb_set_stall(usb_handle, usb_inep, true);
216
}
217
 
218
 
219
static void handle_bus_reset(const struct usb_instance* data, int configuration, int interface, int highspeed)
220
{
221
    maxpacket = highspeed ? 512 : 64;
222
    usb_config1_descriptors.c1_i0_a0_e1out.wMaxPacketSize = maxpacket;
223
    usb_config1_descriptors.c1_i0_a0_e1in.wMaxPacketSize = maxpacket;
224
}
225
 
226
 
227
static struct usb_endpoint usb_c1_i0_a0_ep1out =
228
{
229
    .number = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT },
230
    .ctrl_request = handle_ep_ctrl_request,
231
    .xfer_complete = handle_xfer_complete,
232
};
233
 
234
 
235
static struct usb_endpoint usb_c1_i0_a0_ep1in =
236
{
237
    .number = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN },
238
    .xfer_complete = handle_xfer_complete,
239
    .timeout = handle_timeout,
240
};
241
 
242
 
243
static const struct usb_altsetting usb_c1_i0_a0 =
244
{
245
    .set_altsetting = handle_set_altsetting,
246
    .unset_altsetting = handle_unset_altsetting,
247
    .endpoint_count = 2,
248
    .endpoints =
249
    {
250
        &usb_c1_i0_a0_ep1out,
251
        &usb_c1_i0_a0_ep1in,
252
    },
253
};
254
 
255
 
256
static const struct usb_interface usb_c1_i0 =
257
{
258
    .bus_reset = handle_bus_reset,
259
    .ctrl_request = handle_ctrl_request,
260
    .altsetting_count = 1,
261
    .altsettings =
262
    {
263
        &usb_c1_i0_a0,
264
    },
265
};
266
 
267
 
268
static const struct usb_configuration usb_c1 =
269
{
270
    .descriptor = &usb_config1_descriptors.c1,
271
    .set_configuration = NULL,
272
    .unset_configuration = NULL,
273
    .interface_count = 1,
274
    .interfaces =
275
    {
276
        &usb_c1_i0,
277
    },
278
};
279
 
280
 
281
static const struct usb_configuration* usb_configurations[] =
282
{
283
    &usb_c1,
284
};
285
 
286
 
287
void usb_prepare()
288
{
289
    int i;
290
    uint32_t eps = usbmanager_get_available_endpoints();
291
    int ep_out = 0;
292
    int ep_in = 0;
293
    for (i = 1; i < 16; i++)
294
        if (eps & (1 << i))
295
        {
296
            ep_out = i;
297
            break;
298
        }
299
    for (i = 1; i < 16; i++)
300
        if (eps & (1 << (16 + i)))
301
        {
302
            ep_in = i;
303
            break;
304
        }
305
    if (!ep_out || !ep_in) panicf(PANIC_KILLTHREAD, "Not enough USB endpoints available!\n");
306
    usb_config1_descriptors.c1_i0_a0_e1out.bEndpointAddress.number = ep_out;
307
    usb_config1_descriptors.c1_i0_a0_e1in.bEndpointAddress.number = ep_in;
308
    usb_c1_i0_a0_ep1out.number.number = ep_out;
309
    usb_c1_i0_a0_ep1in.number.number = ep_in;
310
    usb_outep.number = ep_out;
311
    usb_inep.number = ep_in;
312
}
313
 
314
 
315
void usb_connect()
316
{
317
    int rc = usbmanager_install_custom(&usb_devicedescriptor, ARRAYLEN(usb_configurations), usb_configurations,
318
                                       ARRAYLEN(usb_stringdescriptors), usb_stringdescriptors, true);
319
    if (IS_ERR(rc))
320
    {
321
        cprintf(3, "Failed to register USB handler: %08X\n", rc);
322
        return;
323
    }
324
 
325
    wakeup_init(&mainloop_wakeup);
326
 
327
    while (!ums_ejected && usbmanager_get_connected())
328
        if (wakeup_wait(&mainloop_wakeup, 200000) == THREAD_OK)
329
            ums_handle_async();
330
 
331
    usbmanager_uninstall_custom();
967 theseven 332
 
333
    if (error) panic(PANIC_KILLTHREAD, error);
924 theseven 334
}
335
 
336
 
337
void enqueue_async()
338
{
339
    wakeup_signal(&mainloop_wakeup);
340
}
341
 
342
 
343
void usb_transmit(void* buffer, uint32_t len)
344
{
345
    usb_start_tx(usb_handle, usb_inep, buffer, len);
346
}
347
 
348
 
349
void usb_receive(void* buffer, uint32_t len)
350
{
351
    usb_start_rx(usb_handle, usb_outep, buffer, len);
352
}
353
 
354
 
967 theseven 355
void usb_stall_in()
924 theseven 356
{
357
    usb_set_stall(usb_handle, usb_inep, true);
358
}
359
 
967 theseven 360
 
361
void usb_stall_out()
362
{
363
    usb_set_stall(usb_handle, usb_outep, true);
364
}
365
 
366
 
367
void fail(char* errormsg)
368
{
369
    error = errormsg;
370
    ums_ejected = true;
371
    wakeup_signal(&mainloop_wakeup);
372
}