Date: Fri, 14 Jul 2006 14:33:27 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 101554 for review Message-ID: <200607141433.k6EEXRl5094162@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=101554 Change 101554 by hselasky@hselasky_mini_itx on 2006/07/14 14:32:45 Finished reworking the Bluetooth USB driver, UBT. Please test. Affected files ... .. //depot/projects/usb/src/sys/netgraph/bluetooth/drivers/ubt/TODO#2 edit .. //depot/projects/usb/src/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c#2 edit .. //depot/projects/usb/src/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_var.h#2 edit Differences ... ==== //depot/projects/usb/src/sys/netgraph/bluetooth/drivers/ubt/TODO#2 (text+ko) ==== @@ -6,25 +6,13 @@ The code makes use of ng_send_fn() whenever possible. Just need to verify and make sure i did it right -2) Review USB ATTACH function - - It is a bit ugly now. Probably need a better way to discover - USB device configuration. - 2) Firmware upgrade According to Bluetooth spec device may present third interface to perform firmware upgrade. 3Com USB Bluetooth dongle has such interface. Need to implement set of Netgraph messages. -3) Understand and fix isoc. USB transfers (SCO data) +3) Isochronous USB transfers (SCO data) - Currenty device reports that is got zero bytes and calls - isoc_in_complete callback over and over again. Why? - Also might need to setup at least two isoc. transfers in - both directions and switch them on the fly. Just to ensure - there at least one transfer at any time ready to run. - -4) Currently interrupt transfers are done as bulk-in transfers - - Need to check if that is allowed. + Tried to fix isochrounous transfers, which are still disabled + by default. ==== //depot/projects/usb/src/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c#2 (text+ko) ==== @@ -31,25 +31,17 @@ * $FreeBSD: src/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c,v 1.26 2005/12/04 10:06:05 ru Exp $ */ +#include <sys/cdefs.h> #include <sys/param.h> #include <sys/systm.h> -#include <sys/bus.h> -#include <sys/conf.h> +#include <sys/kernel.h> +#include <sys/mbuf.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> +#include <dev/usb/usb_port.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_subr.h> +#include <dev/usb/usb_quirks.h> #include <netgraph/ng_message.h> #include <netgraph/netgraph.h> @@ -65,68 +57,51 @@ * USB methods */ -USB_DECLARE_DRIVER(ubt); +static device_probe_t ubt_probe; +static device_attach_t ubt_attach; +static device_detach_t ubt_detach; -Static int ubt_modevent (module_t, int, void *); +static devclass_t ubt_devclass; -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 device_method_t ubt_methods[] = { + DEVMETHOD(device_probe, ubt_probe), + DEVMETHOD(device_attach, ubt_attach), + DEVMETHOD(device_detach, ubt_detach), + { 0, 0 } +}; -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 driver_t ubt_driver = { + .name = "ubt", + .methods = ubt_methods, + .size = sizeof(struct ubt_softc), +}; -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 (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 (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 */ -Static ng_constructor_t ng_ubt_constructor; -Static ng_shutdown_t ng_ubt_shutdown; -Static ng_newhook_t ng_ubt_newhook; -Static ng_connect_t ng_ubt_connect; -Static ng_disconnect_t ng_ubt_disconnect; -Static ng_rcvmsg_t ng_ubt_rcvmsg; -Static ng_rcvdata_t ng_ubt_rcvdata; +static ng_constructor_t ng_ubt_constructor; +static ng_shutdown_t ng_ubt_shutdown; +static ng_newhook_t ng_ubt_newhook; +static ng_connect_t ng_ubt_connect; +static ng_disconnect_t ng_ubt_disconnect; +static ng_rcvmsg_t ng_ubt_rcvmsg; +static ng_rcvdata_t ng_ubt_rcvdata; /* Queue length */ -Static const struct ng_parse_struct_field ng_ubt_node_qlen_type_fields[] = +static const struct ng_parse_struct_field ng_ubt_node_qlen_type_fields[] = { { "queue", &ng_parse_int32_type, }, { "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 }; /* Stat info */ -Static const struct ng_parse_struct_field ng_ubt_node_stat_type_fields[] = +static const struct ng_parse_struct_field ng_ubt_node_stat_type_fields[] = { { "pckts_recv", &ng_parse_uint32_type, }, { "bytes_recv", &ng_parse_uint32_type, }, @@ -136,13 +111,13 @@ { "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, @@ -189,7 +164,7 @@ }; /* Netgraph node type */ -Static struct ng_type typestruct = { +static struct ng_type typestruct = { .version = NG_ABI_VERSION, .name = NG_UBT_NODE_TYPE, .constructor = ng_ubt_constructor, @@ -202,6 +177,200 @@ .cmdlist = ng_ubt_cmdlist }; +/* USB methods */ + +static int +ubt_modevent(module_t mod, int event, void *data); + +static void +ubt_ctrl_write_callback(struct usbd_xfer *xfer); + +static void +ubt_intr_read_callback(struct usbd_xfer *xfer); + +static void +ubt_intr_read_clear_stall_callback(struct usbd_xfer *xfer); + +static void +ubt_intr_read_complete(node_p node, hook_p hook, void *arg1, int arg2); + +static void +ubt_bulk_read_callback(struct usbd_xfer *xfer); + +static void +ubt_bulk_read_clear_stall_callback(struct usbd_xfer *xfer); + +static void +ubt_bulk_read_complete(node_p node, hook_p hook, void *arg1, int arg2); + +static void +ubt_bulk_write_callback(struct usbd_xfer *xfer); + +static void +ubt_bulk_write_clear_stall_callback(struct usbd_xfer *xfer); + +static void +ubt_isoc_read_callback(struct usbd_xfer *xfer); + +static void +ubt_isoc_read_complete(node_p node, hook_p hook, void *arg1, int arg2); + +static void +ubt_isoc_write_callback(struct usbd_xfer *xfer); + +/* USB config */ +static const struct usbd_config ubt_config_if_0[UBT_IF_0_N_TRANSFER] = { + + [0] = { + .type = UE_BULK, + .endpoint = -1, /* any */ + .direction = UE_DIR_OUT, + .bufsize = UBT_BULK_WRITE_BUFFER_SIZE, + .flags = 0, + .callback = &ubt_bulk_write_callback, + }, + + [1] = { + .type = UE_BULK, + .endpoint = -1, /* any */ + .direction = UE_DIR_IN, + .bufsize = UBT_BULK_READ_BUFFER_SIZE, + .flags = USBD_SHORT_XFER_OK, + .callback = &ubt_bulk_read_callback, + }, + + [2] = { + .type = UE_INTERRUPT, + .endpoint = -1, /* any */ + .direction = UE_DIR_IN, + .flags = USBD_SHORT_XFER_OK, + .bufsize = 0, /* use wMaxPacketSize */ + .callback = &ubt_intr_read_callback, + }, + + [3] = { + .type = UE_CONTROL, + .endpoint = 0x00, /* Control pipe */ + .direction = -1, + .bufsize = (sizeof(usb_device_request_t) + UBT_CTRL_BUFFER_SIZE), + .callback = &ubt_ctrl_write_callback, + .timeout = 5000, /* 5 seconds */ + }, + + [4] = { + .type = UE_CONTROL, + .endpoint = 0x00, /* Control pipe */ + .direction = -1, + .bufsize = sizeof(usb_device_request_t), + .callback = &ubt_bulk_write_clear_stall_callback, + .timeout = 1000, /* 1 second */ + }, + + [5] = { + .type = UE_CONTROL, + .endpoint = 0x00, /* Control pipe */ + .direction = -1, + .bufsize = sizeof(usb_device_request_t), + .callback = &ubt_bulk_read_clear_stall_callback, + .timeout = 1000, /* 1 second */ + }, + + [6] = { + .type = UE_CONTROL, + .endpoint = 0x00, /* Control pipe */ + .direction = -1, + .bufsize = sizeof(usb_device_request_t), + .callback = &ubt_intr_read_clear_stall_callback, + .timeout = 1000, /* 1 second */ + }, +}; + +/* USB config */ +static const struct usbd_config ubt_config_if_1_full_speed[UBT_IF_1_N_TRANSFER] = { + [0] = { + .type = UE_ISOCHRONOUS, + .endpoint = -1, /* any */ + .direction = UE_DIR_IN, + .bufsize = 0, /* use "wMaxPacketSize * frames" */ + .frames = UBT_ISOC_NFRAMES, + .flags = USBD_SHORT_XFER_OK, + .callback = &ubt_isoc_read_callback, + }, + + [1] = { + .type = UE_ISOCHRONOUS, + .endpoint = -1, /* any */ + .direction = UE_DIR_IN, + .bufsize = 0, /* use "wMaxPacketSize * frames" */ + .frames = UBT_ISOC_NFRAMES, + .flags = USBD_SHORT_XFER_OK, + .callback = &ubt_isoc_read_callback, + }, + + [2] = { + .type = UE_ISOCHRONOUS, + .endpoint = -1, /* any */ + .direction = UE_DIR_OUT, + .bufsize = 0, /* use "wMaxPacketSize * frames" */ + .frames = UBT_ISOC_NFRAMES, + .flags = USBD_SHORT_XFER_OK, + .callback = &ubt_isoc_write_callback, + }, + + [3] = { + .type = UE_ISOCHRONOUS, + .endpoint = -1, /* any */ + .direction = UE_DIR_OUT, + .bufsize = 0, /* use "wMaxPacketSize * frames" */ + .frames = UBT_ISOC_NFRAMES, + .flags = USBD_SHORT_XFER_OK, + .callback = &ubt_isoc_write_callback, + }, +}; + +/* USB config */ +static const struct usbd_config ubt_config_if_1_high_speed[UBT_IF_1_N_TRANSFER] = { + [0] = { + .type = UE_ISOCHRONOUS, + .endpoint = -1, /* any */ + .direction = UE_DIR_IN, + .bufsize = 0, /* use "wMaxPacketSize * frames" */ + .frames = UBT_ISOC_NFRAMES * 8, + .flags = USBD_SHORT_XFER_OK, + .callback = &ubt_isoc_read_callback, + }, + + [1] = { + .type = UE_ISOCHRONOUS, + .endpoint = -1, /* any */ + .direction = UE_DIR_IN, + .bufsize = 0, /* use "wMaxPacketSize * frames" */ + .frames = UBT_ISOC_NFRAMES * 8, + .flags = USBD_SHORT_XFER_OK, + .callback = &ubt_isoc_read_callback, + }, + + [2] = { + .type = UE_ISOCHRONOUS, + .endpoint = -1, /* any */ + .direction = UE_DIR_OUT, + .bufsize = 0, /* use "wMaxPacketSize * frames" */ + .frames = UBT_ISOC_NFRAMES * 8, + .flags = USBD_SHORT_XFER_OK, + .callback = &ubt_isoc_write_callback, + }, + + [3] = { + .type = UE_ISOCHRONOUS, + .endpoint = -1, /* any */ + .direction = UE_DIR_OUT, + .bufsize = 0, /* use "wMaxPacketSize * frames" */ + .frames = UBT_ISOC_NFRAMES * 8, + .flags = USBD_SHORT_XFER_OK, + .callback = &ubt_isoc_write_callback, + }, +}; + /* * Module */ @@ -220,7 +389,7 @@ * Load/Unload the driver module */ -Static int +static int ubt_modevent(module_t mod, int event, void *data) { int error; @@ -228,10 +397,11 @@ 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); + 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; @@ -254,7 +424,8 @@ * Probe for a USB Bluetooth device */ -USB_MATCH(ubt) +static int32_t +ubt_probe(device_t dev) { /* * If for some reason device should not be attached then put @@ -266,8 +437,10 @@ * where VENDOR_ID and PRODUCT_ID are hex numbers. */ - Static struct usb_devno const ubt_ignored_devices[] = { - { USB_VENDOR_AVM, 0x2200 }, /* AVM USB Bluetooth-Adapter BlueFritz! v1.0 */ + static struct usb_devno const ubt_ignored_devices[] = { + { USB_VENDOR_AVM, 0x2200 }, /* AVM USB Bluetooth-Adapter + * BlueFritz! v1.0 + */ { 0, 0 } /* This should be the last item in the list */ }; @@ -279,108 +452,84 @@ * to attach to the broken device. */ - Static struct usb_devno const ubt_broken_devices[] = { - { USB_VENDOR_AVM, 0x3800 }, /* AVM USB Bluetooth-Adapter BlueFritz! v2.0 */ + static struct usb_devno const ubt_broken_devices[] = { + { USB_VENDOR_AVM, 0x3800 }, /* AVM USB Bluetooth-Adapter + * BlueFritz! v2.0 + */ { 0, 0 } /* This should be the last item in the list */ }; - USB_MATCH_START(ubt, uaa); - + struct usb_attach_arg *uaa = device_get_ivars(dev); usb_device_descriptor_t *dd = usbd_get_device_descriptor(uaa->device); - if (uaa->iface == NULL || - usb_lookup(ubt_ignored_devices, uaa->vendor, uaa->product)) - return (UMATCH_NONE); + if ((uaa->iface == NULL) || + usb_lookup(ubt_ignored_devices, uaa->vendor, uaa->product)) { + return (UMATCH_NONE); + } - if (dd->bDeviceClass == UDCLASS_WIRELESS && - dd->bDeviceSubClass == UDSUBCLASS_RF && - dd->bDeviceProtocol == UDPROTO_BLUETOOTH) - return (UMATCH_DEVCLASS_DEVSUBCLASS); + if ((dd->bDeviceClass == UDCLASS_WIRELESS) && + (dd->bDeviceSubClass == UDSUBCLASS_RF) && + (dd->bDeviceProtocol == UDPROTO_BLUETOOTH)) { + return (UMATCH_DEVCLASS_DEVSUBCLASS); + } - if (usb_lookup(ubt_broken_devices, uaa->vendor, uaa->product)) - return (UMATCH_VENDOR_PRODUCT); + if (usb_lookup(ubt_broken_devices, uaa->vendor, uaa->product)) { + return (UMATCH_VENDOR_PRODUCT); + } return (UMATCH_NONE); -} /* USB_MATCH(ubt) */ +} /* * Attach the device */ -USB_ATTACH(ubt) +static int32_t +ubt_attach(device_t dev) { - USB_ATTACH_START(ubt, sc, uaa); - usb_config_descriptor_t *cd = NULL; - usb_interface_descriptor_t *id = NULL; - usb_endpoint_descriptor_t *ed = NULL; - char devinfo[1024]; - usbd_status error; - int i, ai, alt_no, isoc_in, isoc_out, - isoc_isize, isoc_osize; + struct usb_attach_arg *uaa = device_get_ivars(dev); + struct ubt_softc *sc = device_get_softc(dev); + u_int8_t i; + + usbd_set_desc(dev, uaa->device); - /* Get USB device info */ - sc->sc_udev = uaa->device; - usbd_devinfo(sc->sc_udev, 0, devinfo); - USB_ATTACH_SETUP; - printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo); + snprintf(sc->sc_name, sizeof(sc->sc_name), + "%s", device_get_nameunit(dev)); /* * Initialize device softc structure */ - /* State */ + /* state */ sc->sc_debug = NG_UBT_WARN_LEVEL; sc->sc_flags = 0; NG_UBT_STAT_RESET(sc->sc_stat); - /* Interfaces */ - sc->sc_iface0 = sc->sc_iface1 = NULL; - - /* Interrupt pipe */ - sc->sc_intr_ep = -1; - sc->sc_intr_pipe = NULL; - sc->sc_intr_xfer = NULL; - sc->sc_intr_buffer = NULL; - - /* Control pipe */ - sc->sc_ctrl_xfer = NULL; - sc->sc_ctrl_buffer = NULL; + /* control pipe */ NG_BT_MBUFQ_INIT(&sc->sc_cmdq, UBT_DEFAULT_QLEN); - /* Bulk-in pipe */ - sc->sc_bulk_in_ep = -1; - sc->sc_bulk_in_pipe = NULL; - sc->sc_bulk_in_xfer = NULL; - sc->sc_bulk_in_buffer = NULL; - - /* Bulk-out pipe */ - sc->sc_bulk_out_ep = -1; - sc->sc_bulk_out_pipe = NULL; - sc->sc_bulk_out_xfer = NULL; - sc->sc_bulk_out_buffer = NULL; + /* bulk-out pipe */ NG_BT_MBUFQ_INIT(&sc->sc_aclq, UBT_DEFAULT_QLEN); - /* Isoc-in pipe */ - sc->sc_isoc_in_ep = -1; - sc->sc_isoc_in_pipe = NULL; - sc->sc_isoc_in_xfer = NULL; + /* isoc-out pipe */ + NG_BT_MBUFQ_INIT(&sc->sc_scoq, + (usbd_get_speed(uaa->device) == USB_SPEED_HIGH) ? + (2 * UBT_ISOC_NFRAMES * 8) : + (2 * UBT_ISOC_NFRAMES)); - /* Isoc-out pipe */ - sc->sc_isoc_out_ep = -1; - sc->sc_isoc_out_pipe = NULL; - sc->sc_isoc_out_xfer = NULL; - sc->sc_isoc_size = -1; - NG_BT_MBUFQ_INIT(&sc->sc_scoq, UBT_DEFAULT_QLEN); + /* isoc-in pipe */ + NG_BT_MBUFQ_INIT(&sc->sc_sciq, + (usbd_get_speed(uaa->device) == USB_SPEED_HIGH) ? + (2 * UBT_ISOC_NFRAMES * 8) : + (2 * UBT_ISOC_NFRAMES)); - /* Netgraph part */ + /* netgraph part */ sc->sc_node = NULL; sc->sc_hook = NULL; - /* - * XXX set configuration? - * - * Configure Bluetooth USB device. Discover all required USB interfaces - * and endpoints. + /* + * Configure Bluetooth USB device. Discover all required USB + * interfaces and endpoints. * * USB device must present two interfaces: * 1) Interface 0 that has 3 endpoints @@ -400,1405 +549,812 @@ * Interface 0 */ - error = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface0); - if (error || sc->sc_iface0 == NULL) { - printf("%s: Could not get interface 0 handle. %s (%d), " \ - "handle=%p\n", USBDEVNAME(sc->sc_dev), - usbd_errstr(error), error, sc->sc_iface0); - goto bad; - } + mtx_init(&(sc->sc_mtx), "ubt lock", NULL, MTX_DEF|MTX_RECURSE); - id = usbd_get_interface_descriptor(sc->sc_iface0); - if (id == NULL) { - printf("%s: Could not get interface 0 descriptor\n", - USBDEVNAME(sc->sc_dev)); - goto bad; + if(usbd_transfer_setup + (uaa->device, 0, + sc->sc_xfer_if_0, ubt_config_if_0, UBT_IF_0_N_TRANSFER, + sc, &(sc->sc_mtx), &(sc->sc_mem_wait))) { + goto detach; } - for (i = 0; i < id->bNumEndpoints; i ++) { - ed = usbd_interface2endpoint_descriptor(sc->sc_iface0, i); - if (ed == NULL) { - printf("%s: Could not read endpoint descriptor for " \ - "interface 0, i=%d\n", USBDEVNAME(sc->sc_dev), - i); - goto bad; - } - - switch (UE_GET_XFERTYPE(ed->bmAttributes)) { - case UE_BULK: - if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) - sc->sc_bulk_in_ep = ed->bEndpointAddress; - else - sc->sc_bulk_out_ep = ed->bEndpointAddress; - break; - - case UE_INTERRUPT: - sc->sc_intr_ep = ed->bEndpointAddress; - break; - } - } - - /* Check if we got everything we wanted on Interface 0 */ - if (sc->sc_intr_ep == -1) { - printf("%s: Could not detect interrupt endpoint\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - if (sc->sc_bulk_in_ep == -1) { - printf("%s: Could not detect bulk-in endpoint\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - if (sc->sc_bulk_out_ep == -1) { - printf("%s: Could not detect bulk-out endpoint\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - - printf("%s: Interface 0 endpoints: interrupt=%#x, bulk-in=%#x, " \ - "bulk-out=%#x\n", USBDEVNAME(sc->sc_dev), - sc->sc_intr_ep, sc->sc_bulk_in_ep, sc->sc_bulk_out_ep); - /* - * Interface 1 + * Interface 1 (search alternate settings) */ - cd = usbd_get_config_descriptor(sc->sc_udev); - if (cd == NULL) { - printf("%s: Could not get device configuration descriptor\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } + for (i = 0; ; i++) { - error = usbd_device2interface_handle(sc->sc_udev, 1, &sc->sc_iface1); - if (error || sc->sc_iface1 == NULL) { - printf("%s: Could not get interface 1 handle. %s (%d), " \ - "handle=%p\n", USBDEVNAME(sc->sc_dev), - usbd_errstr(error), error, sc->sc_iface1); - goto bad; - } + if (usbreq_set_interface(uaa->device, 1, i)) { + break; + } - id = usbd_get_interface_descriptor(sc->sc_iface1); - if (id == NULL) { - printf("%s: Could not get interface 1 descriptor\n", - USBDEVNAME(sc->sc_dev)); - goto bad; + if(usbd_transfer_setup + (uaa->device, 1, + sc->sc_xfer_if_1, + (usbd_get_speed(uaa->device) == USB_SPEED_HIGH) ? + ubt_config_if_1_high_speed : + ubt_config_if_1_full_speed, UBT_IF_1_N_TRANSFER, + sc, &(sc->sc_mtx), &(sc->sc_mem_wait)) == 0) { + goto found; + } } - /* - * Scan all alternate configurations for interface 1 - */ + goto detach; - alt_no = -1; + found: - for (ai = 0; ai < usbd_get_no_alts(cd, 1); ai++) { - error = usbd_set_interface(sc->sc_iface1, ai); - if (error) { - printf("%s: [SCAN] Could not set alternate " \ - "configuration %d for interface 1. %s (%d)\n", - USBDEVNAME(sc->sc_dev), ai, usbd_errstr(error), - error); - goto bad; - } - id = usbd_get_interface_descriptor(sc->sc_iface1); - if (id == NULL) { - printf("%s: Could not get interface 1 descriptor for " \ - "alternate configuration %d\n", - USBDEVNAME(sc->sc_dev), ai); - goto bad; - } - - isoc_in = isoc_out = -1; - isoc_isize = isoc_osize = 0; - - for (i = 0; i < id->bNumEndpoints; i ++) { - ed = usbd_interface2endpoint_descriptor(sc->sc_iface1, i); - if (ed == NULL) { - printf("%s: Could not read endpoint " \ - "descriptor for interface 1, " \ - "alternate configuration %d, i=%d\n", - USBDEVNAME(sc->sc_dev), ai, i); - goto bad; - } - - if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS) - continue; - - if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) { - isoc_in = ed->bEndpointAddress; - isoc_isize = UGETW(ed->wMaxPacketSize); - } else { - isoc_out = ed->bEndpointAddress; - isoc_osize = UGETW(ed->wMaxPacketSize); - } - } + /* create Netgraph node */ - /* - * Make sure that configuration looks sane and if so - * update current settings - */ - - if (isoc_in != -1 && isoc_out != -1 && - isoc_isize > 0 && isoc_osize > 0 && - isoc_isize == isoc_osize && isoc_isize > sc->sc_isoc_size) { - sc->sc_isoc_in_ep = isoc_in; - sc->sc_isoc_out_ep = isoc_out; - sc->sc_isoc_size = isoc_isize; - alt_no = ai; - } - } - - /* Check if we got everything we wanted on Interface 0 */ - if (sc->sc_isoc_in_ep == -1) { - printf("%s: Could not detect isoc-in endpoint\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - if (sc->sc_isoc_out_ep == -1) { - printf("%s: Could not detect isoc-out endpoint\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - if (sc->sc_isoc_size <= 0) { - printf("%s: Invalid isoc. packet size=%d\n", - USBDEVNAME(sc->sc_dev), sc->sc_isoc_size); - goto bad; - } - - error = usbd_set_interface(sc->sc_iface1, alt_no); - if (error) { - printf("%s: Could not set alternate configuration " \ - "%d for interface 1. %s (%d)\n", USBDEVNAME(sc->sc_dev), - alt_no, usbd_errstr(error), error); - goto bad; - } - - /* Allocate USB transfer handles and buffers */ - sc->sc_ctrl_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_ctrl_xfer == NULL) { - printf("%s: Could not allocate control xfer handle\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - sc->sc_ctrl_buffer = usbd_alloc_buffer(sc->sc_ctrl_xfer, - UBT_CTRL_BUFFER_SIZE); - if (sc->sc_ctrl_buffer == NULL) { - printf("%s: Could not allocate control buffer\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - - sc->sc_intr_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_intr_xfer == NULL) { - printf("%s: Could not allocate interrupt xfer handle\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - - sc->sc_bulk_in_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_bulk_in_xfer == NULL) { - printf("%s: Could not allocate bulk-in xfer handle\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - - sc->sc_bulk_out_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_bulk_out_xfer == NULL) { - printf("%s: Could not allocate bulk-out xfer handle\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - sc->sc_bulk_out_buffer = usbd_alloc_buffer(sc->sc_bulk_out_xfer, - UBT_BULK_BUFFER_SIZE); - if (sc->sc_bulk_out_buffer == NULL) { - printf("%s: Could not allocate bulk-out buffer\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - - /* - * Allocate buffers for isoc. transfers - */ - - sc->sc_isoc_nframes = (UBT_ISOC_BUFFER_SIZE / sc->sc_isoc_size) + 1; - - sc->sc_isoc_in_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_isoc_in_xfer == NULL) { - printf("%s: Could not allocate isoc-in xfer handle\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - sc->sc_isoc_in_buffer = usbd_alloc_buffer(sc->sc_isoc_in_xfer, - sc->sc_isoc_nframes * sc->sc_isoc_size); - if (sc->sc_isoc_in_buffer == NULL) { - printf("%s: Could not allocate isoc-in buffer\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - sc->sc_isoc_in_frlen = malloc(sizeof(u_int16_t) * sc->sc_isoc_nframes, - M_USBDEV, M_NOWAIT); - if (sc->sc_isoc_in_frlen == NULL) { - printf("%s: Could not allocate isoc-in frame sizes buffer\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - - sc->sc_isoc_out_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_isoc_out_xfer == NULL) { - printf("%s: Could not allocate isoc-out xfer handle\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - sc->sc_isoc_out_buffer = usbd_alloc_buffer(sc->sc_isoc_out_xfer, - sc->sc_isoc_nframes * sc->sc_isoc_size); - if (sc->sc_isoc_out_buffer == NULL) { - printf("%s: Could not allocate isoc-out buffer\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - sc->sc_isoc_out_frlen = malloc(sizeof(u_int16_t) * sc->sc_isoc_nframes, - M_USBDEV, M_NOWAIT); - if (sc->sc_isoc_out_frlen == NULL) { - printf("%s: Could not allocate isoc-out frame sizes buffer\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - - printf("%s: Interface 1 (alt.config %d) endpoints: isoc-in=%#x, " \ - "isoc-out=%#x; wMaxPacketSize=%d; nframes=%d, buffer size=%d\n", - USBDEVNAME(sc->sc_dev), alt_no, sc->sc_isoc_in_ep, - sc->sc_isoc_out_ep, sc->sc_isoc_size, sc->sc_isoc_nframes, - (sc->sc_isoc_nframes * sc->sc_isoc_size)); - - /* - * Open pipes - */ - - /* Interrupt */ - error = usbd_open_pipe(sc->sc_iface0, sc->sc_intr_ep, - USBD_EXCLUSIVE_USE, &sc->sc_intr_pipe); - if (error != USBD_NORMAL_COMPLETION) { - printf("%s: %s - Could not open interrupt pipe. %s (%d)\n", - __func__, USBDEVNAME(sc->sc_dev), usbd_errstr(error), - error); - goto bad; - } - - /* Bulk-in */ - error = usbd_open_pipe(sc->sc_iface0, sc->sc_bulk_in_ep, - USBD_EXCLUSIVE_USE, &sc->sc_bulk_in_pipe); - if (error != USBD_NORMAL_COMPLETION) { - printf("%s: %s - Could not open bulk-in pipe. %s (%d)\n", - __func__, USBDEVNAME(sc->sc_dev), usbd_errstr(error), - error); - goto bad; - } - - /* Bulk-out */ - error = usbd_open_pipe(sc->sc_iface0, sc->sc_bulk_out_ep, - USBD_EXCLUSIVE_USE, &sc->sc_bulk_out_pipe); - if (error != USBD_NORMAL_COMPLETION) { - printf("%s: %s - Could not open bulk-out pipe. %s (%d)\n", - __func__, USBDEVNAME(sc->sc_dev), usbd_errstr(error), - error); - goto bad; - } - -#if 0 /* XXX FIXME */ - /* Isoc-in */ - error = usbd_open_pipe(sc->sc_iface1, sc->sc_isoc_in_ep, - USBD_EXCLUSIVE_USE, &sc->sc_isoc_in_pipe); - if (error != USBD_NORMAL_COMPLETION) { - printf("%s: %s - Could not open isoc-in pipe. %s (%d)\n", - __func__, USBDEVNAME(sc->sc_dev), usbd_errstr(error), - error); - goto bad; - } - - /* Isoc-out */ - error = usbd_open_pipe(sc->sc_iface1, sc->sc_isoc_out_ep, - USBD_EXCLUSIVE_USE, &sc->sc_isoc_out_pipe); - if (error != USBD_NORMAL_COMPLETION) { - printf("%s: %s - Could not open isoc-out pipe. %s (%d)\n", - __func__, USBDEVNAME(sc->sc_dev), usbd_errstr(error), - error); - goto bad; - } -#endif - - /* Create Netgraph node */ if (ng_make_node_common(&typestruct, &sc->sc_node) != 0) { printf("%s: Could not create Netgraph node\n", - USBDEVNAME(sc->sc_dev)); + sc->sc_name); sc->sc_node = NULL; - goto bad; + goto detach; } - /* Name node */ - if (ng_name_node(sc->sc_node, USBDEVNAME(sc->sc_dev)) != 0) { + /* name node */ + + if (ng_name_node(sc->sc_node, sc->sc_name) != 0) { printf("%s: Could not name Netgraph node\n", - USBDEVNAME(sc->sc_dev)); + sc->sc_name); NG_NODE_UNREF(sc->sc_node); sc->sc_node = NULL; - goto bad; + goto detach; } NG_NODE_SET_PRIVATE(sc->sc_node, sc); NG_NODE_FORCE_WRITER(sc->sc_node); - /* Claim all interfaces on the device */ - for (i = 0; i < uaa->nifaces; i++) - uaa->ifaces[i] = NULL; + /* claim all interfaces on the device */ + + for (i = 0; ; i++) { + + if (usbd_get_iface(uaa->device, i) == NULL) { + break; + } + + USBD_SET_IFACE_NO_PROBE(uaa->device, i); + } - usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, - USBDEV(sc->sc_dev)); + return 0; /* success */ - USB_ATTACH_SUCCESS_RETURN; -bad: >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607141433.k6EEXRl5094162>