qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] hw/bt: drop bluetooth keyboard emulation.


From: Paolo Bonzini
Subject: Re: [Qemu-devel] [PATCH] hw/bt: drop bluetooth keyboard emulation.
Date: Fri, 9 Nov 2018 22:11:31 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.0

On 09/11/2018 15:14, Gerd Hoffmann wrote:
> Broken (segfaultson first keypress) and appearently unused.
> 
> Signed-off-by: Gerd Hoffmann <address@hidden>

No objection, but can we make some effort of, at least, putting the
stack backtrace in the commit log?

Paolo


> ---
>  include/hw/bt.h     |   3 -
>  hw/bt/hid.c         | 554 
> ----------------------------------------------------
>  vl.c                |  34 +---
>  hw/bt/Makefile.objs |   3 +-
>  qemu-options.hx     |   9 -
>  5 files changed, 2 insertions(+), 601 deletions(-)
>  delete mode 100644 hw/bt/hid.c
> 
> diff --git a/include/hw/bt.h b/include/hw/bt.h
> index b5e11d4d43..73fb1911f6 100644
> --- a/include/hw/bt.h
> +++ b/include/hw/bt.h
> @@ -173,9 +173,6 @@ enum bt_l2cap_psm_predef {
>  /* bt-sdp.c */
>  void bt_l2cap_sdp_init(struct bt_l2cap_device_s *dev);
>  
> -/* bt-hid.c */
> -struct bt_device_s *bt_keyboard_init(struct bt_scatternet_s *net);
> -
>  /* Link Management Protocol layer defines */
>  
>  #define LLID_ACLU_CONT               0x1
> diff --git a/hw/bt/hid.c b/hw/bt/hid.c
> deleted file mode 100644
> index 056291f9b5..0000000000
> --- a/hw/bt/hid.c
> +++ /dev/null
> @@ -1,554 +0,0 @@
> -/*
> - * QEMU Bluetooth HID Profile wrapper for USB HID.
> - *
> - * Copyright (C) 2007-2008 OpenMoko, Inc.
> - * Written by Andrzej Zaborowski <address@hidden>
> - *
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public License as
> - * published by the Free Software Foundation; either version 2 or
> - * (at your option) version 3 of the License.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License along
> - * with this program; if not, if not, see <http://www.gnu.org/licenses/>.
> - */
> -
> -#include "qemu/osdep.h"
> -#include "qemu-common.h"
> -#include "qemu/timer.h"
> -#include "ui/console.h"
> -#include "hw/input/hid.h"
> -#include "hw/bt.h"
> -
> -enum hid_transaction_req {
> -    BT_HANDSHAKE                     = 0x0,
> -    BT_HID_CONTROL                   = 0x1,
> -    BT_GET_REPORT                    = 0x4,
> -    BT_SET_REPORT                    = 0x5,
> -    BT_GET_PROTOCOL                  = 0x6,
> -    BT_SET_PROTOCOL                  = 0x7,
> -    BT_GET_IDLE                              = 0x8,
> -    BT_SET_IDLE                              = 0x9,
> -    BT_DATA                          = 0xa,
> -    BT_DATC                          = 0xb,
> -};
> -
> -enum hid_transaction_handshake {
> -    BT_HS_SUCCESSFUL                 = 0x0,
> -    BT_HS_NOT_READY                  = 0x1,
> -    BT_HS_ERR_INVALID_REPORT_ID              = 0x2,
> -    BT_HS_ERR_UNSUPPORTED_REQUEST    = 0x3,
> -    BT_HS_ERR_INVALID_PARAMETER              = 0x4,
> -    BT_HS_ERR_UNKNOWN                        = 0xe,
> -    BT_HS_ERR_FATAL                  = 0xf,
> -};
> -
> -enum hid_transaction_control {
> -    BT_HC_NOP                                = 0x0,
> -    BT_HC_HARD_RESET                 = 0x1,
> -    BT_HC_SOFT_RESET                 = 0x2,
> -    BT_HC_SUSPEND                    = 0x3,
> -    BT_HC_EXIT_SUSPEND                       = 0x4,
> -    BT_HC_VIRTUAL_CABLE_UNPLUG               = 0x5,
> -};
> -
> -enum hid_protocol {
> -    BT_HID_PROTO_BOOT                        = 0,
> -    BT_HID_PROTO_REPORT                      = 1,
> -};
> -
> -enum hid_boot_reportid {
> -    BT_HID_BOOT_INVALID                      = 0,
> -    BT_HID_BOOT_KEYBOARD,
> -    BT_HID_BOOT_MOUSE,
> -};
> -
> -enum hid_data_pkt {
> -    BT_DATA_OTHER                    = 0,
> -    BT_DATA_INPUT,
> -    BT_DATA_OUTPUT,
> -    BT_DATA_FEATURE,
> -};
> -
> -#define BT_HID_MTU                   48
> -
> -/* HID interface requests */
> -#define GET_REPORT                   0xa101
> -#define GET_IDLE                     0xa102
> -#define GET_PROTOCOL                 0xa103
> -#define SET_REPORT                   0x2109
> -#define SET_IDLE                     0x210a
> -#define SET_PROTOCOL                 0x210b
> -
> -struct bt_hid_device_s {
> -    struct bt_l2cap_device_s btdev;
> -    struct bt_l2cap_conn_params_s *control;
> -    struct bt_l2cap_conn_params_s *interrupt;
> -    HIDState hid;
> -
> -    int proto;
> -    int connected;
> -    int data_type;
> -    int intr_state;
> -    struct {
> -        int len;
> -        uint8_t buffer[1024];
> -    } dataother, datain, dataout, feature, intrdataout;
> -    enum {
> -        bt_state_ready,
> -        bt_state_transaction,
> -        bt_state_suspend,
> -    } state;
> -};
> -
> -static void bt_hid_reset(struct bt_hid_device_s *s)
> -{
> -    struct bt_scatternet_s *net = s->btdev.device.net;
> -
> -    /* Go as far as... */
> -    bt_l2cap_device_done(&s->btdev);
> -    bt_l2cap_device_init(&s->btdev, net);
> -
> -    hid_reset(&s->hid);
> -    s->proto = BT_HID_PROTO_REPORT;
> -    s->state = bt_state_ready;
> -    s->dataother.len = 0;
> -    s->datain.len = 0;
> -    s->dataout.len = 0;
> -    s->feature.len = 0;
> -    s->intrdataout.len = 0;
> -    s->intr_state = 0;
> -}
> -
> -static int bt_hid_out(struct bt_hid_device_s *s)
> -{
> -    if (s->data_type == BT_DATA_OUTPUT) {
> -        /* nothing */
> -        ;
> -    }
> -
> -    if (s->data_type == BT_DATA_FEATURE) {
> -        /* XXX:
> -         * does this send a USB_REQ_CLEAR_FEATURE/USB_REQ_SET_FEATURE
> -         * or a SET_REPORT? */
> -        ;
> -    }
> -
> -    return -1;
> -}
> -
> -static int bt_hid_in(struct bt_hid_device_s *s)
> -{
> -    s->datain.len = hid_keyboard_poll(&s->hid, s->datain.buffer,
> -                                      sizeof(s->datain.buffer));
> -    return s->datain.len;
> -}
> -
> -static void bt_hid_send_handshake(struct bt_hid_device_s *s, int result)
> -{
> -    *s->control->sdu_out(s->control, 1) =
> -            (BT_HANDSHAKE << 4) | result;
> -    s->control->sdu_submit(s->control);
> -}
> -
> -static void bt_hid_send_control(struct bt_hid_device_s *s, int operation)
> -{
> -    *s->control->sdu_out(s->control, 1) =
> -            (BT_HID_CONTROL << 4) | operation;
> -    s->control->sdu_submit(s->control);
> -}
> -
> -static void bt_hid_disconnect(struct bt_hid_device_s *s)
> -{
> -    /* Disconnect s->control and s->interrupt */
> -}
> -
> -static void bt_hid_send_data(struct bt_l2cap_conn_params_s *ch, int type,
> -                const uint8_t *data, int len)
> -{
> -    uint8_t *pkt, hdr = (BT_DATA << 4) | type;
> -    int plen;
> -
> -    do {
> -        plen = MIN(len, ch->remote_mtu - 1);
> -        pkt = ch->sdu_out(ch, plen + 1);
> -
> -        pkt[0] = hdr;
> -        if (plen)
> -            memcpy(pkt + 1, data, plen);
> -        ch->sdu_submit(ch);
> -
> -        len -= plen;
> -        data += plen;
> -        hdr = (BT_DATC << 4) | type;
> -    } while (plen == ch->remote_mtu - 1);
> -}
> -
> -static void bt_hid_control_transaction(struct bt_hid_device_s *s,
> -                const uint8_t *data, int len)
> -{
> -    uint8_t type, parameter;
> -    int rlen, ret = -1;
> -    if (len < 1)
> -        return;
> -
> -    type = data[0] >> 4;
> -    parameter = data[0] & 0xf;
> -
> -    switch (type) {
> -    case BT_HANDSHAKE:
> -    case BT_DATA:
> -        switch (parameter) {
> -        default:
> -            /* These are not expected to be sent this direction.  */
> -            ret = BT_HS_ERR_INVALID_PARAMETER;
> -        }
> -        break;
> -
> -    case BT_HID_CONTROL:
> -        if (len != 1 || (parameter != BT_HC_VIRTUAL_CABLE_UNPLUG &&
> -                                s->state == bt_state_transaction)) {
> -            ret = BT_HS_ERR_INVALID_PARAMETER;
> -            break;
> -        }
> -        switch (parameter) {
> -        case BT_HC_NOP:
> -            break;
> -        case BT_HC_HARD_RESET:
> -        case BT_HC_SOFT_RESET:
> -            bt_hid_reset(s);
> -            break;
> -        case BT_HC_SUSPEND:
> -            if (s->state == bt_state_ready)
> -                s->state = bt_state_suspend;
> -            else
> -                ret = BT_HS_ERR_INVALID_PARAMETER;
> -            break;
> -        case BT_HC_EXIT_SUSPEND:
> -            if (s->state == bt_state_suspend)
> -                s->state = bt_state_ready;
> -            else
> -                ret = BT_HS_ERR_INVALID_PARAMETER;
> -            break;
> -        case BT_HC_VIRTUAL_CABLE_UNPLUG:
> -            bt_hid_disconnect(s);
> -            break;
> -        default:
> -            ret = BT_HS_ERR_INVALID_PARAMETER;
> -        }
> -        break;
> -
> -    case BT_GET_REPORT:
> -        /* No ReportIDs declared.  */
> -        if (((parameter & 8) && len != 3) ||
> -                        (!(parameter & 8) && len != 1) ||
> -                        s->state != bt_state_ready) {
> -            ret = BT_HS_ERR_INVALID_PARAMETER;
> -            break;
> -        }
> -        if (parameter & 8)
> -            rlen = data[2] | (data[3] << 8);
> -        else
> -            rlen = INT_MAX;
> -        switch (parameter & 3) {
> -        case BT_DATA_OTHER:
> -            ret = BT_HS_ERR_INVALID_PARAMETER;
> -            break;
> -        case BT_DATA_INPUT:
> -            /* Here we can as well poll s->usbdev */
> -            bt_hid_send_data(s->control, BT_DATA_INPUT,
> -                            s->datain.buffer, MIN(rlen, s->datain.len));
> -            break;
> -        case BT_DATA_OUTPUT:
> -            bt_hid_send_data(s->control, BT_DATA_OUTPUT,
> -                            s->dataout.buffer, MIN(rlen, s->dataout.len));
> -            break;
> -        case BT_DATA_FEATURE:
> -            bt_hid_send_data(s->control, BT_DATA_FEATURE,
> -                            s->feature.buffer, MIN(rlen, s->feature.len));
> -            break;
> -        }
> -        break;
> -
> -    case BT_SET_REPORT:
> -        if (len < 2 || len > BT_HID_MTU || s->state != bt_state_ready ||
> -                        (parameter & 3) == BT_DATA_OTHER ||
> -                        (parameter & 3) == BT_DATA_INPUT) {
> -            ret = BT_HS_ERR_INVALID_PARAMETER;
> -            break;
> -        }
> -        s->data_type = parameter & 3;
> -        if (s->data_type == BT_DATA_OUTPUT) {
> -            s->dataout.len = len - 1;
> -            memcpy(s->dataout.buffer, data + 1, s->dataout.len);
> -        } else {
> -            s->feature.len = len - 1;
> -            memcpy(s->feature.buffer, data + 1, s->feature.len);
> -        }
> -        if (len == BT_HID_MTU)
> -            s->state = bt_state_transaction;
> -        else
> -            bt_hid_out(s);
> -        break;
> -
> -    case BT_GET_PROTOCOL:
> -        if (len != 1 || s->state == bt_state_transaction) {
> -            ret = BT_HS_ERR_INVALID_PARAMETER;
> -            break;
> -        }
> -        *s->control->sdu_out(s->control, 1) = s->proto;
> -        s->control->sdu_submit(s->control);
> -        break;
> -
> -    case BT_SET_PROTOCOL:
> -        if (len != 1 || s->state == bt_state_transaction ||
> -                        (parameter != BT_HID_PROTO_BOOT &&
> -                         parameter != BT_HID_PROTO_REPORT)) {
> -            ret = BT_HS_ERR_INVALID_PARAMETER;
> -            break;
> -        }
> -        s->proto = parameter;
> -        s->hid.protocol = parameter;
> -        ret = BT_HS_SUCCESSFUL;
> -        break;
> -
> -    case BT_GET_IDLE:
> -        if (len != 1 || s->state == bt_state_transaction) {
> -            ret = BT_HS_ERR_INVALID_PARAMETER;
> -            break;
> -        }
> -        *s->control->sdu_out(s->control, 1) = s->hid.idle;
> -        s->control->sdu_submit(s->control);
> -        break;
> -
> -    case BT_SET_IDLE:
> -        if (len != 2 || s->state == bt_state_transaction) {
> -            ret = BT_HS_ERR_INVALID_PARAMETER;
> -            break;
> -        }
> -
> -        s->hid.idle = data[1];
> -        /* XXX: Does this generate a handshake? */
> -        break;
> -
> -    case BT_DATC:
> -        if (len > BT_HID_MTU || s->state != bt_state_transaction) {
> -            ret = BT_HS_ERR_INVALID_PARAMETER;
> -            break;
> -        }
> -        if (s->data_type == BT_DATA_OUTPUT) {
> -            memcpy(s->dataout.buffer + s->dataout.len, data + 1, len - 1);
> -            s->dataout.len += len - 1;
> -        } else {
> -            memcpy(s->feature.buffer + s->feature.len, data + 1, len - 1);
> -            s->feature.len += len - 1;
> -        }
> -        if (len < BT_HID_MTU) {
> -            bt_hid_out(s);
> -            s->state = bt_state_ready;
> -        }
> -        break;
> -
> -    default:
> -        ret = BT_HS_ERR_UNSUPPORTED_REQUEST;
> -    }
> -
> -    if (ret != -1)
> -        bt_hid_send_handshake(s, ret);
> -}
> -
> -static void bt_hid_control_sdu(void *opaque, const uint8_t *data, int len)
> -{
> -    struct bt_hid_device_s *hid = opaque;
> -
> -    bt_hid_control_transaction(hid, data, len);
> -}
> -
> -static void bt_hid_datain(HIDState *hs)
> -{
> -    struct bt_hid_device_s *hid =
> -        container_of(hs, struct bt_hid_device_s, hid);
> -
> -    /* If suspended, wake-up and send a wake-up event first.  We might
> -     * want to also inspect the input report and ignore event like
> -     * mouse movements until a button event occurs.  */
> -    if (hid->state == bt_state_suspend) {
> -        hid->state = bt_state_ready;
> -    }
> -
> -    if (bt_hid_in(hid) > 0)
> -        /* TODO: when in boot-mode precede any Input reports with the 
> ReportID
> -         * byte, here and in GetReport/SetReport on the Control channel.  */
> -        bt_hid_send_data(hid->interrupt, BT_DATA_INPUT,
> -                        hid->datain.buffer, hid->datain.len);
> -}
> -
> -static void bt_hid_interrupt_sdu(void *opaque, const uint8_t *data, int len)
> -{
> -    struct bt_hid_device_s *hid = opaque;
> -
> -    if (len > BT_HID_MTU || len < 1)
> -        goto bad;
> -    if ((data[0] & 3) != BT_DATA_OUTPUT)
> -        goto bad;
> -    if ((data[0] >> 4) == BT_DATA) {
> -        if (hid->intr_state)
> -            goto bad;
> -
> -        hid->data_type = BT_DATA_OUTPUT;
> -        hid->intrdataout.len = 0;
> -    } else if ((data[0] >> 4) == BT_DATC) {
> -        if (!hid->intr_state)
> -            goto bad;
> -    } else
> -        goto bad;
> -
> -    memcpy(hid->intrdataout.buffer + hid->intrdataout.len, data + 1, len - 
> 1);
> -    hid->intrdataout.len += len - 1;
> -    hid->intr_state = (len == BT_HID_MTU);
> -    if (!hid->intr_state) {
> -        memcpy(hid->dataout.buffer, hid->intrdataout.buffer,
> -                        hid->dataout.len = hid->intrdataout.len);
> -        bt_hid_out(hid);
> -    }
> -
> -    return;
> -bad:
> -    error_report("%s: bad transaction on Interrupt channel.",
> -                    __func__);
> -}
> -
> -/* "Virtual cable" plug/unplug event.  */
> -static void bt_hid_connected_update(struct bt_hid_device_s *hid)
> -{
> -    int prev = hid->connected;
> -
> -    hid->connected = hid->control && hid->interrupt;
> -
> -    /* Stop page-/inquiry-scanning when a host is connected.  */
> -    hid->btdev.device.page_scan = !hid->connected;
> -    hid->btdev.device.inquiry_scan = !hid->connected;
> -
> -    if (hid->connected && !prev) {
> -        hid_reset(&hid->hid);
> -        hid->proto = BT_HID_PROTO_REPORT;
> -    }
> -
> -    /* Should set HIDVirtualCable in SDP (possibly need to check that SDP
> -     * isn't destroyed yet, in case we're being called from handle_destroy) 
> */
> -}
> -
> -static void bt_hid_close_control(void *opaque)
> -{
> -    struct bt_hid_device_s *hid = opaque;
> -
> -    hid->control = NULL;
> -    bt_hid_connected_update(hid);
> -}
> -
> -static void bt_hid_close_interrupt(void *opaque)
> -{
> -    struct bt_hid_device_s *hid = opaque;
> -
> -    hid->interrupt = NULL;
> -    bt_hid_connected_update(hid);
> -}
> -
> -static int bt_hid_new_control_ch(struct bt_l2cap_device_s *dev,
> -                struct bt_l2cap_conn_params_s *params)
> -{
> -    struct bt_hid_device_s *hid = (struct bt_hid_device_s *) dev;
> -
> -    if (hid->control)
> -        return 1;
> -
> -    hid->control = params;
> -    hid->control->opaque = hid;
> -    hid->control->close = bt_hid_close_control;
> -    hid->control->sdu_in = bt_hid_control_sdu;
> -
> -    bt_hid_connected_update(hid);
> -
> -    return 0;
> -}
> -
> -static int bt_hid_new_interrupt_ch(struct bt_l2cap_device_s *dev,
> -                struct bt_l2cap_conn_params_s *params)
> -{
> -    struct bt_hid_device_s *hid = (struct bt_hid_device_s *) dev;
> -
> -    if (hid->interrupt)
> -        return 1;
> -
> -    hid->interrupt = params;
> -    hid->interrupt->opaque = hid;
> -    hid->interrupt->close = bt_hid_close_interrupt;
> -    hid->interrupt->sdu_in = bt_hid_interrupt_sdu;
> -
> -    bt_hid_connected_update(hid);
> -
> -    return 0;
> -}
> -
> -static void bt_hid_destroy(struct bt_device_s *dev)
> -{
> -    struct bt_hid_device_s *hid = (struct bt_hid_device_s *) dev;
> -
> -    if (hid->connected)
> -        bt_hid_send_control(hid, BT_HC_VIRTUAL_CABLE_UNPLUG);
> -    bt_l2cap_device_done(&hid->btdev);
> -
> -    hid_free(&hid->hid);
> -
> -    g_free(hid);
> -}
> -
> -enum peripheral_minor_class {
> -    class_other              = 0 << 4,
> -    class_keyboard   = 1 << 4,
> -    class_pointing   = 2 << 4,
> -    class_combo              = 3 << 4,
> -};
> -
> -static struct bt_device_s *bt_hid_init(struct bt_scatternet_s *net,
> -                                       enum peripheral_minor_class minor)
> -{
> -    struct bt_hid_device_s *s = g_malloc0(sizeof(*s));
> -    uint32_t class =
> -            /* Format type */
> -            (0 << 0) |
> -            /* Device class */
> -            (minor << 2) |
> -            (5 << 8) |  /* "Peripheral" */
> -            /* Service classes */
> -            (1 << 13) | /* Limited discoverable mode */
> -            (1 << 19);  /* Capturing device (?) */
> -
> -    bt_l2cap_device_init(&s->btdev, net);
> -    bt_l2cap_sdp_init(&s->btdev);
> -    bt_l2cap_psm_register(&s->btdev, BT_PSM_HID_CTRL,
> -                    BT_HID_MTU, bt_hid_new_control_ch);
> -    bt_l2cap_psm_register(&s->btdev, BT_PSM_HID_INTR,
> -                    BT_HID_MTU, bt_hid_new_interrupt_ch);
> -
> -    hid_init(&s->hid, HID_KEYBOARD, bt_hid_datain);
> -    s->btdev.device.lmp_name = "BT Keyboard";
> -
> -    s->btdev.device.handle_destroy = bt_hid_destroy;
> -
> -    s->btdev.device.class[0] = (class >>  0) & 0xff;
> -    s->btdev.device.class[1] = (class >>  8) & 0xff;
> -    s->btdev.device.class[2] = (class >> 16) & 0xff;
> -
> -    return &s->btdev.device;
> -}
> -
> -struct bt_device_s *bt_keyboard_init(struct bt_scatternet_s *net)
> -{
> -    return bt_hid_init(net, class_keyboard);
> -}
> diff --git a/vl.c b/vl.c
> index 55bab005b6..2a12fc7f3e 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -988,37 +988,6 @@ static void bt_vhci_add(int vlan_id)
>      bt_vhci_init(bt_new_hci(vlan));
>  }
>  
> -static struct bt_device_s *bt_device_add(const char *opt)
> -{
> -    struct bt_scatternet_s *vlan;
> -    int vlan_id = 0;
> -    char *endp = strstr(opt, ",vlan=");
> -    int len = (endp ? endp - opt : strlen(opt)) + 1;
> -    char devname[10];
> -
> -    pstrcpy(devname, MIN(sizeof(devname), len), opt);
> -
> -    if (endp) {
> -        vlan_id = strtol(endp + 6, &endp, 0);
> -        if (*endp) {
> -            error_report("unrecognised bluetooth vlan Id");
> -            return 0;
> -        }
> -    }
> -
> -    vlan = qemu_find_bt_vlan(vlan_id);
> -
> -    if (!vlan->slave)
> -        warn_report("adding a slave device to an empty scatternet %i",
> -                    vlan_id);
> -
> -    if (!strcmp(devname, "keyboard"))
> -        return bt_keyboard_init(vlan);
> -
> -    error_report("unsupported bluetooth device '%s'", devname);
> -    return 0;
> -}
> -
>  static int bt_parse(const char *opt)
>  {
>      const char *endp, *p;
> @@ -1051,8 +1020,7 @@ static int bt_parse(const char *opt)
>              bt_vhci_add(vlan);
>              return 0;
>          }
> -    } else if (strstart(opt, "device:", &endp))
> -        return !bt_device_add(endp);
> +    }
>  
>      error_report("bad bluetooth parameter '%s'", opt);
>      return 1;
> diff --git a/hw/bt/Makefile.objs b/hw/bt/Makefile.objs
> index 867a7d2e8a..a33983b522 100644
> --- a/hw/bt/Makefile.objs
> +++ b/hw/bt/Makefile.objs
> @@ -1,3 +1,2 @@
> -common-obj-y += core.o l2cap.o sdp.o hci.o hid.o
> +common-obj-y += core.o l2cap.o sdp.o hci.o
>  common-obj-y += hci-csr.o
> -
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 38c7a978c1..48885cdca8 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -2804,15 +2804,6 @@ be used as following:
>  qemu-system-i386 [...OPTIONS...] -bt hci,vlan=5 -bt vhci,vlan=5
>  @end example
>  
> address@hidden -bt device:@var{dev}[,address@hidden
> -Emulate a bluetooth device @var{dev} and place it in network @var{n}
> -(default @code{0}).  QEMU can only emulate one type of bluetooth devices
> -currently:
> -
> address@hidden @option
> address@hidden keyboard
> -Virtual wireless keyboard implementing the HIDP bluetooth profile.
> address@hidden table
>  ETEXI
>  
>  STEXI
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]