linux-user/sparc: Fix cpu_clone_regs_*
[qemu.git] / hw / usb / dev-bluetooth.c
blobf6944fa74f15e8440056bca6237be4d80be30b1e
1 /*
2 * QEMU Bluetooth HCI USB Transport Layer v1.0
4 * Copyright (C) 2007 OpenMoko, Inc.
5 * Copyright (C) 2008 Andrzej Zaborowski <balrog@zabor.org>
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.
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.
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/>.
21 #include "qemu/osdep.h"
22 #include "qemu/error-report.h"
23 #include "qemu/module.h"
24 #include "hw/usb.h"
25 #include "migration/vmstate.h"
26 #include "desc.h"
27 #include "sysemu/bt.h"
28 #include "hw/bt.h"
30 struct USBBtState {
31 USBDevice dev;
32 struct HCIInfo *hci;
33 USBEndpoint *intr;
35 int config;
37 #define CFIFO_LEN_MASK 255
38 #define DFIFO_LEN_MASK 4095
39 struct usb_hci_in_fifo_s {
40 uint8_t data[(DFIFO_LEN_MASK + 1) * 2];
41 struct {
42 uint8_t *data;
43 int len;
44 } fifo[CFIFO_LEN_MASK + 1];
45 int dstart, dlen, dsize, start, len;
46 } evt, acl, sco;
48 struct usb_hci_out_fifo_s {
49 uint8_t data[4096];
50 int len;
51 } outcmd, outacl, outsco;
54 #define TYPE_USB_BT "usb-bt-dongle"
55 #define USB_BT(obj) OBJECT_CHECK(struct USBBtState, (obj), TYPE_USB_BT)
57 #define USB_EVT_EP 1
58 #define USB_ACL_EP 2
59 #define USB_SCO_EP 3
61 enum {
62 STR_MANUFACTURER = 1,
63 STR_SERIALNUMBER,
66 static const USBDescStrings desc_strings = {
67 [STR_MANUFACTURER] = "QEMU",
68 [STR_SERIALNUMBER] = "1",
71 static const USBDescIface desc_iface_bluetooth[] = {
73 .bInterfaceNumber = 0,
74 .bNumEndpoints = 3,
75 .bInterfaceClass = 0xe0, /* Wireless */
76 .bInterfaceSubClass = 0x01, /* Radio Frequency */
77 .bInterfaceProtocol = 0x01, /* Bluetooth */
78 .eps = (USBDescEndpoint[]) {
80 .bEndpointAddress = USB_DIR_IN | USB_EVT_EP,
81 .bmAttributes = USB_ENDPOINT_XFER_INT,
82 .wMaxPacketSize = 0x10,
83 .bInterval = 0x02,
86 .bEndpointAddress = USB_DIR_OUT | USB_ACL_EP,
87 .bmAttributes = USB_ENDPOINT_XFER_BULK,
88 .wMaxPacketSize = 0x40,
89 .bInterval = 0x0a,
92 .bEndpointAddress = USB_DIR_IN | USB_ACL_EP,
93 .bmAttributes = USB_ENDPOINT_XFER_BULK,
94 .wMaxPacketSize = 0x40,
95 .bInterval = 0x0a,
98 },{
99 .bInterfaceNumber = 1,
100 .bAlternateSetting = 0,
101 .bNumEndpoints = 2,
102 .bInterfaceClass = 0xe0, /* Wireless */
103 .bInterfaceSubClass = 0x01, /* Radio Frequency */
104 .bInterfaceProtocol = 0x01, /* Bluetooth */
105 .eps = (USBDescEndpoint[]) {
107 .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP,
108 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
109 .wMaxPacketSize = 0,
110 .bInterval = 0x01,
113 .bEndpointAddress = USB_DIR_IN | USB_SCO_EP,
114 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
115 .wMaxPacketSize = 0,
116 .bInterval = 0x01,
120 .bInterfaceNumber = 1,
121 .bAlternateSetting = 1,
122 .bNumEndpoints = 2,
123 .bInterfaceClass = 0xe0, /* Wireless */
124 .bInterfaceSubClass = 0x01, /* Radio Frequency */
125 .bInterfaceProtocol = 0x01, /* Bluetooth */
126 .eps = (USBDescEndpoint[]) {
128 .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP,
129 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
130 .wMaxPacketSize = 0x09,
131 .bInterval = 0x01,
134 .bEndpointAddress = USB_DIR_IN | USB_SCO_EP,
135 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
136 .wMaxPacketSize = 0x09,
137 .bInterval = 0x01,
141 .bInterfaceNumber = 1,
142 .bAlternateSetting = 2,
143 .bNumEndpoints = 2,
144 .bInterfaceClass = 0xe0, /* Wireless */
145 .bInterfaceSubClass = 0x01, /* Radio Frequency */
146 .bInterfaceProtocol = 0x01, /* Bluetooth */
147 .eps = (USBDescEndpoint[]) {
149 .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP,
150 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
151 .wMaxPacketSize = 0x11,
152 .bInterval = 0x01,
155 .bEndpointAddress = USB_DIR_IN | USB_SCO_EP,
156 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
157 .wMaxPacketSize = 0x11,
158 .bInterval = 0x01,
162 .bInterfaceNumber = 1,
163 .bAlternateSetting = 3,
164 .bNumEndpoints = 2,
165 .bInterfaceClass = 0xe0, /* Wireless */
166 .bInterfaceSubClass = 0x01, /* Radio Frequency */
167 .bInterfaceProtocol = 0x01, /* Bluetooth */
168 .eps = (USBDescEndpoint[]) {
170 .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP,
171 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
172 .wMaxPacketSize = 0x19,
173 .bInterval = 0x01,
176 .bEndpointAddress = USB_DIR_IN | USB_SCO_EP,
177 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
178 .wMaxPacketSize = 0x19,
179 .bInterval = 0x01,
183 .bInterfaceNumber = 1,
184 .bAlternateSetting = 4,
185 .bNumEndpoints = 2,
186 .bInterfaceClass = 0xe0, /* Wireless */
187 .bInterfaceSubClass = 0x01, /* Radio Frequency */
188 .bInterfaceProtocol = 0x01, /* Bluetooth */
189 .eps = (USBDescEndpoint[]) {
191 .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP,
192 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
193 .wMaxPacketSize = 0x21,
194 .bInterval = 0x01,
197 .bEndpointAddress = USB_DIR_IN | USB_SCO_EP,
198 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
199 .wMaxPacketSize = 0x21,
200 .bInterval = 0x01,
204 .bInterfaceNumber = 1,
205 .bAlternateSetting = 5,
206 .bNumEndpoints = 2,
207 .bInterfaceClass = 0xe0, /* Wireless */
208 .bInterfaceSubClass = 0x01, /* Radio Frequency */
209 .bInterfaceProtocol = 0x01, /* Bluetooth */
210 .eps = (USBDescEndpoint[]) {
212 .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP,
213 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
214 .wMaxPacketSize = 0x31,
215 .bInterval = 0x01,
218 .bEndpointAddress = USB_DIR_IN | USB_SCO_EP,
219 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
220 .wMaxPacketSize = 0x31,
221 .bInterval = 0x01,
227 static const USBDescDevice desc_device_bluetooth = {
228 .bcdUSB = 0x0110,
229 .bDeviceClass = 0xe0, /* Wireless */
230 .bDeviceSubClass = 0x01, /* Radio Frequency */
231 .bDeviceProtocol = 0x01, /* Bluetooth */
232 .bMaxPacketSize0 = 64,
233 .bNumConfigurations = 1,
234 .confs = (USBDescConfig[]) {
236 .bNumInterfaces = 2,
237 .bConfigurationValue = 1,
238 .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
239 .bMaxPower = 0,
240 .nif = ARRAY_SIZE(desc_iface_bluetooth),
241 .ifs = desc_iface_bluetooth,
246 static const USBDesc desc_bluetooth = {
247 .id = {
248 .idVendor = 0x0a12,
249 .idProduct = 0x0001,
250 .bcdDevice = 0x1958,
251 .iManufacturer = STR_MANUFACTURER,
252 .iProduct = 0,
253 .iSerialNumber = STR_SERIALNUMBER,
255 .full = &desc_device_bluetooth,
256 .str = desc_strings,
259 static void usb_bt_fifo_reset(struct usb_hci_in_fifo_s *fifo)
261 fifo->dstart = 0;
262 fifo->dlen = 0;
263 fifo->dsize = DFIFO_LEN_MASK + 1;
264 fifo->start = 0;
265 fifo->len = 0;
268 static void usb_bt_fifo_enqueue(struct usb_hci_in_fifo_s *fifo,
269 const uint8_t *data, int len)
271 int off = fifo->dstart + fifo->dlen;
272 uint8_t *buf;
274 fifo->dlen += len;
275 if (off <= DFIFO_LEN_MASK) {
276 if (off + len > DFIFO_LEN_MASK + 1 &&
277 (fifo->dsize = off + len) > (DFIFO_LEN_MASK + 1) * 2) {
278 fprintf(stderr, "%s: can't alloc %i bytes\n", __func__, len);
279 exit(-1);
281 buf = fifo->data + off;
282 } else {
283 if (fifo->dlen > fifo->dsize) {
284 fprintf(stderr, "%s: can't alloc %i bytes\n", __func__, len);
285 exit(-1);
287 buf = fifo->data + off - fifo->dsize;
290 off = (fifo->start + fifo->len ++) & CFIFO_LEN_MASK;
291 fifo->fifo[off].data = memcpy(buf, data, len);
292 fifo->fifo[off].len = len;
295 static inline void usb_bt_fifo_dequeue(struct usb_hci_in_fifo_s *fifo,
296 USBPacket *p)
298 int len;
300 assert(fifo->len != 0);
302 len = MIN(p->iov.size, fifo->fifo[fifo->start].len);
303 usb_packet_copy(p, fifo->fifo[fifo->start].data, len);
304 if (len == p->iov.size) {
305 fifo->fifo[fifo->start].len -= len;
306 fifo->fifo[fifo->start].data += len;
307 } else {
308 fifo->start ++;
309 fifo->start &= CFIFO_LEN_MASK;
310 fifo->len --;
313 fifo->dstart += len;
314 fifo->dlen -= len;
315 if (fifo->dstart >= fifo->dsize) {
316 fifo->dstart = 0;
317 fifo->dsize = DFIFO_LEN_MASK + 1;
321 static inline void usb_bt_fifo_out_enqueue(struct USBBtState *s,
322 struct usb_hci_out_fifo_s *fifo,
323 void (*send)(struct HCIInfo *, const uint8_t *, int),
324 int (*complete)(const uint8_t *, int),
325 USBPacket *p)
327 usb_packet_copy(p, fifo->data + fifo->len, p->iov.size);
328 fifo->len += p->iov.size;
329 if (complete(fifo->data, fifo->len)) {
330 send(s->hci, fifo->data, fifo->len);
331 fifo->len = 0;
334 /* TODO: do we need to loop? */
337 static int usb_bt_hci_cmd_complete(const uint8_t *data, int len)
339 len -= HCI_COMMAND_HDR_SIZE;
340 return len >= 0 &&
341 len >= ((struct hci_command_hdr *) data)->plen;
344 static int usb_bt_hci_acl_complete(const uint8_t *data, int len)
346 len -= HCI_ACL_HDR_SIZE;
347 return len >= 0 &&
348 len >= le16_to_cpu(((struct hci_acl_hdr *) data)->dlen);
351 static int usb_bt_hci_sco_complete(const uint8_t *data, int len)
353 len -= HCI_SCO_HDR_SIZE;
354 return len >= 0 &&
355 len >= ((struct hci_sco_hdr *) data)->dlen;
358 static void usb_bt_handle_reset(USBDevice *dev)
360 struct USBBtState *s = (struct USBBtState *) dev->opaque;
362 usb_bt_fifo_reset(&s->evt);
363 usb_bt_fifo_reset(&s->acl);
364 usb_bt_fifo_reset(&s->sco);
365 s->outcmd.len = 0;
366 s->outacl.len = 0;
367 s->outsco.len = 0;
370 static void usb_bt_handle_control(USBDevice *dev, USBPacket *p,
371 int request, int value, int index, int length, uint8_t *data)
373 struct USBBtState *s = (struct USBBtState *) dev->opaque;
374 int ret;
376 ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
377 if (ret >= 0) {
378 switch (request) {
379 case DeviceRequest | USB_REQ_GET_CONFIGURATION:
380 s->config = 0;
381 break;
382 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
383 s->config = 1;
384 usb_bt_fifo_reset(&s->evt);
385 usb_bt_fifo_reset(&s->acl);
386 usb_bt_fifo_reset(&s->sco);
387 break;
389 return;
392 switch (request) {
393 case InterfaceRequest | USB_REQ_GET_STATUS:
394 case EndpointRequest | USB_REQ_GET_STATUS:
395 data[0] = 0x00;
396 data[1] = 0x00;
397 p->actual_length = 2;
398 break;
399 case InterfaceOutRequest | USB_REQ_CLEAR_FEATURE:
400 case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
401 goto fail;
402 case InterfaceOutRequest | USB_REQ_SET_FEATURE:
403 case EndpointOutRequest | USB_REQ_SET_FEATURE:
404 goto fail;
405 break;
406 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE) << 8):
407 if (s->config)
408 usb_bt_fifo_out_enqueue(s, &s->outcmd, s->hci->cmd_send,
409 usb_bt_hci_cmd_complete, p);
410 break;
411 default:
412 fail:
413 p->status = USB_RET_STALL;
414 break;
418 static void usb_bt_handle_data(USBDevice *dev, USBPacket *p)
420 struct USBBtState *s = (struct USBBtState *) dev->opaque;
422 if (!s->config)
423 goto fail;
425 switch (p->pid) {
426 case USB_TOKEN_IN:
427 switch (p->ep->nr) {
428 case USB_EVT_EP:
429 if (s->evt.len == 0) {
430 p->status = USB_RET_NAK;
431 break;
433 usb_bt_fifo_dequeue(&s->evt, p);
434 break;
436 case USB_ACL_EP:
437 if (s->evt.len == 0) {
438 p->status = USB_RET_STALL;
439 break;
441 usb_bt_fifo_dequeue(&s->acl, p);
442 break;
444 case USB_SCO_EP:
445 if (s->evt.len == 0) {
446 p->status = USB_RET_STALL;
447 break;
449 usb_bt_fifo_dequeue(&s->sco, p);
450 break;
452 default:
453 goto fail;
455 break;
457 case USB_TOKEN_OUT:
458 switch (p->ep->nr) {
459 case USB_ACL_EP:
460 usb_bt_fifo_out_enqueue(s, &s->outacl, s->hci->acl_send,
461 usb_bt_hci_acl_complete, p);
462 break;
464 case USB_SCO_EP:
465 usb_bt_fifo_out_enqueue(s, &s->outsco, s->hci->sco_send,
466 usb_bt_hci_sco_complete, p);
467 break;
469 default:
470 goto fail;
472 break;
474 default:
475 fail:
476 p->status = USB_RET_STALL;
477 break;
481 static void usb_bt_out_hci_packet_event(void *opaque,
482 const uint8_t *data, int len)
484 struct USBBtState *s = (struct USBBtState *) opaque;
486 if (s->evt.len == 0) {
487 usb_wakeup(s->intr, 0);
489 usb_bt_fifo_enqueue(&s->evt, data, len);
492 static void usb_bt_out_hci_packet_acl(void *opaque,
493 const uint8_t *data, int len)
495 struct USBBtState *s = (struct USBBtState *) opaque;
497 usb_bt_fifo_enqueue(&s->acl, data, len);
500 static void usb_bt_unrealize(USBDevice *dev, Error **errp)
502 struct USBBtState *s = (struct USBBtState *) dev->opaque;
504 s->hci->opaque = NULL;
505 s->hci->evt_recv = NULL;
506 s->hci->acl_recv = NULL;
509 static void usb_bt_realize(USBDevice *dev, Error **errp)
511 struct USBBtState *s = USB_BT(dev);
513 usb_desc_create_serial(dev);
514 usb_desc_init(dev);
515 s->dev.opaque = s;
516 if (!s->hci) {
517 s->hci = bt_new_hci(qemu_find_bt_vlan(0));
519 s->hci->opaque = s;
520 s->hci->evt_recv = usb_bt_out_hci_packet_event;
521 s->hci->acl_recv = usb_bt_out_hci_packet_acl;
522 usb_bt_handle_reset(&s->dev);
523 s->intr = usb_ep_get(dev, USB_TOKEN_IN, USB_EVT_EP);
526 static USBDevice *usb_bt_init(USBBus *bus, const char *cmdline)
528 USBDevice *dev;
529 struct USBBtState *s;
530 HCIInfo *hci;
531 const char *name = TYPE_USB_BT;
533 if (*cmdline) {
534 hci = hci_init(cmdline);
535 } else {
536 hci = bt_new_hci(qemu_find_bt_vlan(0));
538 if (!hci)
539 return NULL;
541 dev = usb_create(bus, name);
542 s = USB_BT(dev);
543 s->hci = hci;
544 return dev;
547 static const VMStateDescription vmstate_usb_bt = {
548 .name = "usb-bt",
549 .unmigratable = 1,
552 static void usb_bt_class_initfn(ObjectClass *klass, void *data)
554 DeviceClass *dc = DEVICE_CLASS(klass);
555 USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
557 uc->realize = usb_bt_realize;
558 uc->product_desc = "QEMU BT dongle";
559 uc->usb_desc = &desc_bluetooth;
560 uc->handle_reset = usb_bt_handle_reset;
561 uc->handle_control = usb_bt_handle_control;
562 uc->handle_data = usb_bt_handle_data;
563 uc->unrealize = usb_bt_unrealize;
564 dc->vmsd = &vmstate_usb_bt;
565 set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
568 static const TypeInfo bt_info = {
569 .name = TYPE_USB_BT,
570 .parent = TYPE_USB_DEVICE,
571 .instance_size = sizeof(struct USBBtState),
572 .class_init = usb_bt_class_initfn,
575 static void usb_bt_register_types(void)
577 type_register_static(&bt_info);
578 usb_legacy_register(TYPE_USB_BT, "bt", usb_bt_init);
581 type_init(usb_bt_register_types)