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"
25 #include "migration/vmstate.h"
27 #include "sysemu/bt.h"
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];
44 } fifo
[CFIFO_LEN_MASK
+ 1];
45 int dstart
, dlen
, dsize
, start
, len
;
48 struct usb_hci_out_fifo_s
{
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)
66 static const USBDescStrings desc_strings
= {
67 [STR_MANUFACTURER
] = "QEMU",
68 [STR_SERIALNUMBER
] = "1",
71 static const USBDescIface desc_iface_bluetooth
[] = {
73 .bInterfaceNumber
= 0,
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,
86 .bEndpointAddress
= USB_DIR_OUT
| USB_ACL_EP
,
87 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
88 .wMaxPacketSize
= 0x40,
92 .bEndpointAddress
= USB_DIR_IN
| USB_ACL_EP
,
93 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
94 .wMaxPacketSize
= 0x40,
99 .bInterfaceNumber
= 1,
100 .bAlternateSetting
= 0,
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
,
113 .bEndpointAddress
= USB_DIR_IN
| USB_SCO_EP
,
114 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
120 .bInterfaceNumber
= 1,
121 .bAlternateSetting
= 1,
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,
134 .bEndpointAddress
= USB_DIR_IN
| USB_SCO_EP
,
135 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
136 .wMaxPacketSize
= 0x09,
141 .bInterfaceNumber
= 1,
142 .bAlternateSetting
= 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,
155 .bEndpointAddress
= USB_DIR_IN
| USB_SCO_EP
,
156 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
157 .wMaxPacketSize
= 0x11,
162 .bInterfaceNumber
= 1,
163 .bAlternateSetting
= 3,
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,
176 .bEndpointAddress
= USB_DIR_IN
| USB_SCO_EP
,
177 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
178 .wMaxPacketSize
= 0x19,
183 .bInterfaceNumber
= 1,
184 .bAlternateSetting
= 4,
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,
197 .bEndpointAddress
= USB_DIR_IN
| USB_SCO_EP
,
198 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
199 .wMaxPacketSize
= 0x21,
204 .bInterfaceNumber
= 1,
205 .bAlternateSetting
= 5,
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,
218 .bEndpointAddress
= USB_DIR_IN
| USB_SCO_EP
,
219 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
220 .wMaxPacketSize
= 0x31,
227 static const USBDescDevice desc_device_bluetooth
= {
229 .bDeviceClass
= 0xe0, /* Wireless */
230 .bDeviceSubClass
= 0x01, /* Radio Frequency */
231 .bDeviceProtocol
= 0x01, /* Bluetooth */
232 .bMaxPacketSize0
= 64,
233 .bNumConfigurations
= 1,
234 .confs
= (USBDescConfig
[]) {
237 .bConfigurationValue
= 1,
238 .bmAttributes
= USB_CFG_ATT_ONE
| USB_CFG_ATT_SELFPOWER
,
240 .nif
= ARRAY_SIZE(desc_iface_bluetooth
),
241 .ifs
= desc_iface_bluetooth
,
246 static const USBDesc desc_bluetooth
= {
251 .iManufacturer
= STR_MANUFACTURER
,
253 .iSerialNumber
= STR_SERIALNUMBER
,
255 .full
= &desc_device_bluetooth
,
259 static void usb_bt_fifo_reset(struct usb_hci_in_fifo_s
*fifo
)
263 fifo
->dsize
= DFIFO_LEN_MASK
+ 1;
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
;
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
);
281 buf
= fifo
->data
+ off
;
283 if (fifo
->dlen
> fifo
->dsize
) {
284 fprintf(stderr
, "%s: can't alloc %i bytes\n", __func__
, len
);
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
,
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
;
309 fifo
->start
&= CFIFO_LEN_MASK
;
315 if (fifo
->dstart
>= fifo
->dsize
) {
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),
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
);
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
;
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
;
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
;
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
);
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
;
376 ret
= usb_desc_handle_control(dev
, p
, request
, value
, index
, length
, data
);
379 case DeviceRequest
| USB_REQ_GET_CONFIGURATION
:
382 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
384 usb_bt_fifo_reset(&s
->evt
);
385 usb_bt_fifo_reset(&s
->acl
);
386 usb_bt_fifo_reset(&s
->sco
);
393 case InterfaceRequest
| USB_REQ_GET_STATUS
:
394 case EndpointRequest
| USB_REQ_GET_STATUS
:
397 p
->actual_length
= 2;
399 case InterfaceOutRequest
| USB_REQ_CLEAR_FEATURE
:
400 case EndpointOutRequest
| USB_REQ_CLEAR_FEATURE
:
402 case InterfaceOutRequest
| USB_REQ_SET_FEATURE
:
403 case EndpointOutRequest
| USB_REQ_SET_FEATURE
:
406 case ((USB_DIR_OUT
| USB_TYPE_CLASS
| USB_RECIP_DEVICE
) << 8):
408 usb_bt_fifo_out_enqueue(s
, &s
->outcmd
, s
->hci
->cmd_send
,
409 usb_bt_hci_cmd_complete
, p
);
413 p
->status
= USB_RET_STALL
;
418 static void usb_bt_handle_data(USBDevice
*dev
, USBPacket
*p
)
420 struct USBBtState
*s
= (struct USBBtState
*) dev
->opaque
;
429 if (s
->evt
.len
== 0) {
430 p
->status
= USB_RET_NAK
;
433 usb_bt_fifo_dequeue(&s
->evt
, p
);
437 if (s
->evt
.len
== 0) {
438 p
->status
= USB_RET_STALL
;
441 usb_bt_fifo_dequeue(&s
->acl
, p
);
445 if (s
->evt
.len
== 0) {
446 p
->status
= USB_RET_STALL
;
449 usb_bt_fifo_dequeue(&s
->sco
, p
);
460 usb_bt_fifo_out_enqueue(s
, &s
->outacl
, s
->hci
->acl_send
,
461 usb_bt_hci_acl_complete
, p
);
465 usb_bt_fifo_out_enqueue(s
, &s
->outsco
, s
->hci
->sco_send
,
466 usb_bt_hci_sco_complete
, p
);
476 p
->status
= USB_RET_STALL
;
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
);
517 s
->hci
= bt_new_hci(qemu_find_bt_vlan(0));
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
)
529 struct USBBtState
*s
;
531 const char *name
= TYPE_USB_BT
;
534 hci
= hci_init(cmdline
);
536 hci
= bt_new_hci(qemu_find_bt_vlan(0));
541 dev
= usb_create(bus
, name
);
547 static const VMStateDescription vmstate_usb_bt
= {
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
= {
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
)