Subversion Repositories freemyipod

Rev

Go to most recent revision | Details | 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;
37
 
38
 
39
static const struct usb_devicedescriptor usb_devicedescriptor =
40
{
41
    .bLength = sizeof(struct usb_devicedescriptor),
42
    .bDescriptorType = USB_DESCRIPTOR_TYPE_DEVICE,
43
    .bcdUSB = 0x0200,
44
    .bDeviceClass = 0,
45
    .bDeviceSubClass = 0,
46
    .bDeviceProtocol = 0,
47
    .bMaxPacketSize0 = 64,
48
    .idVendor = 0xffff,
49
    .idProduct = 0xe001,
50
    .bcdDevice = 2,
51
    .iManufacturer = 1,
52
    .iProduct = 2,
53
    .iSerialNumber = 0,
54
    .bNumConfigurations = 1,
55
};
56
 
57
 
58
static struct __attribute__((packed)) _usb_config1_descriptors
59
{
60
    struct usb_configurationdescriptor c1;
61
    struct usb_interfacedescriptor c1_i0_a0;
62
    struct usb_endpointdescriptor c1_i0_a0_e1out;
63
    struct usb_endpointdescriptor c1_i0_a0_e1in;
64
} usb_config1_descriptors =
65
{
66
    .c1 =
67
    {
68
        .bLength = sizeof(struct usb_configurationdescriptor),
69
        .bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION,
70
        .wTotalLength = sizeof(struct _usb_config1_descriptors),
71
        .bNumInterfaces = 1,
72
        .bConfigurationValue = 1,
73
        .iConfiguration = 0,
74
        .bmAttributes = { .buspowered = 1, .selfpowered = 1 },
75
        .bMaxPower = 100 / 2,
76
    },
77
    .c1_i0_a0 =
78
    {
79
        .bLength = sizeof(struct usb_interfacedescriptor),
80
        .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
81
        .bInterfaceNumber = 0,
82
        .bAlternateSetting = 0,
83
        .bNumEndpoints = 2,
84
        .bInterfaceClass = 0x08,
85
        .bInterfaceSubClass = 0x06,
86
        .bInterfaceProtocol = 0x50,
87
        .iInterface = 0,
88
    },
89
    .c1_i0_a0_e1out =
90
    {
91
        .bLength = sizeof(struct usb_endpointdescriptor),
92
        .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
93
        .bEndpointAddress = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT },
94
        .bmAttributes = { .type = USB_ENDPOINT_ATTRIBUTE_TYPE_BULK },
95
        .wMaxPacketSize = 512,
96
        .bInterval = 1,
97
    },
98
    .c1_i0_a0_e1in =
99
    {
100
        .bLength = sizeof(struct usb_endpointdescriptor),
101
        .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
102
        .bEndpointAddress = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN },
103
        .bmAttributes = { .type = USB_ENDPOINT_ATTRIBUTE_TYPE_BULK },
104
        .wMaxPacketSize = 512,
105
        .bInterval = 1,
106
    },
107
};
108
 
109
 
110
static const struct usb_stringdescriptor usb_string_language =
111
{
112
    .bLength = sizeof(usb_string_language) + sizeof(*usb_string_language.wString),
113
    .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
114
    .wString = { 0x0409 },
115
};
116
 
117
 
118
static const struct usb_stringdescriptor usb_string_vendor =
119
{
120
    .bLength = sizeof(usb_string_vendor) + sizeof(*usb_string_vendor.wString) * 14,
121
    .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
122
    .wString = { 'f', 'r', 'e', 'e', 'm', 'y', 'i', 'p', 'o', 'd', '.', 'o', 'r', 'g' },
123
};
124
 
125
 
126
static const struct usb_stringdescriptor usb_string_product =
127
{
128
    .bLength = sizeof(usb_string_product) + sizeof(*usb_string_product.wString) * 16,
129
    .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
130
    .wString = { 'e', 'm', 'C', 'O', 'R', 'E', ' ', 'D', 'i', 's', 'k', ' ', 'M', 'o', 'd', 'e' },
131
};
132
 
133
 
134
static const struct usb_stringdescriptor* usb_stringdescriptors[] =
135
{
136
    &usb_string_language,
137
    &usb_string_vendor,
138
    &usb_string_product,
139
};
140
 
141
 
142
int handle_ctrl_request(const struct usb_instance* data, int interface, union usb_ep0_buffer* request, const void** response)
143
{
144
    int size = -1;
145
    switch (request->setup.bmRequestType.type)
146
    {
147
    case USB_SETUP_BMREQUESTTYPE_TYPE_CLASS:
148
        switch (request->setup.bRequest.raw)
149
        {
150
        case 0xfe:  // GET_MAX_LUN
151
            data->buffer->raw[0] = 0;
152
            size = 1;
153
            break;
154
        case 0xff:  // STORAGE_RESET
155
            size = 0;
156
            break;
157
        default: break;
158
        }
159
        break;
160
        default: break;
161
    }
162
    return size;
163
}
164
 
165
 
166
void handle_set_altsetting(const struct usb_instance* data, int interface, int altsetting)
167
{
168
    usb_handle = data;
169
    usb_maxlen = maxpacket * MIN(usb_get_max_transfer_size(usb_handle, usb_outep),
170
                                 usb_get_max_transfer_size(usb_handle, usb_inep));
171
    usb_configure_ep(usb_handle, usb_outep, USB_ENDPOINT_TYPE_BULK, maxpacket);
172
    usb_configure_ep(usb_handle, usb_inep, USB_ENDPOINT_TYPE_BULK, maxpacket);
173
    ums_listen();
174
}
175
 
176
 
177
void handle_unset_altsetting(const struct usb_instance* data, int interface, int altsetting)
178
{
179
    usb_unconfigure_ep(usb_handle, usb_outep);
180
    usb_unconfigure_ep(usb_handle, usb_inep);
181
}
182
 
183
 
184
int handle_ep_ctrl_request(const struct usb_instance* data, int interface, int endpoint, union usb_ep0_buffer* request, const void** response)
185
{
186
    int size = -1;
187
    switch (request->setup.bmRequestType.type)
188
    {
189
    case USB_SETUP_BMREQUESTTYPE_TYPE_STANDARD:
190
        switch (request->setup.bRequest.req)
191
        {
192
        case USB_SETUP_BREQUEST_CLEAR_FEATURE:
193
            if (request->setup.wLength || request->setup.wValue) break;
194
            ums_listen();
195
            break;
196
        default: break;
197
        }
198
        break;
199
        default: break;
200
    }
201
    return size;
202
}
203
 
204
 
205
void handle_xfer_complete(const struct usb_instance* data, int ifnum, int epnum, int bytesleft)
206
{
207
    ums_xfer_complete(epnum & 0x80, bytesleft);
208
}
209
 
210
 
211
void handle_timeout(const struct usb_instance* data, int interface, int endpoint, int bytesleft)
212
{
213
    usb_set_stall(usb_handle, usb_outep, true);
214
    usb_set_stall(usb_handle, usb_inep, true);
215
}
216
 
217
 
218
static void handle_bus_reset(const struct usb_instance* data, int configuration, int interface, int highspeed)
219
{
220
    maxpacket = highspeed ? 512 : 64;
221
    usb_config1_descriptors.c1_i0_a0_e1out.wMaxPacketSize = maxpacket;
222
    usb_config1_descriptors.c1_i0_a0_e1in.wMaxPacketSize = maxpacket;
223
}
224
 
225
 
226
static struct usb_endpoint usb_c1_i0_a0_ep1out =
227
{
228
    .number = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT },
229
    .ctrl_request = handle_ep_ctrl_request,
230
    .xfer_complete = handle_xfer_complete,
231
};
232
 
233
 
234
static struct usb_endpoint usb_c1_i0_a0_ep1in =
235
{
236
    .number = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN },
237
    .ctrl_request = handle_ep_ctrl_request,
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();
332
}
333
 
334
 
335
void enqueue_async()
336
{
337
    wakeup_signal(&mainloop_wakeup);
338
}
339
 
340
 
341
void usb_transmit(void* buffer, uint32_t len)
342
{
343
    usb_start_tx(usb_handle, usb_inep, buffer, len);
344
}
345
 
346
 
347
void usb_receive(void* buffer, uint32_t len)
348
{
349
    usb_start_rx(usb_handle, usb_outep, buffer, len);
350
}
351
 
352
 
353
void usb_stall()
354
{
355
    usb_set_stall(usb_handle, usb_outep, true);
356
    usb_set_stall(usb_handle, usb_inep, true);
357
}
358