PERFORCE change 162985 for review
Andrew Thompson
thompsa at FreeBSD.org
Fri May 29 03:22:49 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=162985
Change 162985 by thompsa at thompsa_burger on 2009/05/29 03:22:30
Sync files to SVN.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/controller/avr32dci.c#5 edit
.. //depot/projects/usb/src/sys/dev/usb/controller/avr32dci.h#6 edit
.. //depot/projects/usb/src/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c#31 edit
.. //depot/projects/usb/src/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_var.h#13 edit
.. //depot/projects/usb/src/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c#26 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/controller/avr32dci.c#5 (text+ko) ====
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/usb/controller/avr32dci.c $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/controller/avr32dci.c 192984 2009-05-28 17:36:36Z thompsa $");
/*-
* Copyright (c) 2009 Hans Petter Selasky. All rights reserved.
@@ -74,23 +74,23 @@
/* prototypes */
-struct usb2_bus_methods avr32dci_bus_methods;
-struct usb2_pipe_methods avr32dci_device_non_isoc_methods;
-struct usb2_pipe_methods avr32dci_device_isoc_fs_methods;
+struct usb_bus_methods avr32dci_bus_methods;
+struct usb_pipe_methods avr32dci_device_non_isoc_methods;
+struct usb_pipe_methods avr32dci_device_isoc_fs_methods;
static avr32dci_cmd_t avr32dci_setup_rx;
static avr32dci_cmd_t avr32dci_data_rx;
static avr32dci_cmd_t avr32dci_data_tx;
static avr32dci_cmd_t avr32dci_data_tx_sync;
-static void avr32dci_device_done(struct usb2_xfer *, usb2_error_t);
-static void avr32dci_do_poll(struct usb2_bus *);
-static void avr32dci_standard_done(struct usb2_xfer *);
+static void avr32dci_device_done(struct usb_xfer *, usb2_error_t);
+static void avr32dci_do_poll(struct usb_bus *);
+static void avr32dci_standard_done(struct usb_xfer *);
static void avr32dci_root_intr(struct avr32dci_softc *sc);
/*
* Here is a list of what the chip supports:
*/
-static const struct usb2_hw_ep_profile
+static const struct usb_hw_ep_profile
avr32dci_ep_profile[4] = {
[0] = {
@@ -134,8 +134,8 @@
};
static void
-avr32dci_get_hw_ep_profile(struct usb2_device *udev,
- const struct usb2_hw_ep_profile **ppf, uint8_t ep_addr)
+avr32dci_get_hw_ep_profile(struct usb_device *udev,
+ const struct usb_hw_ep_profile **ppf, uint8_t ep_addr)
{
if (ep_addr == 0)
*ppf = avr32dci_ep_profile;
@@ -254,7 +254,7 @@
avr32dci_setup_rx(struct avr32dci_td *td)
{
struct avr32dci_softc *sc;
- struct usb2_device_request req;
+ struct usb_device_request req;
uint16_t count;
uint32_t temp;
@@ -329,7 +329,7 @@
avr32dci_data_rx(struct avr32dci_td *td)
{
struct avr32dci_softc *sc;
- struct usb2_page_search buf_res;
+ struct usb_page_search buf_res;
uint16_t count;
uint32_t temp;
uint8_t to;
@@ -429,7 +429,7 @@
avr32dci_data_tx(struct avr32dci_td *td)
{
struct avr32dci_softc *sc;
- struct usb2_page_search buf_res;
+ struct usb_page_search buf_res;
uint16_t count;
uint8_t to;
uint32_t temp;
@@ -538,7 +538,7 @@
}
static uint8_t
-avr32dci_xfer_do_fifo(struct usb2_xfer *xfer)
+avr32dci_xfer_do_fifo(struct usb_xfer *xfer)
{
struct avr32dci_td *td;
@@ -583,7 +583,7 @@
static void
avr32dci_interrupt_poll(struct avr32dci_softc *sc)
{
- struct usb2_xfer *xfer;
+ struct usb_xfer *xfer;
repeat:
TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
@@ -727,7 +727,7 @@
}
static void
-avr32dci_setup_standard_chain(struct usb2_xfer *xfer)
+avr32dci_setup_standard_chain(struct usb_xfer *xfer)
{
struct avr32dci_std_temp temp;
struct avr32dci_softc *sc;
@@ -878,7 +878,7 @@
static void
avr32dci_timeout(void *arg)
{
- struct usb2_xfer *xfer = arg;
+ struct usb_xfer *xfer = arg;
DPRINTF("xfer=%p\n", xfer);
@@ -889,7 +889,7 @@
}
static void
-avr32dci_start_standard_chain(struct usb2_xfer *xfer)
+avr32dci_start_standard_chain(struct usb_xfer *xfer)
{
DPRINTFN(9, "\n");
@@ -925,7 +925,7 @@
}
static usb2_error_t
-avr32dci_standard_done_sub(struct usb2_xfer *xfer)
+avr32dci_standard_done_sub(struct usb_xfer *xfer)
{
struct avr32dci_td *td;
uint32_t len;
@@ -989,7 +989,7 @@
}
static void
-avr32dci_standard_done(struct usb2_xfer *xfer)
+avr32dci_standard_done(struct usb_xfer *xfer)
{
usb2_error_t err = 0;
@@ -1038,7 +1038,7 @@
* same USB transfer!
*------------------------------------------------------------------------*/
static void
-avr32dci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
+avr32dci_device_done(struct usb_xfer *xfer, usb2_error_t error)
{
struct avr32dci_softc *sc = AVR32_BUS2SC(xfer->xroot->bus);
uint8_t ep_no;
@@ -1061,8 +1061,8 @@
}
static void
-avr32dci_set_stall(struct usb2_device *udev, struct usb2_xfer *xfer,
- struct usb2_pipe *pipe)
+avr32dci_set_stall(struct usb_device *udev, struct usb_xfer *xfer,
+ struct usb_pipe *pipe)
{
struct avr32dci_softc *sc;
uint8_t ep_no;
@@ -1086,7 +1086,7 @@
avr32dci_clear_stall_sub(struct avr32dci_softc *sc, uint8_t ep_no,
uint8_t ep_type, uint8_t ep_dir)
{
- const struct usb2_hw_ep_profile *pf;
+ const struct usb_hw_ep_profile *pf;
uint32_t temp;
uint32_t epsize;
uint8_t n;
@@ -1148,10 +1148,10 @@
}
static void
-avr32dci_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe)
+avr32dci_clear_stall(struct usb_device *udev, struct usb_pipe *pipe)
{
struct avr32dci_softc *sc;
- struct usb2_endpoint_descriptor *ed;
+ struct usb_endpoint_descriptor *ed;
DPRINTFN(5, "pipe=%p\n", pipe);
@@ -1279,7 +1279,7 @@
}
static void
-avr32dci_do_poll(struct usb2_bus *bus)
+avr32dci_do_poll(struct usb_bus *bus)
{
struct avr32dci_softc *sc = AVR32_BUS2SC(bus);
@@ -1294,32 +1294,32 @@
* at91dci interrupt support
*------------------------------------------------------------------------*/
static void
-avr32dci_device_non_isoc_open(struct usb2_xfer *xfer)
+avr32dci_device_non_isoc_open(struct usb_xfer *xfer)
{
return;
}
static void
-avr32dci_device_non_isoc_close(struct usb2_xfer *xfer)
+avr32dci_device_non_isoc_close(struct usb_xfer *xfer)
{
avr32dci_device_done(xfer, USB_ERR_CANCELLED);
}
static void
-avr32dci_device_non_isoc_enter(struct usb2_xfer *xfer)
+avr32dci_device_non_isoc_enter(struct usb_xfer *xfer)
{
return;
}
static void
-avr32dci_device_non_isoc_start(struct usb2_xfer *xfer)
+avr32dci_device_non_isoc_start(struct usb_xfer *xfer)
{
/* setup TDs */
avr32dci_setup_standard_chain(xfer);
avr32dci_start_standard_chain(xfer);
}
-struct usb2_pipe_methods avr32dci_device_non_isoc_methods =
+struct usb_pipe_methods avr32dci_device_non_isoc_methods =
{
.open = avr32dci_device_non_isoc_open,
.close = avr32dci_device_non_isoc_close,
@@ -1331,19 +1331,19 @@
* at91dci full speed isochronous support
*------------------------------------------------------------------------*/
static void
-avr32dci_device_isoc_fs_open(struct usb2_xfer *xfer)
+avr32dci_device_isoc_fs_open(struct usb_xfer *xfer)
{
return;
}
static void
-avr32dci_device_isoc_fs_close(struct usb2_xfer *xfer)
+avr32dci_device_isoc_fs_close(struct usb_xfer *xfer)
{
avr32dci_device_done(xfer, USB_ERR_CANCELLED);
}
static void
-avr32dci_device_isoc_fs_enter(struct usb2_xfer *xfer)
+avr32dci_device_isoc_fs_enter(struct usb_xfer *xfer)
{
struct avr32dci_softc *sc = AVR32_BUS2SC(xfer->xroot->bus);
uint32_t temp;
@@ -1398,13 +1398,13 @@
}
static void
-avr32dci_device_isoc_fs_start(struct usb2_xfer *xfer)
+avr32dci_device_isoc_fs_start(struct usb_xfer *xfer)
{
/* start TD chain */
avr32dci_start_standard_chain(xfer);
}
-struct usb2_pipe_methods avr32dci_device_isoc_fs_methods =
+struct usb_pipe_methods avr32dci_device_isoc_fs_methods =
{
.open = avr32dci_device_isoc_fs_open,
.close = avr32dci_device_isoc_fs_close,
@@ -1418,8 +1418,8 @@
* Simulate a hardware HUB by handling all the necessary requests.
*------------------------------------------------------------------------*/
-static const struct usb2_device_descriptor avr32dci_devd = {
- .bLength = sizeof(struct usb2_device_descriptor),
+static const struct usb_device_descriptor avr32dci_devd = {
+ .bLength = sizeof(struct usb_device_descriptor),
.bDescriptorType = UDESC_DEVICE,
.bcdUSB = {0x00, 0x02},
.bDeviceClass = UDCLASS_HUB,
@@ -1432,8 +1432,8 @@
.bNumConfigurations = 1,
};
-static const struct usb2_device_qualifier avr32dci_odevd = {
- .bLength = sizeof(struct usb2_device_qualifier),
+static const struct usb_device_qualifier avr32dci_odevd = {
+ .bLength = sizeof(struct usb_device_qualifier),
.bDescriptorType = UDESC_DEVICE_QUALIFIER,
.bcdUSB = {0x00, 0x02},
.bDeviceClass = UDCLASS_HUB,
@@ -1445,7 +1445,7 @@
static const struct avr32dci_config_desc avr32dci_confd = {
.confd = {
- .bLength = sizeof(struct usb2_config_descriptor),
+ .bLength = sizeof(struct usb_config_descriptor),
.bDescriptorType = UDESC_CONFIG,
.wTotalLength[0] = sizeof(avr32dci_confd),
.bNumInterface = 1,
@@ -1455,7 +1455,7 @@
.bMaxPower = 0,
},
.ifcd = {
- .bLength = sizeof(struct usb2_interface_descriptor),
+ .bLength = sizeof(struct usb_interface_descriptor),
.bDescriptorType = UDESC_INTERFACE,
.bNumEndpoints = 1,
.bInterfaceClass = UICLASS_HUB,
@@ -1463,7 +1463,7 @@
.bInterfaceProtocol = UIPROTO_HSHUBSTT,
},
.endpd = {
- .bLength = sizeof(struct usb2_endpoint_descriptor),
+ .bLength = sizeof(struct usb_endpoint_descriptor),
.bDescriptorType = UDESC_ENDPOINT,
.bEndpointAddress = (UE_DIR_IN | AVR32_INTR_ENDPT),
.bmAttributes = UE_INTERRUPT,
@@ -1472,7 +1472,7 @@
},
};
-static const struct usb2_hub_descriptor_min avr32dci_hubd = {
+static const struct usb_hub_descriptor_min avr32dci_hubd = {
.bDescLength = sizeof(avr32dci_hubd),
.bDescriptorType = UDESC_HUB,
.bNbrPorts = 1,
@@ -1501,8 +1501,8 @@
USB_MAKE_STRING_DESC(STRING_PRODUCT, avr32dci_product);
static usb2_error_t
-avr32dci_roothub_exec(struct usb2_device *udev,
- struct usb2_device_request *req, const void **pptr, uint16_t *plength)
+avr32dci_roothub_exec(struct usb_device *udev,
+ struct usb_device_request *req, const void **pptr, uint16_t *plength)
{
struct avr32dci_softc *sc = AVR32_BUS2SC(udev->bus);
const void *ptr;
@@ -1928,11 +1928,11 @@
}
static void
-avr32dci_xfer_setup(struct usb2_setup_params *parm)
+avr32dci_xfer_setup(struct usb_setup_params *parm)
{
- const struct usb2_hw_ep_profile *pf;
+ const struct usb_hw_ep_profile *pf;
struct avr32dci_softc *sc;
- struct usb2_xfer *xfer;
+ struct usb_xfer *xfer;
void *last_obj;
uint32_t ntd;
uint32_t n;
@@ -2019,14 +2019,14 @@
}
static void
-avr32dci_xfer_unsetup(struct usb2_xfer *xfer)
+avr32dci_xfer_unsetup(struct usb_xfer *xfer)
{
return;
}
static void
-avr32dci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc,
- struct usb2_pipe *pipe)
+avr32dci_pipe_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
+ struct usb_pipe *pipe)
{
struct avr32dci_softc *sc = AVR32_BUS2SC(udev->bus);
@@ -2053,7 +2053,7 @@
}
}
-struct usb2_bus_methods avr32dci_bus_methods =
+struct usb_bus_methods avr32dci_bus_methods =
{
.pipe_init = &avr32dci_pipe_init,
.xfer_setup = &avr32dci_xfer_setup,
==== //depot/projects/usb/src/sys/dev/usb/controller/avr32dci.h#6 (text+ko) ====
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/usb/controller/avr32dci.h $ */
+/* $FreeBSD: head/sys/dev/usb/controller/avr32dci.h 192984 2009-05-28 17:36:36Z thompsa $ */
/*-
* Copyright (c) 2009 Hans Petter Selasky. All rights reserved.
*
@@ -157,12 +157,12 @@
struct avr32dci_td;
typedef uint8_t (avr32dci_cmd_t)(struct avr32dci_td *td);
-typedef void (avr32dci_clocks_t)(struct usb2_bus *);
+typedef void (avr32dci_clocks_t)(struct usb_bus *);
struct avr32dci_td {
struct avr32dci_td *obj_next;
avr32dci_cmd_t *func;
- struct usb2_page_cache *pc;
+ struct usb_page_cache *pc;
uint32_t offset;
uint32_t remainder;
uint16_t max_packet_size;
@@ -176,7 +176,7 @@
struct avr32dci_std_temp {
avr32dci_cmd_t *func;
- struct usb2_page_cache *pc;
+ struct usb_page_cache *pc;
struct avr32dci_td *td;
struct avr32dci_td *td_next;
uint32_t len;
@@ -193,14 +193,14 @@
};
struct avr32dci_config_desc {
- struct usb2_config_descriptor confd;
- struct usb2_interface_descriptor ifcd;
- struct usb2_endpoint_descriptor endpd;
+ struct usb_config_descriptor confd;
+ struct usb_interface_descriptor ifcd;
+ struct usb_endpoint_descriptor endpd;
} __packed;
union avr32dci_hub_temp {
uWord wValue;
- struct usb2_port_status ps;
+ struct usb_port_status ps;
};
struct avr32dci_flags {
@@ -218,14 +218,14 @@
};
struct avr32dci_softc {
- struct usb2_bus sc_bus;
+ struct usb_bus sc_bus;
union avr32dci_hub_temp sc_hub_temp;
/* must be set by by the bus interface layer */
avr32dci_clocks_t *sc_clocks_on;
avr32dci_clocks_t *sc_clocks_off;
- struct usb2_device *sc_devices[AVR32_MAX_DEVICES];
+ struct usb_device *sc_devices[AVR32_MAX_DEVICES];
struct resource *sc_irq_res;
void *sc_intr_hdl;
struct resource *sc_io_res;
==== //depot/projects/usb/src/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c#31 (text+ko) ====
@@ -3,7 +3,7 @@
*/
/*-
- * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin at yahoo.com>
+ * Copyright (c) 2001-2009 Maksim Yevmenkin <m_evmenkin at yahoo.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,29 +27,89 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ng_ubt.c,v 1.22 2005/10/31 17:57:44 max Exp $
- * $FreeBSD: src/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c,v 1.36 2008/10/03 22:40:42 emax Exp $
+ * $Id: ng_ubt.c,v 1.16 2003/10/10 19:15:06 max Exp $
+ * $FreeBSD: head/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c 192984 2009-05-28 17:36:36Z thompsa $
*/
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/endian.h>
-#include <sys/filio.h>
-#include <sys/fcntl.h>
-#include <sys/mbuf.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/poll.h>
-#include <sys/uio.h>
-#include <machine/bus.h>
+/*
+ * NOTE: ng_ubt2 driver has a split personality. On one side it is
+ * a USB device driver and on the other it is a Netgraph node. This
+ * driver will *NOT* create traditional /dev/ enties, only Netgraph
+ * node.
+ *
+ * NOTE ON LOCKS USED: ng_ubt2 drives uses 2 locks (mutexes)
+ *
+ * 1) sc_if_mtx - lock for device's interface #0 and #1. This lock is used
+ * by USB for any USB request going over device's interface #0 and #1,
+ * i.e. interrupt, control, bulk and isoc. transfers.
+ *
+ * 2) sc_ng_mtx - this lock is used to protect shared (between USB, Netgraph
+ * and Taskqueue) data, such as outgoing mbuf queues, task flags and hook
+ * pointer. This lock *SHOULD NOT* be grabbed for a long time. In fact,
+ * think of it as a spin lock.
+ *
+ * NOTE ON LOCKING STRATEGY: ng_ubt2 driver operates in 3 different contexts.
+ *
+ * 1) USB context. This is where all the USB related stuff happens. All
+ * callbacks run in this context. All callbacks are called (by USB) with
+ * appropriate interface lock held. It is (generally) allowed to grab
+ * any additional locks.
+ *
+ * 2) Netgraph context. This is where all the Netgraph related stuff happens.
+ * Since we mark node as WRITER, the Netgraph node will be "locked" (from
+ * Netgraph point of view). Any variable that is only modified from the
+ * Netgraph context does not require any additonal locking. It is generally
+ * *NOT* allowed to grab *ANY* additional locks. Whatever you do, *DO NOT*
+ * grab any lock in the Netgraph context that could cause de-scheduling of
+ * the Netgraph thread for significant amount of time. In fact, the only
+ * lock that is allowed in the Netgraph context is the sc_ng_mtx lock.
+ * Also make sure that any code that is called from the Netgraph context
+ * follows the rule above.
+ *
+ * 3) Taskqueue context. This is where ubt_task runs. Since we are generally
+ * NOT allowed to grab any lock that could cause de-scheduling in the
+ * Netgraph context, and, USB requires us to grab interface lock before
+ * doing things with transfers, it is safer to transition from the Netgraph
+ * context to the Taskqueue context before we can call into USB subsystem.
+ *
+ * So, to put everything together, the rules are as follows.
+ * It is OK to call from the USB context or the Taskqueue context into
+ * the Netgraph context (i.e. call NG_SEND_xxx functions). In other words
+ * it is allowed to call into the Netgraph context with locks held.
+ * Is it *NOT* OK to call from the Netgraph context into the USB context,
+ * because USB requires us to grab interface locks, and, it is safer to
+ * avoid it. So, to make things safer we set task flags to indicate which
+ * actions we want to perform and schedule ubt_task which would run in the
+ * Taskqueue context.
+ * Is is OK to call from the Taskqueue context into the USB context,
+ * and, ubt_task does just that (i.e. grabs appropriate interface locks
+ * before calling into USB).
+ * Access to the outgoing queues, task flags and hook pointer is
+ * controlled by the sc_ng_mtx lock. It is an unavoidable evil. Again,
+ * sc_ng_mtx should really be a spin lock (and it is very likely to an
+ * equivalent of spin lock due to adaptive nature of FreeBSD mutexes).
+ * All USB callbacks accept softc pointer as a private data. USB ensures
+ * that this pointer is valid.
+ */
+#include "usbdevs.h"
#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
+#include <dev/usb/usb_mfunc.h>
+#include <dev/usb/usb_error.h>
+
+#define USB_DEBUG_VAR usb2_debug
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_debug.h>
+#include <dev/usb/usb_parse.h>
+#include <dev/usb/usb_lookup.h>
+#include <dev/usb/usb_util.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_transfer.h>
+
+#include <sys/mbuf.h>
+#include <sys/taskqueue.h>
#include <netgraph/ng_message.h>
#include <netgraph/netgraph.h>
@@ -59,73 +119,17 @@
#include <netgraph/bluetooth/include/ng_ubt.h>
#include <netgraph/bluetooth/drivers/ubt/ng_ubt_var.h>
-#include "usbdevs.h"
+static int ubt_modevent(module_t, int, void *);
+static device_probe_t ubt_probe;
+static device_attach_t ubt_attach;
+static device_detach_t ubt_detach;
-/*
- * USB methods
- */
+static void ubt_task_schedule(ubt_softc_p, int);
+static task_fn_t ubt_task;
-static device_probe_t ubt_match;
-static device_attach_t ubt_attach;
-static device_detach_t ubt_detach;
+#define ubt_xfer_start(sc, i) usb2_transfer_start((sc)->sc_xfer[(i)])
-static device_method_t ubt_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ubt_match),
- DEVMETHOD(device_attach, ubt_attach),
- DEVMETHOD(device_detach, ubt_detach),
-
- { 0, 0 }
-};
-
-static driver_t ubt_driver = {
- "ubt",
- ubt_methods,
- sizeof(struct ubt_softc)
-};
-
-static devclass_t ubt_devclass;
-
-static int ubt_modevent (module_t, int, void *);
-
-static usbd_status ubt_request_start (ubt_softc_p);
-static void ubt_request_complete (usbd_xfer_handle,
- usbd_private_handle, usbd_status);
-static void ubt_request_complete2 (node_p, hook_p, void *, int);
-
-static usbd_status ubt_intr_start (ubt_softc_p);
-static void ubt_intr_complete (usbd_xfer_handle,
- usbd_private_handle, usbd_status);
-static void ubt_intr_complete2 (node_p, hook_p, void *, int);
-
-static usbd_status ubt_bulk_in_start (ubt_softc_p);
-static void ubt_bulk_in_complete (usbd_xfer_handle,
- usbd_private_handle, usbd_status);
-static void ubt_bulk_in_complete2 (node_p, hook_p, void *, int);
-
-static usbd_status ubt_bulk_out_start (ubt_softc_p);
-static void ubt_bulk_out_complete (usbd_xfer_handle,
- usbd_private_handle, usbd_status);
-static void ubt_bulk_out_complete2 (node_p, hook_p, void *, int);
-
-static usbd_status ubt_isoc_in_start_one (ubt_softc_p, int);
-static usbd_status ubt_isoc_in_start (ubt_softc_p);
-static void ubt_isoc_in_complete (usbd_xfer_handle,
- usbd_private_handle, usbd_status);
-static void ubt_isoc_in_complete2 (node_p, hook_p, void *, int);
-
-static usbd_status ubt_isoc_out_start_one (ubt_softc_p, int);
-static usbd_status ubt_isoc_out_start (ubt_softc_p);
-static void ubt_isoc_out_complete (usbd_xfer_handle,
- usbd_private_handle, usbd_status);
-static void ubt_isoc_out_complete2 (node_p, hook_p, void *, int);
-
-static void ubt_reset (ubt_softc_p);
-
-/*
- * Netgraph methods
- */
-
+/* Netgraph methods */
static ng_constructor_t ng_ubt_constructor;
static ng_shutdown_t ng_ubt_shutdown;
static ng_newhook_t ng_ubt_newhook;
@@ -141,7 +145,8 @@
{ "qlen", &ng_parse_int32_type, },
{ NULL, }
};
-static const struct ng_parse_type ng_ubt_node_qlen_type = {
+static const struct ng_parse_type ng_ubt_node_qlen_type =
+{
&ng_parse_struct_type,
&ng_ubt_node_qlen_type_fields
};
@@ -157,61 +162,64 @@
{ "ierrors", &ng_parse_uint32_type, },
{ NULL, }
};
-static const struct ng_parse_type ng_ubt_node_stat_type = {
+static const struct ng_parse_type ng_ubt_node_stat_type =
+{
&ng_parse_struct_type,
&ng_ubt_node_stat_type_fields
};
/* Netgraph node command list */
-static const struct ng_cmdlist ng_ubt_cmdlist[] = {
+static const struct ng_cmdlist ng_ubt_cmdlist[] =
{
- NGM_UBT_COOKIE,
- NGM_UBT_NODE_SET_DEBUG,
- "set_debug",
- &ng_parse_uint16_type,
- NULL
-},
-{
- NGM_UBT_COOKIE,
- NGM_UBT_NODE_GET_DEBUG,
- "get_debug",
- NULL,
- &ng_parse_uint16_type
-},
-{
- NGM_UBT_COOKIE,
- NGM_UBT_NODE_SET_QLEN,
- "set_qlen",
- &ng_ubt_node_qlen_type,
- NULL
-},
-{
- NGM_UBT_COOKIE,
- NGM_UBT_NODE_GET_QLEN,
- "get_qlen",
- &ng_ubt_node_qlen_type,
- &ng_ubt_node_qlen_type
-},
-{
- NGM_UBT_COOKIE,
- NGM_UBT_NODE_GET_STAT,
- "get_stat",
- NULL,
- &ng_ubt_node_stat_type
-},
-{
- NGM_UBT_COOKIE,
- NGM_UBT_NODE_RESET_STAT,
- "reset_stat",
- NULL,
- NULL
-},
-{ 0, }
+ {
+ NGM_UBT_COOKIE,
+ NGM_UBT_NODE_SET_DEBUG,
+ "set_debug",
+ &ng_parse_uint16_type,
+ NULL
+ },
+ {
+ NGM_UBT_COOKIE,
+ NGM_UBT_NODE_GET_DEBUG,
+ "get_debug",
+ NULL,
+ &ng_parse_uint16_type
+ },
+ {
+ NGM_UBT_COOKIE,
+ NGM_UBT_NODE_SET_QLEN,
+ "set_qlen",
+ &ng_ubt_node_qlen_type,
+ NULL
+ },
+ {
+ NGM_UBT_COOKIE,
+ NGM_UBT_NODE_GET_QLEN,
+ "get_qlen",
+ &ng_ubt_node_qlen_type,
+ &ng_ubt_node_qlen_type
+ },
+ {
+ NGM_UBT_COOKIE,
+ NGM_UBT_NODE_GET_STAT,
+ "get_stat",
+ NULL,
+ &ng_ubt_node_stat_type
+ },
+ {
+ NGM_UBT_COOKIE,
+ NGM_UBT_NODE_RESET_STAT,
+ "reset_stat",
+ NULL,
+ NULL
+ },
+ { 0, }
};
/* Netgraph node type */
-static struct ng_type typestruct = {
- .version = NG_ABI_VERSION,
+static struct ng_type typestruct =
+{
+ .version = NG_ABI_VERSION,
.name = NG_UBT_NODE_TYPE,
.constructor = ng_ubt_constructor,
.rcvmsg = ng_ubt_rcvmsg,
@@ -220,192 +228,251 @@
.connect = ng_ubt_connect,
.rcvdata = ng_ubt_rcvdata,
.disconnect = ng_ubt_disconnect,
- .cmdlist = ng_ubt_cmdlist
+ .cmdlist = ng_ubt_cmdlist
};
-/*
- * Module
- */
-
-DRIVER_MODULE(ubt, uhub, ubt_driver, ubt_devclass, ubt_modevent, 0);
-MODULE_VERSION(ng_ubt, NG_BLUETOOTH_VERSION);
-MODULE_DEPEND(ng_ubt, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
-MODULE_DEPEND(ubt, usb, 1, 1, 1);
-
-
/****************************************************************************
****************************************************************************
** USB specific
****************************************************************************
****************************************************************************/
+/* USB methods */
+static usb2_callback_t ubt_ctrl_write_callback;
+static usb2_callback_t ubt_intr_read_callback;
+static usb2_callback_t ubt_bulk_read_callback;
+static usb2_callback_t ubt_bulk_write_callback;
+static usb2_callback_t ubt_isoc_read_callback;
+static usb2_callback_t ubt_isoc_write_callback;
+
+static int ubt_fwd_mbuf_up(ubt_softc_p, struct mbuf **);
+static int ubt_isoc_read_one_frame(struct usb_xfer *, int);
+
/*
- * Load/Unload the driver module
+ * USB config
+ *
+ * The following desribes usb transfers that could be submitted on USB device.
+ *
+ * Interface 0 on the USB device must present the following endpoints
+ * 1) Interrupt endpoint to receive HCI events
+ * 2) Bulk IN endpoint to receive ACL data
+ * 3) Bulk OUT endpoint to send ACL data
+ *
+ * Interface 1 on the USB device must present the following endpoints
+ * 1) Isochronous IN endpoint to receive SCO data
+ * 2) Isochronous OUT endpoint to send SCO data
*/
-static int
-ubt_modevent(module_t mod, int event, void *data)
+static const struct usb_config ubt_config[UBT_N_TRANSFER] =
{
- int error;
+ /*
+ * Interface #0
+ */
+
+ /* Outgoing bulk transfer - ACL packets */
+ [UBT_IF_0_BULK_DT_WR] = {
+ .type = UE_BULK,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_OUT,
+ .if_index = 0,
+ .bufsize = UBT_BULK_WRITE_BUFFER_SIZE,
+ .flags = { .pipe_bof = 1, .force_short_xfer = 1, },
+ .callback = &ubt_bulk_write_callback,
+ },
+ /* Incoming bulk transfer - ACL packets */
+ [UBT_IF_0_BULK_DT_RD] = {
+ .type = UE_BULK,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_IN,
+ .if_index = 0,
+ .bufsize = UBT_BULK_READ_BUFFER_SIZE,
+ .flags = { .pipe_bof = 1, .short_xfer_ok = 1, },
+ .callback = &ubt_bulk_read_callback,
+ },
+ /* Incoming interrupt transfer - HCI events */
+ [UBT_IF_0_INTR_DT_RD] = {
+ .type = UE_INTERRUPT,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_IN,
+ .if_index = 0,
+ .flags = { .pipe_bof = 1, .short_xfer_ok = 1, },
+ .bufsize = UBT_INTR_BUFFER_SIZE,
+ .callback = &ubt_intr_read_callback,
+ },
+ /* Outgoing control transfer - HCI commands */
+ [UBT_IF_0_CTRL_DT_WR] = {
+ .type = UE_CONTROL,
+ .endpoint = 0x00, /* control pipe */
+ .direction = UE_DIR_ANY,
+ .if_index = 0,
+ .bufsize = UBT_CTRL_BUFFER_SIZE,
+ .callback = &ubt_ctrl_write_callback,
+ .timeout = 5000, /* 5 seconds */
+ },
+
+ /*
+ * Interface #1
+ */
+
+ /* Incoming isochronous transfer #1 - SCO packets */
+ [UBT_IF_1_ISOC_DT_RD1] = {
+ .type = UE_ISOCHRONOUS,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_IN,
+ .if_index = 1,
+ .bufsize = 0, /* use "wMaxPacketSize * frames" */
+ .frames = UBT_ISOC_NFRAMES,
+ .flags = { .short_xfer_ok = 1, },
+ .callback = &ubt_isoc_read_callback,
+ },
+ /* Incoming isochronous transfer #2 - SCO packets */
+ [UBT_IF_1_ISOC_DT_RD2] = {
+ .type = UE_ISOCHRONOUS,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_IN,
+ .if_index = 1,
+ .bufsize = 0, /* use "wMaxPacketSize * frames" */
+ .frames = UBT_ISOC_NFRAMES,
+ .flags = { .short_xfer_ok = 1, },
+ .callback = &ubt_isoc_read_callback,
+ },
+ /* Outgoing isochronous transfer #1 - SCO packets */
+ [UBT_IF_1_ISOC_DT_WR1] = {
+ .type = UE_ISOCHRONOUS,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_OUT,
+ .if_index = 1,
+ .bufsize = 0, /* use "wMaxPacketSize * frames" */
+ .frames = UBT_ISOC_NFRAMES,
+ .flags = { .short_xfer_ok = 1, },
+ .callback = &ubt_isoc_write_callback,
+ },
+ /* Outgoing isochronous transfer #2 - SCO packets */
+ [UBT_IF_1_ISOC_DT_WR2] = {
+ .type = UE_ISOCHRONOUS,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_OUT,
+ .if_index = 1,
+ .bufsize = 0, /* use "wMaxPacketSize * frames" */
+ .frames = UBT_ISOC_NFRAMES,
+ .flags = { .short_xfer_ok = 1, },
+ .callback = &ubt_isoc_write_callback,
+ },
+};
- switch (event) {
- case MOD_LOAD:
- error = ng_newtype(&typestruct);
- if (error != 0)
- printf(
-"%s: Could not register Netgraph node type, error=%d\n",
- NG_UBT_NODE_TYPE, error);
- else
- error = usbd_driver_load(mod, event, data);
- break;
+/*
+ * If for some reason device should not be attached then put
+ * VendorID/ProductID pair into the list below. The format is
+ * as follows:
+ *
+ * { USB_VPI(VENDOR_ID, PRODUCT_ID, 0) },
+ *
+ * where VENDOR_ID and PRODUCT_ID are hex numbers.
+ */
- case MOD_UNLOAD:
- error = ng_rmtype(&typestruct);
- if (error == 0)
- error = usbd_driver_load(mod, event, data);
- break;
+static const struct usb_device_id ubt_ignore_devs[] =
+{
+ /* AVM USB Bluetooth-Adapter BlueFritz! v1.0 */
+ { USB_VPI(USB_VENDOR_AVM, 0x2200, 0) },
+};
- default:
- error = EOPNOTSUPP;
- break;
- }
+/* List of supported bluetooth devices */
+static const struct usb_device_id ubt_devs[] =
+{
+ /* Generic Bluetooth class devices */
+ { USB_IFACE_CLASS(UDCLASS_WIRELESS),
+ USB_IFACE_SUBCLASS(UDSUBCLASS_RF),
+ USB_IFACE_PROTOCOL(UDPROTO_BLUETOOTH) },
- return (error);
-} /* ubt_modevent */
+ /* AVM USB Bluetooth-Adapter BlueFritz! v2.0 */
+ { USB_VPI(USB_VENDOR_AVM, 0x3800, 0) },
+};
/*
- * Probe for a USB Bluetooth device
+ * Probe for a USB Bluetooth device.
+ * USB context.
*/
static int
-ubt_match(device_t self)
+ubt_probe(device_t dev)
{
- /*
- * If for some reason device should not be attached then put
- * VendorID/ProductID pair into the list below. The format is
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list