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