PERFORCE change 101554 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Fri Jul 14 14:33:29 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=101554
Change 101554 by hselasky at 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) <<<
More information about the p4-projects
mailing list