aboutsummaryrefslogtreecommitdiff
path: root/hw/bt
diff options
context:
space:
mode:
Diffstat (limited to 'hw/bt')
-rw-r--r--hw/bt/hci-csr.c64
1 files changed, 48 insertions, 16 deletions
diff --git a/hw/bt/hci-csr.c b/hw/bt/hci-csr.c
index fbb3109cc1..3c193848fc 100644
--- a/hw/bt/hci-csr.c
+++ b/hw/bt/hci-csr.c
@@ -26,13 +26,14 @@
#include "hw/irq.h"
#include "sysemu/bt.h"
#include "hw/bt.h"
+#include "qapi/error.h"
struct csrhci_s {
+ Chardev parent;
int enable;
qemu_irq *pins;
int pin_state;
int modem_state;
- CharDriverState chr;
#define FIFO_LEN 4096
int out_start;
int out_len;
@@ -54,6 +55,9 @@ struct csrhci_s {
struct HCIInfo *hci;
};
+#define TYPE_CHARDEV_HCI "chardev-hci"
+#define HCI_CHARDEV(obj) OBJECT_CHECK(struct csrhci_s, (obj), TYPE_CHARDEV_HCI)
+
/* H4+ packet types */
enum {
H4_CMD_PKT = 1,
@@ -78,7 +82,8 @@ enum {
static inline void csrhci_fifo_wake(struct csrhci_s *s)
{
- CharBackend *be = s->chr.be;
+ Chardev *chr = (Chardev *)s;
+ CharBackend *be = chr->be;
if (!s->enable || !s->out_len)
return;
@@ -311,10 +316,10 @@ static void csrhci_ready_for_next_inpkt(struct csrhci_s *s)
s->in_hdr = INT_MAX;
}
-static int csrhci_write(struct CharDriverState *chr,
+static int csrhci_write(struct Chardev *chr,
const uint8_t *buf, int len)
{
- struct csrhci_s *s = (struct csrhci_s *) chr->opaque;
+ struct csrhci_s *s = (struct csrhci_s *)chr;
int total = 0;
if (!s->enable)
@@ -384,10 +389,10 @@ static void csrhci_out_hci_packet_acl(void *opaque,
csrhci_fifo_wake(s);
}
-static int csrhci_ioctl(struct CharDriverState *chr, int cmd, void *arg)
+static int csrhci_ioctl(struct Chardev *chr, int cmd, void *arg)
{
QEMUSerialSetParams *ssp;
- struct csrhci_s *s = (struct csrhci_s *) chr->opaque;
+ struct csrhci_s *s = (struct csrhci_s *) chr;
int prev_state = s->modem_state;
switch (cmd) {
@@ -453,21 +458,19 @@ static void csrhci_pins(void *opaque, int line, int level)
}
}
-qemu_irq *csrhci_pins_get(CharDriverState *chr)
+qemu_irq *csrhci_pins_get(Chardev *chr)
{
- struct csrhci_s *s = (struct csrhci_s *) chr->opaque;
+ struct csrhci_s *s = (struct csrhci_s *) chr;
return s->pins;
}
-CharDriverState *uart_hci_init(void)
+static void csrhci_open(Chardev *chr,
+ ChardevBackend *backend,
+ bool *be_opened,
+ Error **errp)
{
- struct csrhci_s *s = (struct csrhci_s *)
- g_malloc0(sizeof(struct csrhci_s));
-
- s->chr.opaque = s;
- s->chr.chr_write = csrhci_write;
- s->chr.chr_ioctl = csrhci_ioctl;
+ struct csrhci_s *s = HCI_CHARDEV(chr);
s->hci = qemu_next_hci();
s->hci->opaque = s;
@@ -477,6 +480,35 @@ CharDriverState *uart_hci_init(void)
s->out_tm = timer_new_ns(QEMU_CLOCK_VIRTUAL, csrhci_out_tick, s);
s->pins = qemu_allocate_irqs(csrhci_pins, s, __csrhci_pins);
csrhci_reset(s);
+ *be_opened = false;
+}
+
+static void char_hci_class_init(ObjectClass *oc, void *data)
+{
+ ChardevClass *cc = CHARDEV_CLASS(oc);
+
+ cc->internal = true;
+ cc->open = csrhci_open;
+ cc->chr_write = csrhci_write;
+ cc->chr_ioctl = csrhci_ioctl;
+}
- return &s->chr;
+static const TypeInfo char_hci_type_info = {
+ .name = TYPE_CHARDEV_HCI,
+ .parent = TYPE_CHARDEV,
+ .instance_size = sizeof(struct csrhci_s),
+ .class_init = char_hci_class_init,
+};
+
+Chardev *uart_hci_init(void)
+{
+ return qemu_chardev_new(NULL, TYPE_CHARDEV_HCI,
+ NULL, &error_abort);
}
+
+static void register_types(void)
+{
+ type_register_static(&char_hci_type_info);
+}
+
+type_init(register_types);