summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authortron <tron@NetBSD.org>2006-07-26 10:30:59 +0000
committertron <tron@NetBSD.org>2006-07-26 10:30:59 +0000
commit4241fec1bf5dddf07d1681ccdcbe408f389dbbe2 (patch)
tree8bfa4c84be7a357bbb1f40913c22e26eec582650 /sys/dev
parentb504a17332ef6e90bb11c6a3aedd721959b653fb (diff)
Bluetooth fixes by Iain Hibbert:
Change the way in which bluetooth devices attach to system. The new way is for devices to attach directly to a btdevN device via its own control file /dev/btdevN. - bthub(4) is replaced by btdev(4). - /dev/bthubctl is replaced by /dev/btdevN. - configuration now uses proplib(3) property lists. - btcontrol(8) updated to use new API, and now uses private - XML config file /var/db/btdev.xml.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/DEVNAMES4
-rw-r--r--sys/dev/bluetooth/btdev.c283
-rw-r--r--sys/dev/bluetooth/btdev.h61
-rw-r--r--sys/dev/bluetooth/files.bluetooth15
4 files changed, 295 insertions, 68 deletions
diff --git a/sys/dev/DEVNAMES b/sys/dev/DEVNAMES
index 1c983ef3279..d129c04c63c 100644
--- a/sys/dev/DEVNAMES
+++ b/sys/dev/DEVNAMES
@@ -1,4 +1,4 @@
-# $NetBSD: DEVNAMES,v 1.204 2006/07/14 17:44:07 gdamore Exp $
+# $NetBSD: DEVNAMES,v 1.205 2006/07/26 10:31:00 tron Exp $
#
# This file contains all used device names and defined attributes in
# alphabetical order. New devices added to the system somewhere should first
@@ -171,8 +171,8 @@ brgphy MI
bt3c MI
bt_dac sparc Attribute
bt_dac sparc64 Attribute
+btdev MI
bthidev MI
-bthub MI
bthset MI
btkbd MI
btl arc
diff --git a/sys/dev/bluetooth/btdev.c b/sys/dev/bluetooth/btdev.c
new file mode 100644
index 00000000000..91fe80f6647
--- /dev/null
+++ b/sys/dev/bluetooth/btdev.c
@@ -0,0 +1,283 @@
+/* $NetBSD: btdev.c,v 1.1 2006/07/26 10:38:51 tron Exp $ */
+
+/*-
+ * Copyright (c) 2006 Itronix Inc.
+ * All rights reserved.
+ *
+ * Written by Iain Hibbert for Itronix Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of Itronix Inc. may not be used to endorse
+ * or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: btdev.c,v 1.1 2006/07/26 10:38:51 tron Exp $");
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/fcntl.h>
+#include <sys/kernel.h>
+#include <sys/queue.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+
+#include <prop/proplib.h>
+
+#include <netbt/bluetooth.h>
+
+#include <dev/bluetooth/btdev.h>
+
+/*****************************************************************************
+ *
+ * Bluetooth device
+ *
+ * Each device corresponds to a character device /dev/btdevN
+ */
+
+#define BTDEV_DEFAULT_COUNT 4 /* default number of btdevs */
+
+struct btdev_softc {
+ struct device sc_dev;
+ int sc_busy;
+ struct device *sc_child;
+};
+
+/* pseudo-device initialization */
+void btdevattach(int);
+
+/* autoconf(9) glue */
+static int btdev_match(struct device *, struct cfdata *, void *);
+static void btdev_attach(struct device *, struct device *, void *);
+
+CFATTACH_DECL(btdev, sizeof(struct btdev_softc),
+ btdev_match, btdev_attach, NULL, NULL);
+
+/* device control */
+dev_type_open(btdevopen);
+dev_type_close(btdevclose);
+dev_type_ioctl(btdevioctl);
+
+const struct cdevsw btdev_cdevsw = {
+ btdevopen, btdevclose, noread, nowrite, btdevioctl,
+ nostop, notty, nopoll, nommap, nokqfilter,
+};
+
+/* print attach args */
+static int btdev_print(void *, const char *);
+
+/*****************************************************************************
+ *
+ * btdev init routine called at system boot. attach proper devices
+ * for each requested pseudo so we can pass config args later.
+ */
+
+extern struct cfdriver btdev_cd;
+
+static struct cfdata btdev_cfdata = {
+ .cf_name = "btdev",
+ .cf_atname = "btdev",
+ .cf_unit = DVUNIT_ANY,
+ .cf_fstate = FSTATE_STAR,
+};
+
+void
+btdevattach(int num)
+{
+ int err, i;
+
+ if (num < 1)
+ num = BTDEV_DEFAULT_COUNT;
+
+ err = config_cfattach_attach(btdev_cd.cd_name, &btdev_ca);
+ if (err) {
+ aprint_error("%s: unable to register cfattach (%d)\n",
+ btdev_cd.cd_name, err);
+
+ config_cfdriver_detach(&btdev_cd);
+ return;
+ }
+
+ for (i = 0 ; i < num ; i++) {
+ if (config_attach_pseudo(&btdev_cfdata) == NULL) {
+ aprint_error("%s%d: attach failed (%d)\n",
+ btdev_cd.cd_name, i, err);
+
+ return;
+ }
+ }
+}
+
+/*****************************************************************************
+ *
+ * btdev autoconf(9) routines
+ *
+ */
+
+static int
+btdev_match(struct device *self, struct cfdata *cfdata, void *arg)
+{
+
+ return 1;
+}
+
+static void
+btdev_attach(struct device *parent, struct device *self, void *aux)
+{
+}
+
+
+/*****************************************************************************
+ *
+ * btdev access functions to control device
+ */
+
+int
+btdevopen(dev_t devno, int flag, int mode, struct lwp *l)
+{
+ struct btdev_softc *sc;
+
+ sc = device_lookup(&btdev_cd, minor(devno));
+ if (sc == NULL)
+ return ENXIO;
+
+ if (sc->sc_busy)
+ return EBUSY;
+
+ sc->sc_busy = 1;
+ return 0;
+}
+
+int
+btdevclose(dev_t devno, int flag, int mode, struct lwp *l)
+{
+ struct btdev_softc *sc;
+
+ sc = device_lookup(&btdev_cd, minor(devno));
+ sc->sc_busy = 0;
+ return 0;
+}
+
+int
+btdevioctl(dev_t devno, unsigned long cmd, caddr_t data, int flag, struct lwp *l)
+{
+ struct btdev_softc *sc;
+ prop_dictionary_t dict;
+ prop_object_t obj;
+ const struct plistref *plist;
+ int err;
+
+ plist = (const struct plistref *)data;
+ sc = device_lookup(&btdev_cd, minor(devno));
+ dict = NULL;
+ err = 0;
+
+ switch (cmd) {
+ case BTDEV_ATTACH: /* attach BTDEV */
+ if (sc->sc_child) {
+ err = EBUSY;
+ break;
+ }
+
+ /*
+ * load dictionary and validate common items
+ */
+ err = prop_dictionary_copyin_ioctl(plist, flag, &dict);
+ if (err)
+ break;
+
+ obj = prop_dictionary_get(dict, "local-bdaddr");
+ if (obj == NULL
+ || prop_object_type(obj) != PROP_TYPE_DATA
+ || prop_data_size(obj) != sizeof(bdaddr_t)) {
+ err = EINVAL;
+ break;
+ }
+
+ obj = prop_dictionary_get(dict, "remote-bdaddr");
+ if (obj == NULL
+ || prop_object_type(obj) != PROP_TYPE_DATA
+ || prop_data_size(obj) != sizeof(bdaddr_t)
+ || bdaddr_any(prop_data_data_nocopy(obj))) {
+ err = EINVAL;
+ break;
+ }
+
+ obj = prop_dictionary_get(dict, "device-type");
+ if (obj == NULL
+ || prop_object_type(obj) != PROP_TYPE_STRING) {
+ err = EINVAL;
+ break;
+ }
+
+ sc->sc_child = config_found(&sc->sc_dev, dict, btdev_print);
+ if (sc->sc_child == NULL)
+ err = ENXIO;
+
+ break;
+
+ case BTDEV_DETACH: /* detach BTDEV */
+ if (sc->sc_child == NULL) {
+ err = ENXIO;
+ break;
+ }
+
+ config_detach(sc->sc_child, DETACH_FORCE);
+ sc->sc_child = NULL;
+ break;
+
+ default:
+ err = EPASSTHROUGH;
+ break;
+ }
+
+ if (dict != NULL)
+ prop_object_release(dict);
+
+ return err;
+}
+
+static int
+btdev_print(void *aux, const char *pnp)
+{
+ prop_dictionary_t dict = aux;
+ prop_object_t obj;
+ const bdaddr_t *raddr;
+
+ if (pnp != NULL) {
+ obj = prop_dictionary_get(dict, "device-type");
+ aprint_normal("%s: type '%s',", pnp, prop_string_cstring_nocopy(obj));
+ }
+
+ obj = prop_dictionary_get(dict, "remote-bdaddr");
+ raddr = prop_data_data_nocopy(obj);
+
+ aprint_verbose(" bdaddr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
+ raddr->b[5], raddr->b[4], raddr->b[3],
+ raddr->b[2], raddr->b[1], raddr->b[0]);
+
+ return UNCONF;
+}
diff --git a/sys/dev/bluetooth/btdev.h b/sys/dev/bluetooth/btdev.h
index e8aa4ff8421..35714174e81 100644
--- a/sys/dev/bluetooth/btdev.h
+++ b/sys/dev/bluetooth/btdev.h
@@ -1,4 +1,4 @@
-/* $NetBSD: btdev.h,v 1.1 2006/06/19 15:44:45 gdamore Exp $ */
+/* $NetBSD: btdev.h,v 1.2 2006/07/26 10:31:00 tron Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -34,63 +34,8 @@
#ifndef _DEV_BLUETOOTH_BTDEV_H_
#define _DEV_BLUETOOTH_BTDEV_H_
-/*
- * Bluetooth Device attach arguments (from userland)
- */
-struct btdev_attach_args {
- bdaddr_t bd_laddr; /* local address */
- bdaddr_t bd_raddr; /* remote address */
- uint16_t bd_type; /* device type */
-
- union {
- struct { /* HID arguments */
- uint16_t hid_flags;/* HID flags */
- uint16_t hid_ctl; /* control PSM */
- uint16_t hid_int; /* interrupt PSM */
- void *hid_desc; /* HID descriptor */
- uint16_t hid_dlen; /* descriptor length */
- } bdd_hid;
-
- struct { /* HSET arguments */
- uint8_t hset_channel; /* RFCOMM channel */
- uint8_t hset_mtu; /* SCO mtu */
- } bdd_hset;
-
- struct { /* Advance Audio arguments */
- } bdd_a2dp;
- } bdd;
-};
-
-#define bd_hid bdd.bdd_hid
-#define bd_hset bdd.bdd_hset
-#define bd_a2dp bdd.bdd_a2dp
-
-/* btdev type */
-#define BTDEV_HID 0x0001
-#define BTDEV_HSET 0x0002
-
-/* bthid flags */
-#define BTHID_INITIATE (1 << 0) /* normally initiate */
-#define BTHID_CONNECT (1 << 1) /* initiate connect */
-
/* btdev attach/detach ioctl's */
-#define BTDEV_ATTACH _IOW('b', 14, struct btdev_attach_args)
-#define BTDEV_DETACH _IOW('b', 15, bdaddr_t)
-
-#ifdef _KERNEL
-
-/*
- * Bluetooth device header
- */
-struct btdev {
- struct device sc_dev; /* system device */
- bdaddr_t sc_addr; /* device bdaddr */
-
- LIST_ENTRY(btdev) sc_next;
-};
-
-#define btdev_name(d) (((struct btdev *)(d))->sc_dev.dv_xname)
-
-#endif /* _KERNEL */
+#define BTDEV_ATTACH _IOW('b', 14, struct plistref)
+#define BTDEV_DETACH _IOW('b', 15, struct plistref)
#endif /* _DEV_BLUETOOTH_BTDEV_H_ */
diff --git a/sys/dev/bluetooth/files.bluetooth b/sys/dev/bluetooth/files.bluetooth
index 054af96032f..2504322faf1 100644
--- a/sys/dev/bluetooth/files.bluetooth
+++ b/sys/dev/bluetooth/files.bluetooth
@@ -1,18 +1,17 @@
-# $NetBSD: files.bluetooth,v 1.7 2006/06/21 17:14:13 drochner Exp $
+# $NetBSD: files.bluetooth,v 1.8 2006/07/26 10:31:00 tron Exp $
#
-# Config file for machine independent Bluetooth devices that attach
-# to pseudo-device hub
+# Config file for machine independent Bluetooth devices
-# Hub driver
-defpseudo bthub { }
-file dev/bluetooth/bthub.c bthub
+# Bluetooth Devices
+defpseudo btdev { }
+file dev/bluetooth/btdev.c btdev
# HID "bus"
define bthidbus {[ reportid = -1 ]}
# HID Device
device bthidev: bluetooth, bthidbus, hid
-attach bthidev at bthub
+attach bthidev at btdev
file dev/bluetooth/bthidev.c bthidev
# HID Keyboards
@@ -29,5 +28,5 @@ file dev/bluetooth/btms.c btms
# Audio Headsets
device bthset: bluetooth, audiobus, auconv, mulaw, aurateconv
-attach bthset at bthub
+attach bthset at btdev
file dev/bluetooth/bthset.c bthset