diff options
author | Anthony Liguori <anthony@codemonkey.ws> | 2013-09-11 14:46:21 -0500 |
---|---|---|
committer | Anthony Liguori <anthony@codemonkey.ws> | 2013-09-11 14:46:21 -0500 |
commit | a640f07c0d03bfa3031af1fc0a32b0d779917d17 (patch) | |
tree | aef05faa1cb19136263cd28fcd061ff71ae68144 /hw | |
parent | f69f0bcac951f3c3089246695874b84ea8967936 (diff) | |
parent | adbecc89731cf3e0ae656d50ea9fa58c589c4bdc (diff) |
Merge remote-tracking branch 'kraxel/usb.89' into staging
# By Gerd Hoffmann (2) and Miroslav Rezanina (2)
# Via Gerd Hoffmann
* kraxel/usb.89:
ehci: save device pointer in EHCIState
Remove dev-bluetooth.c dependency from vl.c
Preparation for usb-bt-dongle conditional build
usb: sanity check setup_index+setup_len in post_load
Message-id: 1378806073-25197-1-git-send-email-kraxel@redhat.com
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/bt/core.c | 23 | ||||
-rw-r--r-- | hw/bt/hci.c | 48 | ||||
-rw-r--r-- | hw/usb/Makefile.objs | 3 | ||||
-rw-r--r-- | hw/usb/bus.c | 4 | ||||
-rw-r--r-- | hw/usb/dev-bluetooth.c | 10 | ||||
-rw-r--r-- | hw/usb/hcd-ehci.c | 7 | ||||
-rw-r--r-- | hw/usb/hcd-ehci.h | 1 |
7 files changed, 88 insertions, 8 deletions
diff --git a/hw/bt/core.c b/hw/bt/core.c index 49012e028c..0ffc948898 100644 --- a/hw/bt/core.c +++ b/hw/bt/core.c @@ -119,3 +119,26 @@ void bt_device_done(struct bt_device_s *dev) *p = dev->next; } + +static struct bt_vlan_s { + struct bt_scatternet_s net; + int id; + struct bt_vlan_s *next; +} *first_bt_vlan; + +/* find or alloc a new bluetooth "VLAN" */ +struct bt_scatternet_s *qemu_find_bt_vlan(int id) +{ + struct bt_vlan_s **pvlan, *vlan; + for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) { + if (vlan->id == id) + return &vlan->net; + } + vlan = g_malloc0(sizeof(struct bt_vlan_s)); + vlan->id = id; + pvlan = &first_bt_vlan; + while (*pvlan != NULL) + pvlan = &(*pvlan)->next; + *pvlan = vlan; + return &vlan->net; +} diff --git a/hw/bt/hci.c b/hw/bt/hci.c index d1c0604a9b..7ea3dc6b70 100644 --- a/hw/bt/hci.c +++ b/hw/bt/hci.c @@ -429,6 +429,24 @@ static const uint8_t bt_event_reserved_mask[8] = { 0xff, 0x9f, 0xfb, 0xff, 0x07, 0x18, 0x00, 0x00, }; + +static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len) +{ +} + +static int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr) +{ + return -ENOTSUP; +} + +struct HCIInfo null_hci = { + .cmd_send = null_hci_send, + .sco_send = null_hci_send, + .acl_send = null_hci_send, + .bdaddr_set = null_hci_addr_set, +}; + + static inline uint8_t *bt_hci_event_start(struct bt_hci_s *hci, int evt, int len) { @@ -2176,6 +2194,36 @@ struct HCIInfo *bt_new_hci(struct bt_scatternet_s *net) return &s->info; } +struct HCIInfo *hci_init(const char *str) +{ + char *endp; + struct bt_scatternet_s *vlan = 0; + + if (!strcmp(str, "null")) + /* null */ + return &null_hci; + else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == ':')) + /* host[:hciN] */ + return bt_host_hci(str[4] ? str + 5 : "hci0"); + else if (!strncmp(str, "hci", 3)) { + /* hci[,vlan=n] */ + if (str[3]) { + if (!strncmp(str + 3, ",vlan=", 6)) { + vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0)); + if (*endp) + vlan = 0; + } + } else + vlan = qemu_find_bt_vlan(0); + if (vlan) + return bt_new_hci(vlan); + } + + fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str); + + return 0; +} + static void bt_hci_done(struct HCIInfo *info) { struct bt_hci_s *hci = hci_from_info(info); diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs index f9695e7d8a..a3eac3e5c1 100644 --- a/hw/usb/Makefile.objs +++ b/hw/usb/Makefile.objs @@ -18,9 +18,6 @@ common-obj-$(CONFIG_USB_STORAGE_UAS) += dev-uas.o common-obj-$(CONFIG_USB_AUDIO) += dev-audio.o common-obj-$(CONFIG_USB_SERIAL) += dev-serial.o common-obj-$(CONFIG_USB_NETWORK) += dev-network.o - -# FIXME: make configurable too -CONFIG_USB_BLUETOOTH := y common-obj-$(CONFIG_USB_BLUETOOTH) += dev-bluetooth.o ifeq ($(CONFIG_USB_SMARTCARD),y) diff --git a/hw/usb/bus.c b/hw/usb/bus.c index 82ca6a13e8..72d5b92225 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -47,6 +47,10 @@ static int usb_device_post_load(void *opaque, int version_id) } else { dev->attached = 1; } + if (dev->setup_index >= sizeof(dev->data_buf) || + dev->setup_len >= sizeof(dev->data_buf)) { + return -EINVAL; + } return 0; } diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c index f2fc2a8034..7f292b1ae6 100644 --- a/hw/usb/dev-bluetooth.c +++ b/hw/usb/dev-bluetooth.c @@ -511,10 +511,17 @@ static int usb_bt_initfn(USBDevice *dev) return 0; } -USBDevice *usb_bt_init(USBBus *bus, HCIInfo *hci) +static USBDevice *usb_bt_init(USBBus *bus, const char *cmdline) { USBDevice *dev; struct USBBtState *s; + HCIInfo *hci; + + if (*cmdline) { + hci = hci_init(cmdline); + } else { + hci = bt_new_hci(qemu_find_bt_vlan(0)); + } if (!hci) return NULL; @@ -566,6 +573,7 @@ static const TypeInfo bt_info = { static void usb_bt_register_types(void) { type_register_static(&bt_info); + usb_legacy_register("usb-bt-dongle", "bt", usb_bt_init); } type_init(usb_bt_register_types) diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 137e200202..22bdbf4a7d 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -1241,13 +1241,11 @@ static int ehci_init_transfer(EHCIPacket *p) { uint32_t cpage, offset, bytes, plen; dma_addr_t page; - USBBus *bus = &p->queue->ehci->bus; - BusState *qbus = BUS(bus); cpage = get_field(p->qtd.token, QTD_TOKEN_CPAGE); bytes = get_field(p->qtd.token, QTD_TOKEN_TBYTES); offset = p->qtd.bufptr[0] & ~QTD_BUFPTR_MASK; - qemu_sglist_init(&p->sgl, qbus->parent, 5, p->queue->ehci->as); + qemu_sglist_init(&p->sgl, p->queue->ehci->device, 5, p->queue->ehci->as); while (bytes > 0) { if (cpage > 4) { @@ -1486,7 +1484,7 @@ static int ehci_process_itd(EHCIState *ehci, return -1; } - qemu_sglist_init(&ehci->isgl, DEVICE(ehci), 2, ehci->as); + qemu_sglist_init(&ehci->isgl, ehci->device, 2, ehci->as); if (off + len > 4096) { /* transfer crosses page border */ uint32_t len2 = off + len - 4096; @@ -2529,6 +2527,7 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp) s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ehci_frame_timer, s); s->async_bh = qemu_bh_new(ehci_frame_timer, s); + s->device = dev; qemu_register_reset(ehci_reset, s); qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s); diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h index 15a28e8b31..065c9fa741 100644 --- a/hw/usb/hcd-ehci.h +++ b/hw/usb/hcd-ehci.h @@ -255,6 +255,7 @@ typedef QTAILQ_HEAD(EHCIQueueHead, EHCIQueue) EHCIQueueHead; struct EHCIState { USBBus bus; + DeviceState *device; qemu_irq irq; MemoryRegion mem; AddressSpace *as; |