Commit e6a6d5abc680ab7872c0faeb91326654379c12cf

Authored by balrog
1 parent ab2b6f50

Emulate a USB bluetooth dongle (or HCI Transport layer).


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5349 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
... ... @@ -81,7 +81,7 @@ OBJS+=scsi-generic.o
81 81 OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o
82 82 OBJS+=usb-serial.o usb-net.o
83 83 OBJS+=sd.o ssi-sd.o
84   -OBJS+=bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o
  84 +OBJS+=bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
85 85  
86 86 ifdef CONFIG_BRLAPI
87 87 OBJS+= baum.o
... ...
hw/usb-bt.c 0 → 100644
  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
  18 + * along with this program; if not, write to the Free Software
  19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 + * MA 02111-1307 USA
  21 + */
  22 +
  23 +#include "qemu-common.h"
  24 +#include "usb.h"
  25 +#include "net.h"
  26 +#include "bt.h"
  27 +
  28 +struct USBBtState {
  29 + USBDevice dev;
  30 + struct HCIInfo *hci;
  31 +
  32 + int altsetting;
  33 + int config;
  34 +
  35 +#define CFIFO_LEN_MASK 255
  36 +#define DFIFO_LEN_MASK 4095
  37 + struct usb_hci_in_fifo_s {
  38 + uint8_t data[(DFIFO_LEN_MASK + 1) * 2];
  39 + struct {
  40 + uint8_t *data;
  41 + int len;
  42 + } fifo[CFIFO_LEN_MASK + 1];
  43 + int dstart, dlen, dsize, start, len;
  44 + } evt, acl, sco;
  45 +
  46 + struct usb_hci_out_fifo_s {
  47 + uint8_t data[4096];
  48 + int len;
  49 + } outcmd, outacl, outsco;
  50 +};
  51 +
  52 +#define USB_EVT_EP 1
  53 +#define USB_ACL_EP 2
  54 +#define USB_SCO_EP 3
  55 +
  56 +static const uint8_t qemu_bt_dev_descriptor[] = {
  57 + 0x12, /* u8 bLength; */
  58 + USB_DT_DEVICE, /* u8 bDescriptorType; Device */
  59 + 0x10, 0x01, /* u16 bcdUSB; v1.10 */
  60 +
  61 + 0xe0, /* u8 bDeviceClass; Wireless */
  62 + 0x01, /* u8 bDeviceSubClass; Radio Frequency */
  63 + 0x01, /* u8 bDeviceProtocol; Bluetooth */
  64 + 0x40, /* u8 bMaxPacketSize0; 64 Bytes */
  65 +
  66 + 0x12, 0x0a, /* u16 idVendor; */
  67 + 0x01, 0x00, /* u16 idProduct; Bluetooth Dongle (HCI mode) */
  68 + 0x58, 0x19, /* u16 bcdDevice; (some devices have 0x48, 0x02) */
  69 +
  70 + 0x00, /* u8 iManufacturer; */
  71 + 0x00, /* u8 iProduct; */
  72 + 0x00, /* u8 iSerialNumber; */
  73 + 0x01, /* u8 bNumConfigurations; */
  74 +};
  75 +
  76 +static const uint8_t qemu_bt_config_descriptor[] = {
  77 + /* one configuration */
  78 + 0x09, /* u8 bLength; */
  79 + USB_DT_CONFIG, /* u8 bDescriptorType; */
  80 + 0xb1, 0x00, /* u16 wTotalLength; */
  81 + 0x02, /* u8 bNumInterfaces; (2) */
  82 + 0x01, /* u8 bConfigurationValue; */
  83 + 0x00, /* u8 iConfiguration; */
  84 + 0xc0, /* u8 bmAttributes;
  85 + Bit 7: must be set,
  86 + 6: Self-powered,
  87 + 5: Remote wakeup,
  88 + 4..0: resvd */
  89 + 0x00, /* u8 MaxPower; */
  90 +
  91 + /* USB 1.1:
  92 + * USB 2.0, single TT organization (mandatory):
  93 + * one interface, protocol 0
  94 + *
  95 + * USB 2.0, multiple TT organization (optional):
  96 + * two interfaces, protocols 1 (like single TT)
  97 + * and 2 (multiple TT mode) ... config is
  98 + * sometimes settable
  99 + * NOT IMPLEMENTED
  100 + */
  101 +
  102 + /* interface one */
  103 + 0x09, /* u8 if_bLength; */
  104 + USB_DT_INTERFACE, /* u8 if_bDescriptorType; */
  105 + 0x00, /* u8 if_bInterfaceNumber; */
  106 + 0x00, /* u8 if_bAlternateSetting; */
  107 + 0x03, /* u8 if_bNumEndpoints; */
  108 + 0xe0, /* u8 if_bInterfaceClass; Wireless */
  109 + 0x01, /* u8 if_bInterfaceSubClass; Radio Frequency */
  110 + 0x01, /* u8 if_bInterfaceProtocol; Bluetooth */
  111 + 0x00, /* u8 if_iInterface; */
  112 +
  113 + /* endpoint one */
  114 + 0x07, /* u8 ep_bLength; */
  115 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  116 + USB_DIR_IN | USB_EVT_EP, /* u8 ep_bEndpointAddress; */
  117 + 0x03, /* u8 ep_bmAttributes; Interrupt */
  118 + 0x10, 0x00, /* u16 ep_wMaxPacketSize; */
  119 + 0x02, /* u8 ep_bInterval; */
  120 +
  121 + /* endpoint two */
  122 + 0x07, /* u8 ep_bLength; */
  123 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  124 + USB_DIR_OUT | USB_ACL_EP, /* u8 ep_bEndpointAddress; */
  125 + 0x02, /* u8 ep_bmAttributes; Bulk */
  126 + 0x40, 0x00, /* u16 ep_wMaxPacketSize; */
  127 + 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
  128 +
  129 + /* endpoint three */
  130 + 0x07, /* u8 ep_bLength; */
  131 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  132 + USB_DIR_IN | USB_ACL_EP, /* u8 ep_bEndpointAddress; */
  133 + 0x02, /* u8 ep_bmAttributes; Bulk */
  134 + 0x40, 0x00, /* u16 ep_wMaxPacketSize; */
  135 + 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
  136 +
  137 + /* interface two setting one */
  138 + 0x09, /* u8 if_bLength; */
  139 + USB_DT_INTERFACE, /* u8 if_bDescriptorType; */
  140 + 0x01, /* u8 if_bInterfaceNumber; */
  141 + 0x00, /* u8 if_bAlternateSetting; */
  142 + 0x02, /* u8 if_bNumEndpoints; */
  143 + 0xe0, /* u8 if_bInterfaceClass; Wireless */
  144 + 0x01, /* u8 if_bInterfaceSubClass; Radio Frequency */
  145 + 0x01, /* u8 if_bInterfaceProtocol; Bluetooth */
  146 + 0x00, /* u8 if_iInterface; */
  147 +
  148 + /* endpoint one */
  149 + 0x07, /* u8 ep_bLength; */
  150 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  151 + USB_DIR_OUT | USB_SCO_EP, /* u8 ep_bEndpointAddress; */
  152 + 0x01, /* u8 ep_bmAttributes; Isochronous */
  153 + 0x00, 0x00, /* u16 ep_wMaxPacketSize; */
  154 + 0x01, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
  155 +
  156 + /* endpoint two */
  157 + 0x07, /* u8 ep_bLength; */
  158 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  159 + USB_DIR_IN | USB_SCO_EP, /* u8 ep_bEndpointAddress; */
  160 + 0x01, /* u8 ep_bmAttributes; Isochronous */
  161 + 0x00, 0x00, /* u16 ep_wMaxPacketSize; */
  162 + 0x01, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
  163 +
  164 + /* interface two setting two */
  165 + 0x09, /* u8 if_bLength; */
  166 + USB_DT_INTERFACE, /* u8 if_bDescriptorType; */
  167 + 0x01, /* u8 if_bInterfaceNumber; */
  168 + 0x01, /* u8 if_bAlternateSetting; */
  169 + 0x02, /* u8 if_bNumEndpoints; */
  170 + 0xe0, /* u8 if_bInterfaceClass; Wireless */
  171 + 0x01, /* u8 if_bInterfaceSubClass; Radio Frequency */
  172 + 0x01, /* u8 if_bInterfaceProtocol; Bluetooth */
  173 + 0x00, /* u8 if_iInterface; */
  174 +
  175 + /* endpoint one */
  176 + 0x07, /* u8 ep_bLength; */
  177 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  178 + USB_DIR_OUT | USB_SCO_EP, /* u8 ep_bEndpointAddress; */
  179 + 0x01, /* u8 ep_bmAttributes; Isochronous */
  180 + 0x09, 0x00, /* u16 ep_wMaxPacketSize; */
  181 + 0x01, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
  182 +
  183 + /* endpoint two */
  184 + 0x07, /* u8 ep_bLength; */
  185 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  186 + USB_DIR_IN | USB_SCO_EP, /* u8 ep_bEndpointAddress; */
  187 + 0x01, /* u8 ep_bmAttributes; Isochronous */
  188 + 0x09, 0x00, /* u16 ep_wMaxPacketSize; */
  189 + 0x01, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
  190 +
  191 + /* interface two setting three */
  192 + 0x09, /* u8 if_bLength; */
  193 + USB_DT_INTERFACE, /* u8 if_bDescriptorType; */
  194 + 0x01, /* u8 if_bInterfaceNumber; */
  195 + 0x02, /* u8 if_bAlternateSetting; */
  196 + 0x02, /* u8 if_bNumEndpoints; */
  197 + 0xe0, /* u8 if_bInterfaceClass; Wireless */
  198 + 0x01, /* u8 if_bInterfaceSubClass; Radio Frequency */
  199 + 0x01, /* u8 if_bInterfaceProtocol; Bluetooth */
  200 + 0x00, /* u8 if_iInterface; */
  201 +
  202 + /* endpoint one */
  203 + 0x07, /* u8 ep_bLength; */
  204 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  205 + USB_DIR_OUT | USB_SCO_EP, /* u8 ep_bEndpointAddress; */
  206 + 0x01, /* u8 ep_bmAttributes; Isochronous */
  207 + 0x11, 0x00, /* u16 ep_wMaxPacketSize; */
  208 + 0x01, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
  209 +
  210 + /* endpoint two */
  211 + 0x07, /* u8 ep_bLength; */
  212 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  213 + USB_DIR_IN | USB_SCO_EP, /* u8 ep_bEndpointAddress; */
  214 + 0x01, /* u8 ep_bmAttributes; Isochronous */
  215 + 0x11, 0x00, /* u16 ep_wMaxPacketSize; */
  216 + 0x01, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
  217 +
  218 + /* interface two setting four */
  219 + 0x09, /* u8 if_bLength; */
  220 + USB_DT_INTERFACE, /* u8 if_bDescriptorType; */
  221 + 0x01, /* u8 if_bInterfaceNumber; */
  222 + 0x03, /* u8 if_bAlternateSetting; */
  223 + 0x02, /* u8 if_bNumEndpoints; */
  224 + 0xe0, /* u8 if_bInterfaceClass; Wireless */
  225 + 0x01, /* u8 if_bInterfaceSubClass; Radio Frequency */
  226 + 0x01, /* u8 if_bInterfaceProtocol; Bluetooth */
  227 + 0x00, /* u8 if_iInterface; */
  228 +
  229 + /* endpoint one */
  230 + 0x07, /* u8 ep_bLength; */
  231 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  232 + USB_DIR_OUT | USB_SCO_EP, /* u8 ep_bEndpointAddress; */
  233 + 0x01, /* u8 ep_bmAttributes; Isochronous */
  234 + 0x19, 0x00, /* u16 ep_wMaxPacketSize; */
  235 + 0x01, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
  236 +
  237 + /* endpoint two */
  238 + 0x07, /* u8 ep_bLength; */
  239 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  240 + USB_DIR_IN | USB_SCO_EP, /* u8 ep_bEndpointAddress; */
  241 + 0x01, /* u8 ep_bmAttributes; Isochronous */
  242 + 0x19, 0x00, /* u16 ep_wMaxPacketSize; */
  243 + 0x01, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
  244 +
  245 + /* interface two setting five */
  246 + 0x09, /* u8 if_bLength; */
  247 + USB_DT_INTERFACE, /* u8 if_bDescriptorType; */
  248 + 0x01, /* u8 if_bInterfaceNumber; */
  249 + 0x04, /* u8 if_bAlternateSetting; */
  250 + 0x02, /* u8 if_bNumEndpoints; */
  251 + 0xe0, /* u8 if_bInterfaceClass; Wireless */
  252 + 0x01, /* u8 if_bInterfaceSubClass; Radio Frequency */
  253 + 0x01, /* u8 if_bInterfaceProtocol; Bluetooth */
  254 + 0x00, /* u8 if_iInterface; */
  255 +
  256 + /* endpoint one */
  257 + 0x07, /* u8 ep_bLength; */
  258 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  259 + USB_DIR_OUT | USB_SCO_EP, /* u8 ep_bEndpointAddress; */
  260 + 0x01, /* u8 ep_bmAttributes; Isochronous */
  261 + 0x21, 0x00, /* u16 ep_wMaxPacketSize; */
  262 + 0x01, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
  263 +
  264 + /* endpoint two */
  265 + 0x07, /* u8 ep_bLength; */
  266 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  267 + USB_DIR_IN | USB_SCO_EP, /* u8 ep_bEndpointAddress; */
  268 + 0x01, /* u8 ep_bmAttributes; Isochronous */
  269 + 0x21, 0x00, /* u16 ep_wMaxPacketSize; */
  270 + 0x01, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
  271 +
  272 + /* interface two setting six */
  273 + 0x09, /* u8 if_bLength; */
  274 + USB_DT_INTERFACE, /* u8 if_bDescriptorType; */
  275 + 0x01, /* u8 if_bInterfaceNumber; */
  276 + 0x05, /* u8 if_bAlternateSetting; */
  277 + 0x02, /* u8 if_bNumEndpoints; */
  278 + 0xe0, /* u8 if_bInterfaceClass; Wireless */
  279 + 0x01, /* u8 if_bInterfaceSubClass; Radio Frequency */
  280 + 0x01, /* u8 if_bInterfaceProtocol; Bluetooth */
  281 + 0x00, /* u8 if_iInterface; */
  282 +
  283 + /* endpoint one */
  284 + 0x07, /* u8 ep_bLength; */
  285 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  286 + USB_DIR_OUT | USB_SCO_EP, /* u8 ep_bEndpointAddress; */
  287 + 0x01, /* u8 ep_bmAttributes; Isochronous */
  288 + 0x31, 0x00, /* u16 ep_wMaxPacketSize; */
  289 + 0x01, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
  290 +
  291 + /* endpoint two */
  292 + 0x07, /* u8 ep_bLength; */
  293 + USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; */
  294 + USB_DIR_IN | USB_SCO_EP, /* u8 ep_bEndpointAddress; */
  295 + 0x01, /* u8 ep_bmAttributes; Isochronous */
  296 + 0x31, 0x00, /* u16 ep_wMaxPacketSize; */
  297 + 0x01, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
  298 +
  299 + /* If implemented, the DFU interface descriptor goes here with no
  300 + * endpoints or alternative settings. */
  301 +};
  302 +
  303 +static void usb_bt_fifo_reset(struct usb_hci_in_fifo_s *fifo)
  304 +{
  305 + fifo->dstart = 0;
  306 + fifo->dlen = 0;
  307 + fifo->dsize = DFIFO_LEN_MASK + 1;
  308 + fifo->start = 0;
  309 + fifo->len = 0;
  310 +}
  311 +
  312 +static void usb_bt_fifo_enqueue(struct usb_hci_in_fifo_s *fifo,
  313 + const uint8_t *data, int len)
  314 +{
  315 + int off = fifo->dstart + fifo->dlen;
  316 + uint8_t *buf;
  317 +
  318 + fifo->dlen += len;
  319 + if (off <= DFIFO_LEN_MASK) {
  320 + if (off + len > DFIFO_LEN_MASK + 1 &&
  321 + (fifo->dsize = off + len) > (DFIFO_LEN_MASK + 1) * 2) {
  322 + fprintf(stderr, "%s: can't alloc %i bytes\n", __FUNCTION__, len);
  323 + exit(-1);
  324 + }
  325 + buf = fifo->data + off;
  326 + } else {
  327 + if (fifo->dlen > fifo->dsize) {
  328 + fprintf(stderr, "%s: can't alloc %i bytes\n", __FUNCTION__, len);
  329 + exit(-1);
  330 + }
  331 + buf = fifo->data + off - fifo->dsize;
  332 + }
  333 +
  334 + off = (fifo->start + fifo->len ++) & CFIFO_LEN_MASK;
  335 + fifo->fifo[off].data = memcpy(buf, data, len);
  336 + fifo->fifo[off].len = len;
  337 +}
  338 +
  339 +static inline int usb_bt_fifo_dequeue(struct usb_hci_in_fifo_s *fifo,
  340 + USBPacket *p)
  341 +{
  342 + int len;
  343 +
  344 + if (likely(!fifo->len))
  345 + return USB_RET_STALL;
  346 +
  347 + len = MIN(p->len, fifo->fifo[fifo->start].len);
  348 + memcpy(p->data, fifo->fifo[fifo->start].data, len);
  349 + if (len == p->len) {
  350 + fifo->fifo[fifo->start].len -= len;
  351 + fifo->fifo[fifo->start].data += len;
  352 + } else {
  353 + fifo->start ++;
  354 + fifo->start &= CFIFO_LEN_MASK;
  355 + fifo->len --;
  356 + }
  357 +
  358 + fifo->dstart += len;
  359 + fifo->dlen -= len;
  360 + if (fifo->dstart >= fifo->dsize) {
  361 + fifo->dstart = 0;
  362 + fifo->dsize = DFIFO_LEN_MASK + 1;
  363 + }
  364 +
  365 + return len;
  366 +}
  367 +
  368 +static void inline usb_bt_fifo_out_enqueue(struct USBBtState *s,
  369 + struct usb_hci_out_fifo_s *fifo,
  370 + void (*send)(struct HCIInfo *, const uint8_t *, int),
  371 + int (*complete)(const uint8_t *, int),
  372 + const uint8_t *data, int len)
  373 +{
  374 + if (fifo->len) {
  375 + memcpy(fifo->data + fifo->len, data, len);
  376 + fifo->len += len;
  377 + if (complete(fifo->data, fifo->len)) {
  378 + send(s->hci, fifo->data, fifo->len);
  379 + fifo->len = 0;
  380 + }
  381 + } else if (complete(data, len))
  382 + send(s->hci, data, len);
  383 + else {
  384 + memcpy(fifo->data, data, len);
  385 + fifo->len = len;
  386 + }
  387 +
  388 + /* TODO: do we need to loop? */
  389 +}
  390 +
  391 +static int usb_bt_hci_cmd_complete(const uint8_t *data, int len)
  392 +{
  393 + len -= HCI_COMMAND_HDR_SIZE;
  394 + return len >= 0 &&
  395 + len >= ((struct hci_command_hdr *) data)->plen;
  396 +}
  397 +
  398 +static int usb_bt_hci_acl_complete(const uint8_t *data, int len)
  399 +{
  400 + len -= HCI_ACL_HDR_SIZE;
  401 + return len >= 0 &&
  402 + len >= le16_to_cpu(((struct hci_acl_hdr *) data)->dlen);
  403 +}
  404 +
  405 +static int usb_bt_hci_sco_complete(const uint8_t *data, int len)
  406 +{
  407 + len -= HCI_SCO_HDR_SIZE;
  408 + return len >= 0 &&
  409 + len >= ((struct hci_sco_hdr *) data)->dlen;
  410 +}
  411 +
  412 +static void usb_bt_handle_reset(USBDevice *dev)
  413 +{
  414 + struct USBBtState *s = (struct USBBtState *) dev->opaque;
  415 +
  416 + usb_bt_fifo_reset(&s->evt);
  417 + usb_bt_fifo_reset(&s->acl);
  418 + usb_bt_fifo_reset(&s->sco);
  419 + s->outcmd.len = 0;
  420 + s->outacl.len = 0;
  421 + s->outsco.len = 0;
  422 + s->altsetting = 0;
  423 +}
  424 +
  425 +static int usb_bt_handle_control(USBDevice *dev, int request, int value,
  426 + int index, int length, uint8_t *data)
  427 +{
  428 + struct USBBtState *s = (struct USBBtState *) dev->opaque;
  429 + int ret = 0;
  430 +
  431 + switch (request) {
  432 + case DeviceRequest | USB_REQ_GET_STATUS:
  433 + case InterfaceRequest | USB_REQ_GET_STATUS:
  434 + case EndpointRequest | USB_REQ_GET_STATUS:
  435 + data[0] = (1 << USB_DEVICE_SELF_POWERED) |
  436 + (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
  437 + data[1] = 0x00;
  438 + ret = 2;
  439 + break;
  440 + case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
  441 + case InterfaceOutRequest | USB_REQ_CLEAR_FEATURE:
  442 + case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
  443 + if (value == USB_DEVICE_REMOTE_WAKEUP) {
  444 + dev->remote_wakeup = 0;
  445 + } else {
  446 + goto fail;
  447 + }
  448 + ret = 0;
  449 + break;
  450 + case DeviceOutRequest | USB_REQ_SET_FEATURE:
  451 + case InterfaceOutRequest | USB_REQ_SET_FEATURE:
  452 + case EndpointOutRequest | USB_REQ_SET_FEATURE:
  453 + if (value == USB_DEVICE_REMOTE_WAKEUP) {
  454 + dev->remote_wakeup = 1;
  455 + } else {
  456 + goto fail;
  457 + }
  458 + ret = 0;
  459 + break;
  460 + case DeviceOutRequest | USB_REQ_SET_ADDRESS:
  461 + dev->addr = value;
  462 + ret = 0;
  463 + break;
  464 + case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
  465 + switch (value >> 8) {
  466 + case USB_DT_DEVICE:
  467 + ret = sizeof(qemu_bt_dev_descriptor);
  468 + memcpy(data, qemu_bt_dev_descriptor, ret);
  469 + break;
  470 + case USB_DT_CONFIG:
  471 + ret = sizeof(qemu_bt_config_descriptor);
  472 + memcpy(data, qemu_bt_config_descriptor, ret);
  473 + break;
  474 + case USB_DT_STRING:
  475 + switch(value & 0xff) {
  476 + case 0:
  477 + /* language ids */
  478 + data[0] = 4;
  479 + data[1] = 3;
  480 + data[2] = 0x09;
  481 + data[3] = 0x04;
  482 + ret = 4;
  483 + break;
  484 + default:
  485 + goto fail;
  486 + }
  487 + break;
  488 + default:
  489 + goto fail;
  490 + }
  491 + break;
  492 + case DeviceRequest | USB_REQ_GET_CONFIGURATION:
  493 + data[0] = qemu_bt_config_descriptor[0x5];
  494 + ret = 1;
  495 + s->config = 0;
  496 + break;
  497 + case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
  498 + ret = 0;
  499 + if (value != qemu_bt_config_descriptor[0x5] && value != 0) {
  500 + printf("%s: Wrong SET_CONFIGURATION request (%i)\n",
  501 + __FUNCTION__, value);
  502 + goto fail;
  503 + }
  504 + s->config = 1;
  505 + usb_bt_fifo_reset(&s->evt);
  506 + usb_bt_fifo_reset(&s->acl);
  507 + usb_bt_fifo_reset(&s->sco);
  508 + break;
  509 + case InterfaceRequest | USB_REQ_GET_INTERFACE:
  510 + if (value != 0 || (index & ~1) || length != 1)
  511 + goto fail;
  512 + if (index == 1)
  513 + data[0] = s->altsetting;
  514 + else
  515 + data[0] = 0;
  516 + ret = 1;
  517 + break;
  518 + case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
  519 + if ((index & ~1) || length != 0 ||
  520 + (index == 1 && (value < 0 || value > 4)) ||
  521 + (index == 0 && value != 0)) {
  522 + printf("%s: Wrong SET_INTERFACE request (%i, %i)\n",
  523 + __FUNCTION__, index, value);
  524 + goto fail;
  525 + }
  526 + s->altsetting = value;
  527 + ret = 0;
  528 + break;
  529 + case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE) << 8):
  530 + if (s->config)
  531 + usb_bt_fifo_out_enqueue(s, &s->outcmd, s->hci->cmd_send,
  532 + usb_bt_hci_cmd_complete, data, length);
  533 + break;
  534 + default:
  535 + fail:
  536 + ret = USB_RET_STALL;
  537 + break;
  538 + }
  539 + return ret;
  540 +}
  541 +
  542 +static int usb_bt_handle_data(USBDevice *dev, USBPacket *p)
  543 +{
  544 + struct USBBtState *s = (struct USBBtState *) dev->opaque;
  545 + int ret = 0;
  546 +
  547 + if (!s->config)
  548 + goto fail;
  549 +
  550 + switch (p->pid) {
  551 + case USB_TOKEN_IN:
  552 + switch (p->devep & 0xf) {
  553 + case USB_EVT_EP:
  554 + ret = usb_bt_fifo_dequeue(&s->evt, p);
  555 + break;
  556 +
  557 + case USB_ACL_EP:
  558 + ret = usb_bt_fifo_dequeue(&s->acl, p);
  559 + break;
  560 +
  561 + case USB_SCO_EP:
  562 + ret = usb_bt_fifo_dequeue(&s->sco, p);
  563 + break;
  564 +
  565 + default:
  566 + goto fail;
  567 + }
  568 + break;
  569 +
  570 + case USB_TOKEN_OUT:
  571 + switch (p->devep & 0xf) {
  572 + case USB_ACL_EP:
  573 + usb_bt_fifo_out_enqueue(s, &s->outacl, s->hci->acl_send,
  574 + usb_bt_hci_acl_complete, p->data, p->len);
  575 + break;
  576 +
  577 + case USB_SCO_EP:
  578 + usb_bt_fifo_out_enqueue(s, &s->outsco, s->hci->sco_send,
  579 + usb_bt_hci_sco_complete, p->data, p->len);
  580 + break;
  581 +
  582 + default:
  583 + goto fail;
  584 + }
  585 + break;
  586 +
  587 + default:
  588 + fail:
  589 + ret = USB_RET_STALL;
  590 + break;
  591 + }
  592 +
  593 + return ret;
  594 +}
  595 +
  596 +static void usb_bt_out_hci_packet_event(void *opaque,
  597 + const uint8_t *data, int len)
  598 +{
  599 + struct USBBtState *s = (struct USBBtState *) opaque;
  600 +
  601 + usb_bt_fifo_enqueue(&s->evt, data, len);
  602 +}
  603 +
  604 +static void usb_bt_out_hci_packet_acl(void *opaque,
  605 + const uint8_t *data, int len)
  606 +{
  607 + struct USBBtState *s = (struct USBBtState *) opaque;
  608 +
  609 + usb_bt_fifo_enqueue(&s->acl, data, len);
  610 +}
  611 +
  612 +static void usb_bt_handle_destroy(USBDevice *dev)
  613 +{
  614 + struct USBBtState *s = (struct USBBtState *) dev->opaque;
  615 +
  616 + s->hci->opaque = 0;
  617 + s->hci->evt_recv = 0;
  618 + s->hci->acl_recv = 0;
  619 + qemu_free(s);
  620 +}
  621 +
  622 +USBDevice *usb_bt_init(HCIInfo *hci)
  623 +{
  624 + struct USBBtState *s;
  625 +
  626 + s = qemu_mallocz(sizeof(struct USBBtState));
  627 + if (!s)
  628 + return NULL;
  629 + s->dev.opaque = s;
  630 + s->dev.speed = USB_SPEED_HIGH;
  631 + s->dev.handle_packet = usb_generic_handle_packet;
  632 + pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU BT dongle");
  633 +
  634 + s->dev.handle_reset = usb_bt_handle_reset;
  635 + s->dev.handle_control = usb_bt_handle_control;
  636 + s->dev.handle_data = usb_bt_handle_data;
  637 + s->dev.handle_destroy = usb_bt_handle_destroy;
  638 +
  639 + s->hci = hci;
  640 + s->hci->opaque = s;
  641 + s->hci->evt_recv = usb_bt_out_hci_packet_event;
  642 + s->hci->acl_recv = usb_bt_out_hci_packet_acl;
  643 +
  644 + usb_bt_handle_reset(&s->dev);
  645 +
  646 + return &s->dev;
  647 +}
... ...
hw/usb.h
... ... @@ -255,6 +255,9 @@ USBDevice *usb_msd_init(const char *filename);
255 255 /* usb-net.c */
256 256 USBDevice *usb_net_init(NICInfo *nd);
257 257  
  258 +/* usb-bt.c */
  259 +USBDevice *usb_bt_init(HCIInfo *hci);
  260 +
258 261 /* usb-wacom.c */
259 262 USBDevice *usb_wacom_init(void);
260 263  
... ...