Statistics
| Branch: | Revision:

root / hw / usb-bt.c @ 079d0b7f

History | View | Annotate | Download (16.7 kB)

1
/*
2
 * QEMU Bluetooth HCI USB Transport Layer v1.0
3
 *
4
 * Copyright (C) 2007 OpenMoko, Inc.
5
 * Copyright (C) 2008 Andrzej Zaborowski  <balrog@zabor.org>
6
 *
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU General Public License as
9
 * published by the Free Software Foundation; either version 2 or
10
 * (at your option) version 3 of the License.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License along
18
 * with this program; if not, see <http://www.gnu.org/licenses/>.
19
 */
20

    
21
#include "qemu-common.h"
22
#include "usb.h"
23
#include "usb-desc.h"
24
#include "net.h"
25
#include "bt.h"
26

    
27
struct USBBtState {
28
    USBDevice dev;
29
    struct HCIInfo *hci;
30

    
31
    int config;
32

    
33
#define CFIFO_LEN_MASK        255
34
#define DFIFO_LEN_MASK        4095
35
    struct usb_hci_in_fifo_s {
36
        uint8_t data[(DFIFO_LEN_MASK + 1) * 2];
37
        struct {
38
            uint8_t *data;
39
            int len;
40
        } fifo[CFIFO_LEN_MASK + 1];
41
        int dstart, dlen, dsize, start, len;
42
    } evt, acl, sco;
43

    
44
    struct usb_hci_out_fifo_s {
45
        uint8_t data[4096];
46
        int len;
47
    } outcmd, outacl, outsco;
48
};
49

    
50
#define USB_EVT_EP        1
51
#define USB_ACL_EP        2
52
#define USB_SCO_EP        3
53

    
54
enum {
55
    STR_MANUFACTURER = 1,
56
    STR_SERIALNUMBER,
57
};
58

    
59
static const USBDescStrings desc_strings = {
60
    [STR_MANUFACTURER]     = "QEMU " QEMU_VERSION,
61
    [STR_SERIALNUMBER]     = "1",
62
};
63

    
64
static const USBDescIface desc_iface_bluetooth[] = {
65
    {
66
        .bInterfaceNumber              = 0,
67
        .bNumEndpoints                 = 3,
68
        .bInterfaceClass               = 0xe0, /* Wireless */
69
        .bInterfaceSubClass            = 0x01, /* Radio Frequency */
70
        .bInterfaceProtocol            = 0x01, /* Bluetooth */
71
        .eps = (USBDescEndpoint[]) {
72
            {
73
                .bEndpointAddress      = USB_DIR_IN | USB_EVT_EP,
74
                .bmAttributes          = USB_ENDPOINT_XFER_INT,
75
                .wMaxPacketSize        = 0x10,
76
                .bInterval             = 0x02,
77
            },
78
            {
79
                .bEndpointAddress      = USB_DIR_OUT | USB_ACL_EP,
80
                .bmAttributes          = USB_ENDPOINT_XFER_BULK,
81
                .wMaxPacketSize        = 0x40,
82
                .bInterval             = 0x0a,
83
            },
84
            {
85
                .bEndpointAddress      = USB_DIR_IN | USB_ACL_EP,
86
                .bmAttributes          = USB_ENDPOINT_XFER_BULK,
87
                .wMaxPacketSize        = 0x40,
88
                .bInterval             = 0x0a,
89
            },
90
        },
91
    },{
92
        .bInterfaceNumber              = 1,
93
        .bAlternateSetting             = 0,
94
        .bNumEndpoints                 = 2,
95
        .bInterfaceClass               = 0xe0, /* Wireless */
96
        .bInterfaceSubClass            = 0x01, /* Radio Frequency */
97
        .bInterfaceProtocol            = 0x01, /* Bluetooth */
98
        .eps = (USBDescEndpoint[]) {
99
            {
100
                .bEndpointAddress      = USB_DIR_OUT | USB_SCO_EP,
101
                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
102
                .wMaxPacketSize        = 0,
103
                .bInterval             = 0x01,
104
            },
105
            {
106
                .bEndpointAddress      = USB_DIR_IN | USB_SCO_EP,
107
                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
108
                .wMaxPacketSize        = 0,
109
                .bInterval             = 0x01,
110
            },
111
        },
112
    },{
113
        .bInterfaceNumber              = 1,
114
        .bAlternateSetting             = 1,
115
        .bNumEndpoints                 = 2,
116
        .bInterfaceClass               = 0xe0, /* Wireless */
117
        .bInterfaceSubClass            = 0x01, /* Radio Frequency */
118
        .bInterfaceProtocol            = 0x01, /* Bluetooth */
119
        .eps = (USBDescEndpoint[]) {
120
            {
121
                .bEndpointAddress      = USB_DIR_OUT | USB_SCO_EP,
122
                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
123
                .wMaxPacketSize        = 0x09,
124
                .bInterval             = 0x01,
125
            },
126
            {
127
                .bEndpointAddress      = USB_DIR_IN | USB_SCO_EP,
128
                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
129
                .wMaxPacketSize        = 0x09,
130
                .bInterval             = 0x01,
131
            },
132
        },
133
    },{
134
        .bInterfaceNumber              = 1,
135
        .bAlternateSetting             = 2,
136
        .bNumEndpoints                 = 2,
137
        .bInterfaceClass               = 0xe0, /* Wireless */
138
        .bInterfaceSubClass            = 0x01, /* Radio Frequency */
139
        .bInterfaceProtocol            = 0x01, /* Bluetooth */
140
        .eps = (USBDescEndpoint[]) {
141
            {
142
                .bEndpointAddress      = USB_DIR_OUT | USB_SCO_EP,
143
                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
144
                .wMaxPacketSize        = 0x11,
145
                .bInterval             = 0x01,
146
            },
147
            {
148
                .bEndpointAddress      = USB_DIR_IN | USB_SCO_EP,
149
                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
150
                .wMaxPacketSize        = 0x11,
151
                .bInterval             = 0x01,
152
            },
153
        },
154
    },{
155
        .bInterfaceNumber              = 1,
156
        .bAlternateSetting             = 3,
157
        .bNumEndpoints                 = 2,
158
        .bInterfaceClass               = 0xe0, /* Wireless */
159
        .bInterfaceSubClass            = 0x01, /* Radio Frequency */
160
        .bInterfaceProtocol            = 0x01, /* Bluetooth */
161
        .eps = (USBDescEndpoint[]) {
162
            {
163
                .bEndpointAddress      = USB_DIR_OUT | USB_SCO_EP,
164
                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
165
                .wMaxPacketSize        = 0x19,
166
                .bInterval             = 0x01,
167
            },
168
            {
169
                .bEndpointAddress      = USB_DIR_IN | USB_SCO_EP,
170
                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
171
                .wMaxPacketSize        = 0x19,
172
                .bInterval             = 0x01,
173
            },
174
        },
175
    },{
176
        .bInterfaceNumber              = 1,
177
        .bAlternateSetting             = 4,
178
        .bNumEndpoints                 = 2,
179
        .bInterfaceClass               = 0xe0, /* Wireless */
180
        .bInterfaceSubClass            = 0x01, /* Radio Frequency */
181
        .bInterfaceProtocol            = 0x01, /* Bluetooth */
182
        .eps = (USBDescEndpoint[]) {
183
            {
184
                .bEndpointAddress      = USB_DIR_OUT | USB_SCO_EP,
185
                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
186
                .wMaxPacketSize        = 0x21,
187
                .bInterval             = 0x01,
188
            },
189
            {
190
                .bEndpointAddress      = USB_DIR_IN | USB_SCO_EP,
191
                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
192
                .wMaxPacketSize        = 0x21,
193
                .bInterval             = 0x01,
194
            },
195
        },
196
    },{
197
        .bInterfaceNumber              = 1,
198
        .bAlternateSetting             = 5,
199
        .bNumEndpoints                 = 2,
200
        .bInterfaceClass               = 0xe0, /* Wireless */
201
        .bInterfaceSubClass            = 0x01, /* Radio Frequency */
202
        .bInterfaceProtocol            = 0x01, /* Bluetooth */
203
        .eps = (USBDescEndpoint[]) {
204
            {
205
                .bEndpointAddress      = USB_DIR_OUT | USB_SCO_EP,
206
                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
207
                .wMaxPacketSize        = 0x31,
208
                .bInterval             = 0x01,
209
            },
210
            {
211
                .bEndpointAddress      = USB_DIR_IN | USB_SCO_EP,
212
                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
213
                .wMaxPacketSize        = 0x31,
214
                .bInterval             = 0x01,
215
            },
216
        },
217
    }
218
};
219

    
220
static const USBDescDevice desc_device_bluetooth = {
221
    .bcdUSB                        = 0x0110,
222
    .bDeviceClass                  = 0xe0, /* Wireless */
223
    .bDeviceSubClass               = 0x01, /* Radio Frequency */
224
    .bDeviceProtocol               = 0x01, /* Bluetooth */
225
    .bMaxPacketSize0               = 64,
226
    .bNumConfigurations            = 1,
227
    .confs = (USBDescConfig[]) {
228
        {
229
            .bNumInterfaces        = 2,
230
            .bConfigurationValue   = 1,
231
            .bmAttributes          = 0xc0,
232
            .bMaxPower             = 0,
233
            .nif = ARRAY_SIZE(desc_iface_bluetooth),
234
            .ifs = desc_iface_bluetooth,
235
        },
236
    },
237
};
238

    
239
static const USBDesc desc_bluetooth = {
240
    .id = {
241
        .idVendor          = 0x0a12,
242
        .idProduct         = 0x0001,
243
        .bcdDevice         = 0x1958,
244
        .iManufacturer     = STR_MANUFACTURER,
245
        .iProduct          = 0,
246
        .iSerialNumber     = STR_SERIALNUMBER,
247
    },
248
    .full = &desc_device_bluetooth,
249
    .str  = desc_strings,
250
};
251

    
252
static void usb_bt_fifo_reset(struct usb_hci_in_fifo_s *fifo)
253
{
254
    fifo->dstart = 0;
255
    fifo->dlen = 0;
256
    fifo->dsize = DFIFO_LEN_MASK + 1;
257
    fifo->start = 0;
258
    fifo->len = 0;
259
}
260

    
261
static void usb_bt_fifo_enqueue(struct usb_hci_in_fifo_s *fifo,
262
                const uint8_t *data, int len)
263
{
264
    int off = fifo->dstart + fifo->dlen;
265
    uint8_t *buf;
266

    
267
    fifo->dlen += len;
268
    if (off <= DFIFO_LEN_MASK) {
269
        if (off + len > DFIFO_LEN_MASK + 1 &&
270
                        (fifo->dsize = off + len) > (DFIFO_LEN_MASK + 1) * 2) {
271
            fprintf(stderr, "%s: can't alloc %i bytes\n", __FUNCTION__, len);
272
            exit(-1);
273
        }
274
        buf = fifo->data + off;
275
    } else {
276
        if (fifo->dlen > fifo->dsize) {
277
            fprintf(stderr, "%s: can't alloc %i bytes\n", __FUNCTION__, len);
278
            exit(-1);
279
        }
280
        buf = fifo->data + off - fifo->dsize;
281
    }
282

    
283
    off = (fifo->start + fifo->len ++) & CFIFO_LEN_MASK;
284
    fifo->fifo[off].data = memcpy(buf, data, len);
285
    fifo->fifo[off].len = len;
286
}
287

    
288
static inline int usb_bt_fifo_dequeue(struct usb_hci_in_fifo_s *fifo,
289
                USBPacket *p)
290
{
291
    int len;
292

    
293
    if (likely(!fifo->len))
294
        return USB_RET_STALL;
295

    
296
    len = MIN(p->iov.size, fifo->fifo[fifo->start].len);
297
    usb_packet_copy(p, fifo->fifo[fifo->start].data, len);
298
    if (len == p->iov.size) {
299
        fifo->fifo[fifo->start].len -= len;
300
        fifo->fifo[fifo->start].data += len;
301
    } else {
302
        fifo->start ++;
303
        fifo->start &= CFIFO_LEN_MASK;
304
        fifo->len --;
305
    }
306

    
307
    fifo->dstart += len;
308
    fifo->dlen -= len;
309
    if (fifo->dstart >= fifo->dsize) {
310
        fifo->dstart = 0;
311
        fifo->dsize = DFIFO_LEN_MASK + 1;
312
    }
313

    
314
    return len;
315
}
316

    
317
static inline void usb_bt_fifo_out_enqueue(struct USBBtState *s,
318
                struct usb_hci_out_fifo_s *fifo,
319
                void (*send)(struct HCIInfo *, const uint8_t *, int),
320
                int (*complete)(const uint8_t *, int),
321
                USBPacket *p)
322
{
323
    usb_packet_copy(p, fifo->data + fifo->len, p->iov.size);
324
    fifo->len += p->iov.size;
325
    if (complete(fifo->data, fifo->len)) {
326
        send(s->hci, fifo->data, fifo->len);
327
        fifo->len = 0;
328
    }
329

    
330
    /* TODO: do we need to loop? */
331
}
332

    
333
static int usb_bt_hci_cmd_complete(const uint8_t *data, int len)
334
{
335
    len -= HCI_COMMAND_HDR_SIZE;
336
    return len >= 0 &&
337
            len >= ((struct hci_command_hdr *) data)->plen;
338
}
339

    
340
static int usb_bt_hci_acl_complete(const uint8_t *data, int len)
341
{
342
    len -= HCI_ACL_HDR_SIZE;
343
    return len >= 0 &&
344
            len >= le16_to_cpu(((struct hci_acl_hdr *) data)->dlen);
345
}
346

    
347
static int usb_bt_hci_sco_complete(const uint8_t *data, int len)
348
{
349
    len -= HCI_SCO_HDR_SIZE;
350
    return len >= 0 &&
351
            len >= ((struct hci_sco_hdr *) data)->dlen;
352
}
353

    
354
static void usb_bt_handle_reset(USBDevice *dev)
355
{
356
    struct USBBtState *s = (struct USBBtState *) dev->opaque;
357

    
358
    usb_bt_fifo_reset(&s->evt);
359
    usb_bt_fifo_reset(&s->acl);
360
    usb_bt_fifo_reset(&s->sco);
361
    s->outcmd.len = 0;
362
    s->outacl.len = 0;
363
    s->outsco.len = 0;
364
}
365

    
366
static int usb_bt_handle_control(USBDevice *dev, USBPacket *p,
367
               int request, int value, int index, int length, uint8_t *data)
368
{
369
    struct USBBtState *s = (struct USBBtState *) dev->opaque;
370
    int ret;
371

    
372
    ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
373
    if (ret >= 0) {
374
        switch (request) {
375
        case DeviceRequest | USB_REQ_GET_CONFIGURATION:
376
            s->config = 0;
377
            break;
378
        case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
379
            s->config = 1;
380
            usb_bt_fifo_reset(&s->evt);
381
            usb_bt_fifo_reset(&s->acl);
382
            usb_bt_fifo_reset(&s->sco);
383
            break;
384
        }
385
        return ret;
386
    }
387

    
388
    ret = 0;
389
    switch (request) {
390
    case InterfaceRequest | USB_REQ_GET_STATUS:
391
    case EndpointRequest | USB_REQ_GET_STATUS:
392
        data[0] = 0x00;
393
        data[1] = 0x00;
394
        ret = 2;
395
        break;
396
    case InterfaceOutRequest | USB_REQ_CLEAR_FEATURE:
397
    case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
398
        goto fail;
399
    case InterfaceOutRequest | USB_REQ_SET_FEATURE:
400
    case EndpointOutRequest | USB_REQ_SET_FEATURE:
401
        goto fail;
402
        break;
403
    case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE) << 8):
404
        if (s->config)
405
            usb_bt_fifo_out_enqueue(s, &s->outcmd, s->hci->cmd_send,
406
                            usb_bt_hci_cmd_complete, p);
407
        break;
408
    default:
409
    fail:
410
        ret = USB_RET_STALL;
411
        break;
412
    }
413
    return ret;
414
}
415

    
416
static int usb_bt_handle_data(USBDevice *dev, USBPacket *p)
417
{
418
    struct USBBtState *s = (struct USBBtState *) dev->opaque;
419
    int ret = 0;
420

    
421
    if (!s->config)
422
        goto fail;
423

    
424
    switch (p->pid) {
425
    case USB_TOKEN_IN:
426
        switch (p->ep->nr) {
427
        case USB_EVT_EP:
428
            ret = usb_bt_fifo_dequeue(&s->evt, p);
429
            break;
430

    
431
        case USB_ACL_EP:
432
            ret = usb_bt_fifo_dequeue(&s->acl, p);
433
            break;
434

    
435
        case USB_SCO_EP:
436
            ret = usb_bt_fifo_dequeue(&s->sco, p);
437
            break;
438

    
439
        default:
440
            goto fail;
441
        }
442
        break;
443

    
444
    case USB_TOKEN_OUT:
445
        switch (p->ep->nr) {
446
        case USB_ACL_EP:
447
            usb_bt_fifo_out_enqueue(s, &s->outacl, s->hci->acl_send,
448
                            usb_bt_hci_acl_complete, p);
449
            break;
450

    
451
        case USB_SCO_EP:
452
            usb_bt_fifo_out_enqueue(s, &s->outsco, s->hci->sco_send,
453
                            usb_bt_hci_sco_complete, p);
454
            break;
455

    
456
        default:
457
            goto fail;
458
        }
459
        break;
460

    
461
    default:
462
    fail:
463
        ret = USB_RET_STALL;
464
        break;
465
    }
466

    
467
    return ret;
468
}
469

    
470
static void usb_bt_out_hci_packet_event(void *opaque,
471
                const uint8_t *data, int len)
472
{
473
    struct USBBtState *s = (struct USBBtState *) opaque;
474

    
475
    usb_bt_fifo_enqueue(&s->evt, data, len);
476
}
477

    
478
static void usb_bt_out_hci_packet_acl(void *opaque,
479
                const uint8_t *data, int len)
480
{
481
    struct USBBtState *s = (struct USBBtState *) opaque;
482

    
483
    usb_bt_fifo_enqueue(&s->acl, data, len);
484
}
485

    
486
static void usb_bt_handle_destroy(USBDevice *dev)
487
{
488
    struct USBBtState *s = (struct USBBtState *) dev->opaque;
489

    
490
    s->hci->opaque = NULL;
491
    s->hci->evt_recv = NULL;
492
    s->hci->acl_recv = NULL;
493
}
494

    
495
static int usb_bt_initfn(USBDevice *dev)
496
{
497
    usb_desc_init(dev);
498
    return 0;
499
}
500

    
501
USBDevice *usb_bt_init(HCIInfo *hci)
502
{
503
    USBDevice *dev;
504
    struct USBBtState *s;
505

    
506
    if (!hci)
507
        return NULL;
508
    dev = usb_create_simple(NULL /* FIXME */, "usb-bt-dongle");
509
    if (!dev) {
510
        return NULL;
511
    }
512
    s = DO_UPCAST(struct USBBtState, dev, dev);
513
    s->dev.opaque = s;
514

    
515
    s->hci = hci;
516
    s->hci->opaque = s;
517
    s->hci->evt_recv = usb_bt_out_hci_packet_event;
518
    s->hci->acl_recv = usb_bt_out_hci_packet_acl;
519

    
520
    usb_bt_handle_reset(&s->dev);
521

    
522
    return dev;
523
}
524

    
525
static const VMStateDescription vmstate_usb_bt = {
526
    .name = "usb-bt",
527
    .unmigratable = 1,
528
};
529

    
530
static void usb_bt_class_initfn(ObjectClass *klass, void *data)
531
{
532
    DeviceClass *dc = DEVICE_CLASS(klass);
533
    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
534

    
535
    uc->init           = usb_bt_initfn;
536
    uc->product_desc   = "QEMU BT dongle";
537
    uc->usb_desc       = &desc_bluetooth;
538
    uc->handle_reset   = usb_bt_handle_reset;
539
    uc->handle_control = usb_bt_handle_control;
540
    uc->handle_data    = usb_bt_handle_data;
541
    uc->handle_destroy = usb_bt_handle_destroy;
542
    dc->vmsd = &vmstate_usb_bt;
543
}
544

    
545
static TypeInfo bt_info = {
546
    .name          = "usb-bt-dongle",
547
    .parent        = TYPE_USB_DEVICE,
548
    .instance_size = sizeof(struct USBBtState),
549
    .class_init    = usb_bt_class_initfn,
550
};
551

    
552
static void usb_bt_register_devices(void)
553
{
554
    type_register_static(&bt_info);
555
}
556
device_init(usb_bt_register_devices)