Date: Fri, 29 May 2009 03:22:47 GMT From: Andrew Thompson <thompsa@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 162985 for review Message-ID: <200905290322.n4T3Mlu0054296@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=162985 Change 162985 by thompsa@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@yahoo.com> + * Copyright (c) 2001-2009 Maksim Yevmenkin <m_evmenkin@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) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905290322.n4T3Mlu0054296>