~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/SLOF/lib/libusb/usb-core.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 * Copyright (c) 2013 IBM Corporation
 
3
 * All rights reserved.
 
4
 * This program and the accompanying materials
 
5
 * are made available under the terms of the BSD License
 
6
 * which accompanies this distribution, and is available at
 
7
 * http://www.opensource.org/licenses/bsd-license.php
 
8
 *
 
9
 * Contributors:
 
10
 *     IBM Corporation - initial implementation
 
11
 *****************************************************************************/
 
12
 
 
13
#include <string.h>
 
14
#include "usb-core.h"
 
15
 
 
16
#undef DEBUG
 
17
//#define DEBUG
 
18
#ifdef DEBUG
 
19
#define dprintf(_x ...) do { printf(_x); } while(0)
 
20
#else
 
21
#define dprintf(_x ...)
 
22
#endif
 
23
 
 
24
#define __unused __attribute__((unused))
 
25
 
 
26
struct usb_hcd_ops *head;
 
27
struct usb_dev *devpool;
 
28
#define USB_DEVPOOL_SIZE 4096
 
29
 
 
30
static struct usb_dev *usb_alloc_devpool(void)
 
31
{
 
32
        struct usb_dev *head, *curr, *prev;
 
33
        unsigned int dev_count = 0, i;
 
34
 
 
35
        head = SLOF_alloc_mem(USB_DEVPOOL_SIZE);
 
36
        if (!head)
 
37
                return NULL;
 
38
 
 
39
        dev_count = USB_DEVPOOL_SIZE/sizeof(struct usb_dev);
 
40
        dprintf("%s: %d number of devices\n", __func__, dev_count);
 
41
        /* Although an array, link them*/
 
42
        for (i = 0, curr = head, prev = NULL; i < dev_count; i++, curr++) {
 
43
                if (prev)
 
44
                        prev->next = curr;
 
45
                curr->next = NULL;
 
46
                prev = curr;
 
47
        }
 
48
 
 
49
#ifdef DEBUG
 
50
        for (i = 0, curr = head; curr; curr = curr->next)
 
51
                printf("%s: %d dev %p\n", __func__, i++, curr);
 
52
#endif
 
53
 
 
54
        return head;
 
55
}
 
56
 
 
57
struct usb_dev *usb_devpool_get(void)
 
58
{
 
59
        struct usb_dev *new;
 
60
 
 
61
        if (!devpool) {
 
62
                devpool = usb_alloc_devpool();
 
63
                if (!devpool)
 
64
                        return NULL;
 
65
        }
 
66
 
 
67
        new = devpool;
 
68
        devpool = devpool->next;
 
69
        memset(new, 0, sizeof(*new));
 
70
        new->next = NULL;
 
71
        return new;
 
72
}
 
73
 
 
74
void usb_devpool_put(struct usb_dev *dev)
 
75
{
 
76
        struct usb_dev *curr;
 
77
        if (!dev && !devpool)
 
78
                return;
 
79
 
 
80
        curr = devpool;
 
81
        while (curr->next)
 
82
                curr = curr->next;
 
83
        curr->next = dev;
 
84
        dev->next = NULL;
 
85
}
 
86
 
 
87
#ifndef DEBUG
 
88
#define validate_hcd_ops(dev) (dev && dev->hcidev && dev->hcidev->ops)
 
89
#else
 
90
int validate_hcd_ops(struct usb_dev *dev)
 
91
{
 
92
        int ret = true;
 
93
 
 
94
        if (!dev) {
 
95
                printf("dev is NULL\n");
 
96
                ret = false;
 
97
        } else if (!dev->hcidev) {
 
98
                printf("hcidev is NULL\n");
 
99
                ret = false;
 
100
        } else if (!dev->hcidev->ops)  {
 
101
                printf("ops is NULL\n");
 
102
                ret = false;
 
103
        }
 
104
        return ret;
 
105
}
 
106
#endif
 
107
 
 
108
struct usb_pipe *usb_get_pipe(struct usb_dev *dev, struct usb_ep_descr *ep,
 
109
                        char *buf, size_t len)
 
110
{
 
111
        if (validate_hcd_ops(dev) && dev->hcidev->ops->get_pipe)
 
112
                return dev->hcidev->ops->get_pipe(dev, ep, buf, len);
 
113
        else {
 
114
                printf("%s: Failed\n", __func__);
 
115
                return NULL;
 
116
        }
 
117
}
 
118
 
 
119
void usb_put_pipe(struct usb_pipe *pipe)
 
120
{
 
121
        struct usb_dev *dev = NULL;
 
122
        if (pipe && pipe->dev) {
 
123
                dev = pipe->dev;
 
124
                if (validate_hcd_ops(dev) && dev->hcidev->ops->put_pipe)
 
125
                        dev->hcidev->ops->put_pipe(pipe);
 
126
        }
 
127
}
 
128
 
 
129
int usb_poll_intr(struct usb_pipe *pipe, uint8_t *buf)
 
130
{
 
131
        struct usb_dev *dev = NULL;
 
132
        if (pipe && pipe->dev) {
 
133
                dev = pipe->dev;
 
134
                if (validate_hcd_ops(dev) && dev->hcidev->ops->poll_intr)
 
135
                        return dev->hcidev->ops->poll_intr(pipe, buf);
 
136
        }
 
137
        return 0;
 
138
}
 
139
 
 
140
void usb_hcd_register(struct usb_hcd_ops *ops)
 
141
{
 
142
        struct usb_hcd_ops *list;
 
143
 
 
144
        if (!ops)
 
145
                printf("Error");
 
146
        dprintf("Registering %s %d\n", ops->name, ops->usb_type);
 
147
 
 
148
        if (head) {
 
149
                list = head;
 
150
                while (list->next)
 
151
                        list = list->next;
 
152
                list->next = ops;
 
153
        } else
 
154
                head = ops;
 
155
}
 
156
 
 
157
void usb_hcd_init(void *hcidev)
 
158
{
 
159
        struct usb_hcd_dev *dev = hcidev;
 
160
        struct usb_hcd_ops *list = head;
 
161
 
 
162
        if (!dev) {
 
163
                printf("Device Error");
 
164
                return;
 
165
        }
 
166
 
 
167
        while (list) {
 
168
                if (list->usb_type == dev->type) {
 
169
                        dprintf("usb_ops(%p) for the controller found\n", list);
 
170
                        dev->ops = list;
 
171
                        dev->ops->init(dev);
 
172
                        return;
 
173
                }
 
174
                list = list->next;
 
175
        }
 
176
 
 
177
        dprintf("usb_ops for the controller not found\n");
 
178
}
 
179
 
 
180
void usb_hcd_exit(void *_hcidev)
 
181
{
 
182
        struct usb_hcd_dev *hcidev = _hcidev;
 
183
 
 
184
        dprintf("%s: enter \n", __func__);
 
185
        if (!hcidev) {
 
186
                printf("Device Error");
 
187
                return;
 
188
        }
 
189
 
 
190
        if (hcidev->ops->exit)
 
191
                hcidev->ops->exit(hcidev);
 
192
}
 
193
 
 
194
int usb_send_ctrl(struct usb_pipe *pipe, struct usb_dev_req *req, void *data)
 
195
{
 
196
        struct usb_dev *dev = NULL;
 
197
        if (!pipe)
 
198
                return false;
 
199
        dev = pipe->dev;
 
200
        if (validate_hcd_ops(dev) && dev->hcidev->ops->send_ctrl)
 
201
                return dev->hcidev->ops->send_ctrl(pipe, req, data);
 
202
        else {
 
203
                printf("%s: Failed\n", __func__);
 
204
                return false;
 
205
        }
 
206
}
 
207
 
 
208
int usb_transfer_ctrl(void *dev, void *req, void *data)
 
209
{
 
210
        struct usb_pipe *pipe = NULL;
 
211
        struct usb_dev *usbdev;
 
212
 
 
213
        if (!dev)
 
214
                return false;
 
215
        usbdev = (struct usb_dev *)dev;
 
216
        pipe = usbdev->control;
 
217
        return usb_send_ctrl(pipe, req, data);
 
218
}
 
219
 
 
220
int usb_transfer_bulk(void *dev, int dir, void *td, void *td_phys, void *data, int size)
 
221
{
 
222
        struct usb_pipe *pipe = NULL;
 
223
        struct usb_dev *usbdev;
 
224
 
 
225
        if (!dev)
 
226
                return false;
 
227
        usbdev = (struct usb_dev *)dev;
 
228
        pipe = (dir == USB_PIPE_OUT) ? usbdev->bulk_out : usbdev->bulk_in;
 
229
        if (!pipe)
 
230
                return false;
 
231
        if (validate_hcd_ops(usbdev) && usbdev->hcidev->ops->transfer_bulk)
 
232
                return usbdev->hcidev->ops->transfer_bulk(pipe, td, td_phys, data, size);
 
233
        else {
 
234
                printf("%s: Failed\n", __func__);
 
235
                return false;
 
236
        }
 
237
}
 
238
 
 
239
/*
 
240
 * USB Specification 1.1
 
241
 *     9.3 USB Device Requests
 
242
 *     9.4 Standard Device Requests
 
243
 */
 
244
static int usb_set_address(struct usb_dev *dev, uint32_t port)
 
245
{
 
246
        struct usb_dev_req req;
 
247
        struct usb_hcd_dev *hcidev;
 
248
 
 
249
        if (!dev)
 
250
                return false;
 
251
 
 
252
        hcidev = dev->hcidev;
 
253
        req.bmRequestType = 0;
 
254
        req.bRequest = REQ_SET_ADDRESS;
 
255
        req.wIndex = 0;
 
256
        req.wLength = 0;
 
257
        req.wValue = cpu_to_le16((uint16_t)(hcidev->nextaddr));
 
258
        if (usb_send_ctrl(dev->control, &req, NULL)) {
 
259
                dev->addr = hcidev->nextaddr++;
 
260
                return true;
 
261
        } else
 
262
                return false;
 
263
}
 
264
 
 
265
static int usb_get_device_descr(struct usb_dev *dev, void *data, size_t size)
 
266
{
 
267
        struct usb_dev_req req;
 
268
 
 
269
        if (!dev)
 
270
                return false;
 
271
 
 
272
        req.bmRequestType = 0x80;
 
273
        req.bRequest = REQ_GET_DESCRIPTOR;
 
274
        req.wIndex = 0;
 
275
        req.wLength = cpu_to_le16((uint16_t) size);
 
276
        req.wValue = cpu_to_le16(DESCR_TYPE_DEVICE << 8);
 
277
        return usb_send_ctrl(dev->control, &req, data);
 
278
}
 
279
 
 
280
static int usb_get_config_descr(struct usb_dev *dev, void *data, size_t size)
 
281
{
 
282
        struct usb_dev_req req;
 
283
 
 
284
        if (!dev)
 
285
                return false;
 
286
 
 
287
        req.bmRequestType = 0x80;
 
288
        req.bRequest = REQ_GET_DESCRIPTOR;
 
289
        req.wIndex = 0;
 
290
        req.wLength = cpu_to_le16((uint16_t) size);
 
291
        req.wValue = cpu_to_le16(DESCR_TYPE_CONFIGURATION << 8);
 
292
        return usb_send_ctrl(dev->control, &req, data);
 
293
 
 
294
}
 
295
 
 
296
static int usb_set_config(struct usb_dev *dev, uint8_t cfg_value)
 
297
{
 
298
        struct usb_dev_req req;
 
299
 
 
300
        if (!dev)
 
301
                return false;
 
302
 
 
303
        req.bmRequestType = 0x00;
 
304
        req.bRequest = REQ_SET_CONFIGURATION;
 
305
        req.wIndex = 0;
 
306
        req.wLength = 0;
 
307
        req.wValue = cpu_to_le16(0x00FF & cfg_value);
 
308
        return usb_send_ctrl(dev->control, &req, NULL);
 
309
}
 
310
 
 
311
static int usb_clear_halt(struct usb_pipe *pipe)
 
312
{
 
313
        struct usb_dev_req req;
 
314
        struct usb_dev *dev;
 
315
 
 
316
        if (pipe && pipe->dev) {
 
317
                dev = pipe->dev;
 
318
                dprintf("Clearing port %d dir %d type %d\n",
 
319
                        pipe->epno, pipe->dir, pipe->type);
 
320
                req.bmRequestType = REQT_DIR_OUT | REQT_REC_EP;
 
321
                req.bRequest = REQ_CLEAR_FEATURE;
 
322
                req.wValue = FEATURE_ENDPOINT_HALT;
 
323
                req.wIndex = cpu_to_le16(pipe->epno | pipe->dir);
 
324
                req.wLength = 0;
 
325
                return usb_send_ctrl(dev->control, &req, NULL);
 
326
        }
 
327
        return false;
 
328
}
 
329
 
 
330
int usb_dev_populate_pipe(struct usb_dev *dev, struct usb_ep_descr *ep,
 
331
                        void *buf, size_t len)
 
332
{
 
333
        uint8_t dir, type;
 
334
 
 
335
        dir = (ep->bEndpointAddress & 0x80) >> 7;
 
336
        type = ep->bmAttributes & USB_EP_TYPE_MASK;
 
337
 
 
338
        dprintf("EP: %s: %d size %d type %d\n", dir ? "IN " : "OUT",
 
339
                ep->bEndpointAddress & 0xF, le16_to_cpu(ep->wMaxPacketSize),
 
340
                type);
 
341
        if (type == USB_EP_TYPE_BULK) {
 
342
                if (dir)
 
343
                        dev->bulk_in = usb_get_pipe(dev, ep, buf, len);
 
344
                else
 
345
                        dev->bulk_out = usb_get_pipe(dev, ep, buf, len);
 
346
        } else if (type == USB_EP_TYPE_INTR)
 
347
                dev->intr = usb_get_pipe(dev, ep, buf, len);
 
348
 
 
349
        return true;
 
350
}
 
351
 
 
352
static void usb_dev_copy_epdesc(struct usb_dev *dev, struct usb_ep_descr *ep)
 
353
{
 
354
        uint32_t ep_cnt;
 
355
 
 
356
        ep_cnt = dev->ep_cnt;
 
357
        if (ep_cnt < USB_DEV_EP_MAX)
 
358
                memcpy((void *)&dev->ep[ep_cnt], ep, sizeof(*ep));
 
359
        else
 
360
                dprintf("usb-core: only %d EPs supported\n", USB_DEV_EP_MAX);
 
361
        dev->ep_cnt++;
 
362
}
 
363
 
 
364
int usb_hid_init(void *vdev)
 
365
{
 
366
        struct usb_dev *dev;
 
367
        dev = (struct usb_dev *) vdev;
 
368
        if (!dev)
 
369
                return false;
 
370
        if (dev->class == DEV_HID_KEYB)
 
371
                usb_hid_kbd_init(dev);
 
372
        return true;
 
373
}
 
374
 
 
375
int usb_hid_exit(void *vdev)
 
376
{
 
377
        struct usb_dev *dev;
 
378
        dev = (struct usb_dev *) vdev;
 
379
        if (!dev)
 
380
                return false;
 
381
        if (dev->class == DEV_HID_KEYB)
 
382
                usb_hid_kbd_exit(dev);
 
383
        return true;
 
384
}
 
385
 
 
386
int usb_msc_init(void *vdev)
 
387
{
 
388
        struct usb_dev *dev;
 
389
        int i;
 
390
 
 
391
        dev = (struct usb_dev *) vdev;
 
392
        dprintf("%s: enter %x\n", __func__, dev->class);
 
393
        if (!dev)
 
394
                return false;
 
395
        if (usb_get_intf_class(dev->class) == 8) {
 
396
                for (i = 0; i < dev->ep_cnt; i++) {
 
397
                        if ((dev->ep[i].bmAttributes & USB_EP_TYPE_MASK)
 
398
                                == USB_EP_TYPE_BULK)
 
399
                                usb_dev_populate_pipe(dev, &dev->ep[i], NULL, 0);
 
400
                }
 
401
        }
 
402
        return true;
 
403
}
 
404
 
 
405
int usb_msc_exit(void *vdev)
 
406
{
 
407
        struct  usb_dev *dev;
 
408
        dev = (struct usb_dev *) vdev;
 
409
        dprintf("%s: enter %x\n", __func__, dev->class);
 
410
        if (!dev)
 
411
                return false;
 
412
        if (usb_get_intf_class(dev->class) == 8) {
 
413
                if (dev->bulk_in)
 
414
                        usb_put_pipe(dev->bulk_in);
 
415
                if (dev->bulk_out)
 
416
                        usb_put_pipe(dev->bulk_out);
 
417
        }
 
418
        return true;
 
419
}
 
420
 
 
421
int usb_msc_reset(struct usb_dev *dev)
 
422
{
 
423
        struct usb_dev_req req;
 
424
 
 
425
        if (!dev)
 
426
                return false;
 
427
 
 
428
        req.bmRequestType = REQT_TYPE_CLASS | REQT_REC_INTERFACE | REQT_DIR_OUT;
 
429
        req.bRequest = 0xFF;
 
430
        req.wLength = 0;
 
431
        req.wValue = 0;
 
432
        req.wIndex = cpu_to_le16(dev->intf_num);
 
433
        return usb_send_ctrl(dev->control, &req, NULL);
 
434
}
 
435
 
 
436
void usb_msc_resetrecovery(struct usb_dev *dev)
 
437
{
 
438
        // usb_msc_reset(dev);
 
439
        usb_clear_halt(dev->bulk_in);
 
440
        usb_clear_halt(dev->bulk_out);
 
441
        SLOF_msleep(2);
 
442
}
 
443
 
 
444
static int usb_handle_device(struct usb_dev *dev, struct usb_dev_config_descr *cfg,
 
445
                uint8_t *ptr, uint16_t len)
 
446
{
 
447
        struct usb_dev_intf_descr *intf = NULL;
 
448
        struct usb_ep_descr *ep = NULL;
 
449
        struct usb_dev_hid_descr *hid __unused = NULL;
 
450
        uint8_t desc_len, desc_type;
 
451
 
 
452
        len -= sizeof(struct usb_dev_config_descr);
 
453
        ptr = (uint8_t *)(ptr + sizeof(struct usb_dev_config_descr));
 
454
 
 
455
        while (len > 0) {
 
456
                desc_len = *ptr;
 
457
                desc_type = *(ptr + 1);
 
458
                switch (desc_type) {
 
459
                case DESCR_TYPE_INTERFACE:
 
460
                        intf = (struct usb_dev_intf_descr *)ptr;
 
461
                        dev->class = intf->bInterfaceClass << 16 |
 
462
                                intf->bInterfaceSubClass << 8 |
 
463
                                intf->bInterfaceProtocol;
 
464
                        break;
 
465
                case DESCR_TYPE_ENDPOINT:
 
466
                        ep = (struct usb_ep_descr *)ptr;
 
467
                        dev->intf_num = intf->bInterfaceNumber;
 
468
                        usb_dev_copy_epdesc(dev, ep);
 
469
                        break;
 
470
                case DESCR_TYPE_HID:
 
471
                        hid = (struct usb_dev_hid_descr *)ptr;
 
472
                        dprintf("hid-report %d size %d\n",
 
473
                                hid->bReportType, le16_to_cpu(hid->wReportLength));
 
474
                        break;
 
475
                case DESCR_TYPE_HUB:
 
476
                        break;
 
477
                default:
 
478
                        dprintf("ptr %p desc_type %d\n", ptr, desc_type);
 
479
                }
 
480
                ptr += desc_len;
 
481
                len -= desc_len;
 
482
        }
 
483
        return true;
 
484
}
 
485
 
 
486
int usb_setup_new_device(struct usb_dev *dev, unsigned int port)
 
487
{
 
488
        struct usb_dev_descr descr;
 
489
        struct usb_dev_config_descr cfg;
 
490
        struct usb_ep_descr ep;
 
491
        uint16_t len;
 
492
        void *data = NULL;
 
493
 
 
494
        dprintf("usb: %s - port %d\n", __func__, port);
 
495
 
 
496
        dev->addr = 0;
 
497
        dev->port = port;
 
498
        ep.bEndpointAddress = 0;
 
499
        ep.bmAttributes = USB_EP_TYPE_CONTROL;
 
500
        ep.wMaxPacketSize = cpu_to_le16(8);
 
501
        dev->control = usb_get_pipe(dev, &ep, NULL, 0);
 
502
 
 
503
        if (!usb_get_device_descr(dev, &descr, 8))
 
504
                goto fail;
 
505
        dev->control->mps = descr.bMaxPacketSize0;
 
506
 
 
507
        /*
 
508
         * For USB3.0 ADDRESS-SLOT command takes care of setting
 
509
         * address, skip this during generic device setup for USB3.0
 
510
         * devices
 
511
         */
 
512
        if (dev->speed != USB_SUPER_SPEED) {
 
513
                /*
 
514
                 * Qemu starts the port number from 1 which was
 
515
                 * revealed in bootindex and resulted in mismatch for
 
516
                 * storage devices names. Adjusting this here for
 
517
                 * compatibility.
 
518
                 */
 
519
                dev->port = port + 1;
 
520
                if(!usb_set_address(dev, dev->port))
 
521
                        goto fail;
 
522
        }
 
523
        mb();
 
524
        SLOF_msleep(100);
 
525
 
 
526
        if (!usb_get_device_descr(dev, &descr, sizeof(struct usb_dev_descr)))
 
527
                goto fail;
 
528
 
 
529
        if (!usb_get_config_descr(dev, &cfg, sizeof(struct usb_dev_config_descr)))
 
530
                goto fail;
 
531
 
 
532
        len = le16_to_cpu(cfg.wTotalLength);
 
533
        /* No device config descriptor present */
 
534
        if (len == sizeof(struct usb_dev_config_descr))
 
535
                goto fail;
 
536
 
 
537
        data = SLOF_dma_alloc(len);
 
538
        if (!data) {
 
539
                printf("%s: alloc failed %d\n", __func__, port);
 
540
                goto fail;
 
541
        }
 
542
 
 
543
        if (!usb_get_config_descr(dev, data, len))
 
544
                goto fail_mem_free;
 
545
        if (!usb_set_config(dev, cfg.bConfigurationValue))
 
546
                goto fail_mem_free;
 
547
        mb();
 
548
        SLOF_msleep(100);
 
549
 
 
550
        if (!usb_handle_device(dev, &cfg, data, len))
 
551
                goto fail_mem_free;
 
552
 
 
553
        SLOF_dma_free(data, len);
 
554
        return true;
 
555
fail_mem_free:
 
556
        SLOF_dma_free(data, len);
 
557
fail:
 
558
        return false;
 
559
}