symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/usb-bt.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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     if (!hci)
       
   627         return NULL;
       
   628     s = qemu_mallocz(sizeof(struct USBBtState));
       
   629     if (!s)
       
   630         return NULL;
       
   631     s->dev.opaque = s;
       
   632     s->dev.speed = USB_SPEED_HIGH;
       
   633     s->dev.handle_packet = usb_generic_handle_packet;
       
   634     pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU BT dongle");
       
   635 
       
   636     s->dev.handle_reset = usb_bt_handle_reset;
       
   637     s->dev.handle_control = usb_bt_handle_control;
       
   638     s->dev.handle_data = usb_bt_handle_data;
       
   639     s->dev.handle_destroy = usb_bt_handle_destroy;
       
   640 
       
   641     s->hci = hci;
       
   642     s->hci->opaque = s;
       
   643     s->hci->evt_recv = usb_bt_out_hci_packet_event;
       
   644     s->hci->acl_recv = usb_bt_out_hci_packet_acl;
       
   645 
       
   646     usb_bt_handle_reset(&s->dev);
       
   647 
       
   648     return &s->dev;
       
   649 }