PERFORCE change 162950 for review

Marko Zec zec at FreeBSD.org
Thu May 28 17:13:12 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=162950

Change 162950 by zec at zec_amdx4 on 2009/05/28 17:13:07

	Fix mysterious misintergations.

Affected files ...

.. //depot/projects/vimage-commit/src/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_var.h#5 edit
.. //depot/projects/vimage-commit/src/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c#6 edit

Differences ...

==== //depot/projects/vimage-commit/src/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_var.h#5 (text+ko) ====

@@ -3,7 +3,7 @@
  */
 
 /*-
- * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin at yahoo.com>
+ * Copyright (c) 2001-2009 Maksim Yevmenkin <m_evmenkin at yahoo.com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,123 +27,102 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: ng_ubt_var.h,v 1.5 2005/10/31 17:57:44 max Exp $
- * $FreeBSD: src/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_var.h,v 1.8 2008/07/11 17:13:43 emax Exp $
+ * $Id: ng_ubt_var.h,v 1.2 2003/03/22 23:44:36 max Exp $
+ * $FreeBSD: src/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_var.h,v 1.10 2009/05/27 16:34:08 thompsa Exp $
  */
 
 #ifndef _NG_UBT_VAR_H_
-#define _NG_UBT_VAR_H_
+#define	_NG_UBT_VAR_H_	1
+
+/* Debug printf's */
+#define	UBT_DEBUG(level, sc, fmt, ...)				\
+do {								\
+	if ((sc)->sc_debug >= (level))				\
+		device_printf((sc)->sc_dev, "%s:%d: " fmt, 	\
+			__FUNCTION__, __LINE__,## __VA_ARGS__);	\
+} while (0)
 
-/* pullup wrapper */
-#define NG_UBT_M_PULLUP(m, s) \
-	do { \
-		if ((m)->m_len < (s)) \
-			(m) = m_pullup((m), (s)); \
-		if ((m) == NULL) \
-			NG_UBT_ALERT("%s: %s - m_pullup(%d) failed\n", \
-				__func__, device_get_nameunit(sc->sc_dev), (s)); \
-	} while (0)
+#define	UBT_ALERT(...)		UBT_DEBUG(NG_UBT_ALERT_LEVEL, __VA_ARGS__)
+#define	UBT_ERR(...)		UBT_DEBUG(NG_UBT_ERR_LEVEL, __VA_ARGS__)
+#define	UBT_WARN(...)		UBT_DEBUG(NG_UBT_WARN_LEVEL, __VA_ARGS__)
+#define	UBT_INFO(...)		UBT_DEBUG(NG_UBT_INFO_LEVEL, __VA_ARGS__)
 
-/* Debug printf's */
-#define NG_UBT_ALERT	if (sc->sc_debug >= NG_UBT_ALERT_LEVEL) printf
-#define NG_UBT_ERR	if (sc->sc_debug >= NG_UBT_ERR_LEVEL)   printf
-#define NG_UBT_WARN	if (sc->sc_debug >= NG_UBT_WARN_LEVEL)  printf
-#define NG_UBT_INFO	if (sc->sc_debug >= NG_UBT_INFO_LEVEL)  printf
+#define UBT_NG_LOCK(sc)		mtx_lock(&(sc)->sc_ng_mtx)
+#define UBT_NG_UNLOCK(sc)	mtx_unlock(&(sc)->sc_ng_mtx)
 
 /* Bluetooth USB control request type */
-#define UBT_HCI_REQUEST		0x20
-#define UBT_DEFAULT_QLEN	12
+#define	UBT_HCI_REQUEST		0x20
+#define	UBT_DEFAULT_QLEN	64
+#define	UBT_ISOC_NFRAMES	32	/* should be factor of 8 */
 
-/* Isoc transfers */
-#define NG_UBT_NXFERS		3	/* max xfers to queue */
-#define NG_UBT_NFRAMES		10	/* frames per xfer */
+/* Bluetooth USB defines */
+enum {
+	/* Interface #0 transfers */
+	UBT_IF_0_BULK_DT_WR = 0,
+	UBT_IF_0_BULK_DT_RD,
+	UBT_IF_0_INTR_DT_RD,
+	UBT_IF_0_CTRL_DT_WR,
+	
+	/* Interface #1 transfers */
+	UBT_IF_1_ISOC_DT_RD1,
+	UBT_IF_1_ISOC_DT_RD2,
+	UBT_IF_1_ISOC_DT_WR1,
+	UBT_IF_1_ISOC_DT_WR2,
 
-struct ubt_isoc_xfer {
-	usbd_xfer_handle	 xfer;		/* isoc xfer */
-	void			*buffer;	/* isoc buffer */
- 	uint16_t		*frlen;		/* isoc frame length */
-	int			 active;	/* is xfer active */
+	UBT_N_TRANSFER,		/* total number of transfers */
 };
-typedef struct ubt_isoc_xfer	ubt_isoc_xfer_t;
-typedef struct ubt_isoc_xfer *	ubt_isoc_xfer_p;
 
 /* USB device softc structure */
 struct ubt_softc {
+	device_t		sc_dev;		/* for debug printf */
+
 	/* State */
-	ng_ubt_node_debug_ep	 sc_debug;	/* debug level */
-	uint32_t		 sc_flags;	/* device flags */
-#define UBT_NEED_FRAME_TYPE	(1 << 0)	/* device required frame type */
-#define UBT_HAVE_FRAME_TYPE UBT_NEED_FRAME_TYPE
-#define UBT_CMD_XMIT		(1 << 1)	/* CMD xmit in progress */
-#define UBT_ACL_XMIT		(1 << 2)	/* ACL xmit in progress */
-#define UBT_SCO_XMIT		(1 << 3)	/* SCO xmit in progress */
-#define UBT_EVT_RECV		(1 << 4)	/* EVN recv in progress */
-#define UBT_ACL_RECV		(1 << 5)	/* ACL recv in progress */
-#define UBT_SCO_RECV		(1 << 6)	/* SCO recv in progress */
+	ng_ubt_node_debug_ep	sc_debug;	/* debug level */
 
-	ng_ubt_node_stat_ep	 sc_stat;	/* statistic */
-#define NG_UBT_STAT_PCKTS_SENT(s)	(s).pckts_sent ++
-#define NG_UBT_STAT_BYTES_SENT(s, n)	(s).bytes_sent += (n)
-#define NG_UBT_STAT_PCKTS_RECV(s)	(s).pckts_recv ++
-#define NG_UBT_STAT_BYTES_RECV(s, n)	(s).bytes_recv += (n)
-#define NG_UBT_STAT_OERROR(s)		(s).oerrors ++
-#define NG_UBT_STAT_IERROR(s)		(s).ierrors ++
-#define NG_UBT_STAT_RESET(s)		bzero(&(s), sizeof((s)))
+	ng_ubt_node_stat_ep	sc_stat;	/* statistic */
+#define	UBT_STAT_PCKTS_SENT(sc)		(sc)->sc_stat.pckts_sent ++
+#define	UBT_STAT_BYTES_SENT(sc, n)	(sc)->sc_stat.bytes_sent += (n)
+#define	UBT_STAT_PCKTS_RECV(sc)		(sc)->sc_stat.pckts_recv ++
+#define	UBT_STAT_BYTES_RECV(sc, n)	(sc)->sc_stat.bytes_recv += (n)
+#define	UBT_STAT_OERROR(sc)		(sc)->sc_stat.oerrors ++
+#define	UBT_STAT_IERROR(sc)		(sc)->sc_stat.ierrors ++
+#define	UBT_STAT_RESET(sc)	bzero(&(sc)->sc_stat, sizeof((sc)->sc_stat))
 
 	/* USB device specific */
-	device_t		 sc_dev;	/* pointer back to USB device */
-	usbd_device_handle	 sc_udev;	/* USB device handle */
+	struct mtx		sc_if_mtx;	/* interfaces lock */
+	struct usb2_xfer	*sc_xfer[UBT_N_TRANSFER];
 
-	usbd_interface_handle	 sc_iface0;	/* USB interface 0 */
-	usbd_interface_handle	 sc_iface1;	/* USB interface 1 */
+	struct mtx		sc_ng_mtx;	/* lock for shared NG data */
 
-	/* Interrupt pipe (HCI events) */
-	int			 sc_intr_ep;	/* interrupt endpoint */
-	usbd_pipe_handle	 sc_intr_pipe;	/* interrupt pipe handle */
-	usbd_xfer_handle	 sc_intr_xfer;	/* intr xfer */
-	struct mbuf		*sc_intr_buffer; /* interrupt buffer */
+	/* HCI commands */
+	struct ng_bt_mbufq	sc_cmdq;	/* HCI command queue */
+#define	UBT_CTRL_BUFFER_SIZE	(sizeof(struct usb2_device_request) +	\
+				 sizeof(ng_hci_cmd_pkt_t) + NG_HCI_CMD_PKT_SIZE)
+#define	UBT_INTR_BUFFER_SIZE	(MCLBYTES-1)	/* reserve 1 byte for ID-tag */
 
-	/* Control pipe (HCI commands) */
-	usbd_xfer_handle	 sc_ctrl_xfer;	/* control xfer handle */
-	void			*sc_ctrl_buffer; /* control buffer */
-	struct ng_bt_mbufq	 sc_cmdq;	/* HCI command queue */
-#define UBT_CTRL_BUFFER_SIZE \
-		(sizeof(ng_hci_cmd_pkt_t) + NG_HCI_CMD_PKT_SIZE)
+	/* ACL data */
+	struct ng_bt_mbufq	sc_aclq;	/* ACL data queue */
+#define	UBT_BULK_READ_BUFFER_SIZE (MCLBYTES-1)	/* reserve 1 byte for ID-tag */
+#define	UBT_BULK_WRITE_BUFFER_SIZE (MCLBYTES)
 
-	/* Bulk in pipe (ACL data) */
-	int			 sc_bulk_in_ep;	/* bulk-in enpoint */
-	usbd_pipe_handle	 sc_bulk_in_pipe; /* bulk-in pipe */
-	usbd_xfer_handle	 sc_bulk_in_xfer; /* bulk-in xfer */
-	struct mbuf		*sc_bulk_in_buffer; /* bulk-in buffer */
+	/* SCO data */
+	struct ng_bt_mbufq	sc_scoq;	/* SCO data queue */
+	struct mbuf		*sc_isoc_in_buffer; /* SCO reassembly buffer */
 
-	/* Bulk out pipe (ACL data) */
-	int			 sc_bulk_out_ep; /* bulk-out endpoint */
-	usbd_pipe_handle	 sc_bulk_out_pipe; /* bulk-out pipe */
-	usbd_xfer_handle	 sc_bulk_out_xfer; /* bulk-out xfer */
-	void			*sc_bulk_out_buffer; /* bulk-out buffer */
-	struct ng_bt_mbufq	 sc_aclq;	/* ACL data queue */
-#define UBT_BULK_BUFFER_SIZE \
-		MCLBYTES /* XXX should be big enough to hold one frame */
+	/* Netgraph specific */
+	node_p			sc_node;	/* pointer back to node */
+	hook_p			sc_hook;	/* upstream hook */
 
-	/* Isoc. in pipe (SCO data) */
-	struct mbuf		*sc_isoc_in_buffer;
-	int			 sc_isoc_in_ep; /* isoc-in endpoint */
-	usbd_pipe_handle	 sc_isoc_in_pipe; /* isoc-in pipe */
-	ubt_isoc_xfer_t		 sc_isoc_in[NG_UBT_NXFERS]; /* isoc-in xfers */
+	/* Glue */
+	int			sc_task_flags;	/* task flags */
+#define UBT_FLAG_T_PENDING	(1 << 0)	/* task pending */
+#define UBT_FLAG_T_STOP_ALL	(1 << 1)	/* stop all xfers */
+#define UBT_FLAG_T_START_ALL	(1 << 2)	/* start all read and isoc
+						   write xfers */
+#define UBT_FLAG_T_START_CTRL	(1 << 3)	/* start control xfer (write) */
+#define UBT_FLAG_T_START_BULK	(1 << 4)	/* start bulk xfer (write) */
 
-	/* Isoc. out pipe (SCO data) */
-	int			 sc_isoc_out_ep; /* isoc-out endpoint */
-	usbd_pipe_handle	 sc_isoc_out_pipe; /* isoc-out pipe */
-	ubt_isoc_xfer_t		 sc_isoc_out[NG_UBT_NXFERS]; /* isoc-out xfers */
-	struct ng_bt_mbufq	 sc_scoq;	/* SCO data queue */
-
-	int			 sc_isoc_size; /* max. size of isoc. packet */
-#define UBT_ISOC_BUFFER_SIZE \
-		(sizeof(ng_hci_scodata_pkt_t) + NG_HCI_SCO_PKT_SIZE)
-	
-	/* Netgraph specific */
-	node_p			 sc_node;	/* pointer back to node */
-	hook_p			 sc_hook;	/* upstream hook */
+	struct task		sc_task;
 };
 typedef struct ubt_softc	ubt_softc_t;
 typedef struct ubt_softc *	ubt_softc_p;

==== //depot/projects/vimage-commit/src/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c#6 (text+ko) ====

@@ -3,7 +3,7 @@
  */
 
 /*-
- * Copyright (c) 2003 Maksim Yevmenkin <m_evmenkin at yahoo.com>
+ * Copyright (c) 2003-2009 Maksim Yevmenkin <m_evmenkin at yahoo.com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,489 +28,394 @@
  * SUCH DAMAGE.
  *
  * $Id: ubtbcmfw.c,v 1.3 2003/10/10 19:15:08 max Exp $
- * $FreeBSD: src/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c,v 1.20 2009/04/17 22:13:41 ed Exp $
+ * $FreeBSD: src/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c,v 1.22 2009/05/27 16:32:05 thompsa Exp $
  */
 
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/filio.h>
-#include <sys/fcntl.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/poll.h>
-#include <sys/proc.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
+#include "usbdevs.h"
+#include <dev/usb/usb.h>
+#include <dev/usb/usb_mfunc.h>
+#include <dev/usb/usb_error.h>
+#include <dev/usb/usb_ioctl.h>
 
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
+#define	USB_DEBUG_VAR usb2_debug
 
-#include "usbdevs.h"
+#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_mbuf.h>
+#include <dev/usb/usb_dev.h>
 
 /*
  * Download firmware to BCM2033.
  */
 
-#define UBTBCMFW_CONFIG_NO	1	/* Config number */
-#define UBTBCMFW_IFACE_IDX	0 	/* Control interface */
-#define UBTBCMFW_INTR_IN_EP	0x81	/* Fixed endpoint */
-#define UBTBCMFW_BULK_OUT_EP	0x02	/* Fixed endpoint */
-#define UBTBCMFW_INTR_IN	UE_GET_ADDR(UBTBCMFW_INTR_IN_EP)
-#define UBTBCMFW_BULK_OUT	UE_GET_ADDR(UBTBCMFW_BULK_OUT_EP)
+#define	UBTBCMFW_CONFIG_NO	1	/* Config number */
+#define	UBTBCMFW_IFACE_IDX	0	/* Control interface */
+
+#define	UBTBCMFW_BSIZE		1024
+#define	UBTBCMFW_IFQ_MAXLEN	2
+
+enum {
+	UBTBCMFW_BULK_DT_WR = 0,
+	UBTBCMFW_INTR_DT_RD,
+	UBTBCMFW_N_TRANSFER,
+};
 
 struct ubtbcmfw_softc {
-	device_t		sc_dev;			/* base device */
-	usbd_device_handle	sc_udev;		/* USB device handle */
-	struct cdev *sc_ctrl_dev;		/* control device */
-	struct cdev *sc_intr_in_dev;		/* interrupt device */
-	struct cdev *sc_bulk_out_dev;	/* bulk device */
-	usbd_pipe_handle	sc_intr_in_pipe;	/* interrupt pipe */
-	usbd_pipe_handle	sc_bulk_out_pipe;	/* bulk out pipe */
-	int			sc_flags;
-#define UBTBCMFW_CTRL_DEV	(1 << 0)
-#define UBTBCMFW_INTR_IN_DEV	(1 << 1)
-#define UBTBCMFW_BULK_OUT_DEV	(1 << 2)
-	int			sc_refcnt;
-	int			sc_dying;
+	struct usb2_device	*sc_udev;
+	struct mtx		sc_mtx;
+	struct usb2_xfer	*sc_xfer[UBTBCMFW_N_TRANSFER];
+	struct usb2_fifo_sc	sc_fifo;
 };
 
-typedef struct ubtbcmfw_softc	*ubtbcmfw_softc_p;
+/*
+ * Prototypes
+ */
+
+static device_probe_t		ubtbcmfw_probe;
+static device_attach_t		ubtbcmfw_attach;
+static device_detach_t		ubtbcmfw_detach;
+
+static usb2_callback_t		ubtbcmfw_write_callback;
+static usb2_callback_t		ubtbcmfw_read_callback;
+
+static usb2_fifo_close_t	ubtbcmfw_close;
+static usb2_fifo_cmd_t		ubtbcmfw_start_read;
+static usb2_fifo_cmd_t		ubtbcmfw_start_write;
+static usb2_fifo_cmd_t		ubtbcmfw_stop_read;
+static usb2_fifo_cmd_t		ubtbcmfw_stop_write;
+static usb2_fifo_ioctl_t	ubtbcmfw_ioctl;
+static usb2_fifo_open_t		ubtbcmfw_open;
+
+static struct usb2_fifo_methods	ubtbcmfw_fifo_methods = 
+{
+	.f_close =		&ubtbcmfw_close,
+	.f_ioctl =		&ubtbcmfw_ioctl,
+	.f_open =		&ubtbcmfw_open,
+	.f_start_read =		&ubtbcmfw_start_read,
+	.f_start_write =	&ubtbcmfw_start_write,
+	.f_stop_read =		&ubtbcmfw_stop_read,
+	.f_stop_write =		&ubtbcmfw_stop_write,
+	.basename[0] =		"ubtbcmfw",
+	.basename[1] =		"ubtbcmfw",
+	.basename[2] =		"ubtbcmfw",
+	.postfix[0] =		"",
+	.postfix[1] =		".1",
+	.postfix[2] =		".2",
+};
 
 /*
- * Device methods
+ * Device's config structure
  */
 
-#define UBTBCMFW_BSIZE		1024
+static const struct usb2_config	ubtbcmfw_config[UBTBCMFW_N_TRANSFER] =
+{
+	[UBTBCMFW_BULK_DT_WR] = {
+		.type =		UE_BULK,
+		.endpoint =	0x02,	/* fixed */
+		.direction =	UE_DIR_OUT,
+		.if_index =	UBTBCMFW_IFACE_IDX,
+		.bufsize =	UBTBCMFW_BSIZE,
+		.flags =	{ .pipe_bof = 1, .force_short_xfer = 1,
+				  .proxy_buffer = 1, },
+		.callback =	&ubtbcmfw_write_callback,
+	},
 
-static d_open_t		ubtbcmfw_open;
-static d_close_t	ubtbcmfw_close;
-static d_read_t		ubtbcmfw_read;
-static d_write_t	ubtbcmfw_write;
-static d_ioctl_t	ubtbcmfw_ioctl;
-static d_poll_t		ubtbcmfw_poll;
-
-static struct cdevsw	ubtbcmfw_cdevsw = {
-	.d_version =	D_VERSION,
-	.d_flags =	D_NEEDGIANT,
-	.d_open =	ubtbcmfw_open,
-	.d_close =	ubtbcmfw_close,
-	.d_read =	ubtbcmfw_read,
-	.d_write =	ubtbcmfw_write,
-	.d_ioctl =	ubtbcmfw_ioctl,
-	.d_poll =	ubtbcmfw_poll,
-	.d_name =	"ubtbcmfw",
+	[UBTBCMFW_INTR_DT_RD] = {
+		.type =		UE_INTERRUPT,
+		.endpoint =	0x01,	/* fixed */
+		.direction =	UE_DIR_IN,
+		.if_index =	UBTBCMFW_IFACE_IDX,
+		.bufsize =	UBTBCMFW_BSIZE,
+		.flags =	{ .pipe_bof = 1, .short_xfer_ok = 1,
+				  .proxy_buffer = 1, },
+		.callback =	&ubtbcmfw_read_callback,
+	},
 };
 
 /*
  * Module
  */
 
-static device_probe_t ubtbcmfw_match;
-static device_attach_t ubtbcmfw_attach;
-static device_detach_t ubtbcmfw_detach;
+static devclass_t	ubtbcmfw_devclass;
 
-static device_method_t ubtbcmfw_methods[] = {
-	/* Device interface */
-	DEVMETHOD(device_probe,		ubtbcmfw_match),
-	DEVMETHOD(device_attach,	ubtbcmfw_attach),
-	DEVMETHOD(device_detach,	ubtbcmfw_detach),
-
-	{ 0, 0 }
+static device_method_t	ubtbcmfw_methods[] =
+{
+	DEVMETHOD(device_probe, ubtbcmfw_probe),
+	DEVMETHOD(device_attach, ubtbcmfw_attach),
+	DEVMETHOD(device_detach, ubtbcmfw_detach),
+	{0, 0}
 };
 
-static driver_t ubtbcmfw_driver = {
-	"ubtbcmfw",
-	ubtbcmfw_methods,
-	sizeof(struct ubtbcmfw_softc)
+static driver_t		ubtbcmfw_driver =
+{
+	.name =		"ubtbcmfw",
+	.methods =	ubtbcmfw_methods,
+	.size =		sizeof(struct ubtbcmfw_softc),
 };
 
-static devclass_t ubtbcmfw_devclass;
-
+DRIVER_MODULE(ubtbcmfw, uhub, ubtbcmfw_driver, ubtbcmfw_devclass, NULL, 0);
 MODULE_DEPEND(ubtbcmfw, usb, 1, 1, 1);
-DRIVER_MODULE(ubtbcmfw, uhub, ubtbcmfw_driver, ubtbcmfw_devclass,
-	      usbd_driver_load, 0);
 
 /*
  * Probe for a USB Bluetooth device
  */
 
 static int
-ubtbcmfw_match(device_t self)
+ubtbcmfw_probe(device_t dev)
 {
-#define	USB_PRODUCT_BROADCOM_BCM2033NF	0x2033
-	struct usb_attach_arg *uaa = device_get_ivars(self);
+	const struct usb2_device_id	devs[] = {
+	/* Broadcom BCM2033 devices only */
+	{ USB_VPI(USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033, 0) },
+	};
+
+	struct usb2_attach_arg	*uaa = device_get_ivars(dev);
 
-	if (uaa->iface != NULL)
-		return (UMATCH_NONE);
+	if (uaa->usb_mode != USB_MODE_HOST)
+		return (ENXIO);
 
-	/* Match the boot device. */
-	if (uaa->vendor == USB_VENDOR_BROADCOM &&
-	    uaa->product == USB_PRODUCT_BROADCOM_BCM2033NF)
-		return (UMATCH_VENDOR_PRODUCT);
+	if (uaa->info.bIfaceIndex != 0)
+		return (ENXIO);
 
-	return (UMATCH_NONE);
-}
+	return (usb2_lookup_id_by_uaa(devs, sizeof(devs), uaa));
+} /* ubtbcmfw_probe */
 
 /*
  * Attach the device
  */
 
 static int
-ubtbcmfw_attach(device_t self)
+ubtbcmfw_attach(device_t dev)
 {
-	struct ubtbcmfw_softc *sc = device_get_softc(self);
-	struct usb_attach_arg *uaa = device_get_ivars(self);
-	usbd_interface_handle	iface;
-	usbd_status		err;
+	struct usb2_attach_arg	*uaa = device_get_ivars(dev);
+	struct ubtbcmfw_softc	*sc = device_get_softc(dev);
+	uint8_t			iface_index;
+	int			error;
 
-	sc->sc_dev = self;
 	sc->sc_udev = uaa->device;
 
-	sc->sc_ctrl_dev = sc->sc_intr_in_dev = sc->sc_bulk_out_dev = NULL;
-	sc->sc_intr_in_pipe = sc->sc_bulk_out_pipe = NULL;
-	sc->sc_flags = sc->sc_refcnt = sc->sc_dying = 0;
+	device_set_usb2_desc(dev);
 
-	err = usbd_set_config_no(sc->sc_udev, UBTBCMFW_CONFIG_NO, 1);
-	if (err) {
-		printf("%s: setting config no failed. %s\n",
-			device_get_nameunit(sc->sc_dev), usbd_errstr(err));
-		goto bad;
-	}
+	mtx_init(&sc->sc_mtx, "ubtbcmfw lock", NULL, MTX_DEF | MTX_RECURSE);
 
-	err = usbd_device2interface_handle(sc->sc_udev, UBTBCMFW_IFACE_IDX,
-			&iface);
-	if (err) {
-		printf("%s: getting interface handle failed. %s\n",
-			device_get_nameunit(sc->sc_dev), usbd_errstr(err));
-		goto bad;
+	iface_index = UBTBCMFW_IFACE_IDX;
+	error = usb2_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
+				ubtbcmfw_config, UBTBCMFW_N_TRANSFER,
+				sc, &sc->sc_mtx);
+	if (error != 0) {
+		device_printf(dev, "allocating USB transfers failed. %s\n",
+			usb2_errstr(error));
+		goto detach;
 	}
 
-	/* Will be used as a bulk pipe */
-	err = usbd_open_pipe(iface, UBTBCMFW_INTR_IN_EP, 0,
-			&sc->sc_intr_in_pipe);
-	if (err) {
-		printf("%s: open intr in failed. %s\n",
-			device_get_nameunit(sc->sc_dev), usbd_errstr(err));
-		goto bad;
+	error = usb2_fifo_attach(uaa->device, sc, &sc->sc_mtx,
+			&ubtbcmfw_fifo_methods, &sc->sc_fifo,
+			device_get_unit(dev), 0 - 1, uaa->info.bIfaceIndex,
+			UID_ROOT, GID_OPERATOR, 0644);
+	if (error != 0) {
+		device_printf(dev, "could not attach fifo. %s\n",
+			usb2_errstr(error));
+		goto detach;
 	}
 
-	err = usbd_open_pipe(iface, UBTBCMFW_BULK_OUT_EP, 0,
-			&sc->sc_bulk_out_pipe);
-	if (err) {
-		printf("%s: open bulk out failed. %s\n",
-			device_get_nameunit(sc->sc_dev), usbd_errstr(err));
-		goto bad;
-	}
+	return (0);	/* success */
 
-	/* Create device nodes */
-	sc->sc_ctrl_dev = make_dev(&ubtbcmfw_cdevsw,
-		0, UID_ROOT, GID_OPERATOR, 0644,
-		"%s", device_get_nameunit(sc->sc_dev));
-	sc->sc_ctrl_dev->si_drv1 = sc;
+detach:
+	ubtbcmfw_detach(dev);
 
-	sc->sc_intr_in_dev = make_dev(&ubtbcmfw_cdevsw,
-		UBTBCMFW_INTR_IN, UID_ROOT, GID_OPERATOR, 0644,
-		"%s.%d", device_get_nameunit(sc->sc_dev), UBTBCMFW_INTR_IN);
-	sc->sc_intr_in_dev->si_drv1 = sc;
-
-	sc->sc_bulk_out_dev = make_dev(&ubtbcmfw_cdevsw,
-		UBTBCMFW_BULK_OUT, UID_ROOT, GID_OPERATOR, 0644,
-		"%s.%d", device_get_nameunit(sc->sc_dev), UBTBCMFW_BULK_OUT);
-	sc->sc_bulk_out_dev->si_drv1 = sc;
-
-	return 0;
-bad:
-	ubtbcmfw_detach(self);  
-	return ENXIO;
-}
+	return (ENXIO);	/* failure */
+} /* ubtbcmfw_attach */ 
 
 /*
  * Detach the device
  */
 
 static int
-ubtbcmfw_detach(device_t self)
+ubtbcmfw_detach(device_t dev)
 {
-	struct ubtbcmfw_softc *sc = device_get_softc(self);
+	struct ubtbcmfw_softc	*sc = device_get_softc(dev);
 
-	sc->sc_dying = 1;
-	if (-- sc->sc_refcnt >= 0) {
-		if (sc->sc_intr_in_pipe != NULL) 
-			usbd_abort_pipe(sc->sc_intr_in_pipe);
+	usb2_fifo_detach(&sc->sc_fifo);
 
-		if (sc->sc_bulk_out_pipe != NULL) 
-			usbd_abort_pipe(sc->sc_bulk_out_pipe);
+	usb2_transfer_unsetup(sc->sc_xfer, UBTBCMFW_N_TRANSFER);
 
-		usb_detach_wait(sc->sc_dev);
-	}
-
-	/* Destroy device nodes */
-	if (sc->sc_bulk_out_dev != NULL) {
-		destroy_dev(sc->sc_bulk_out_dev);
-		sc->sc_bulk_out_dev = NULL;
-	}
-
-	if (sc->sc_intr_in_dev != NULL) {
-		destroy_dev(sc->sc_intr_in_dev);
-		sc->sc_intr_in_dev = NULL;
-	}
-
-	if (sc->sc_ctrl_dev != NULL) {
-		destroy_dev(sc->sc_ctrl_dev);
-		sc->sc_ctrl_dev = NULL;
-	}
-
-	/* Close pipes */
-	if (sc->sc_intr_in_pipe != NULL) {
-		usbd_close_pipe(sc->sc_intr_in_pipe);
-		sc->sc_intr_in_pipe = NULL;
-	}
-
-	if (sc->sc_bulk_out_pipe != NULL) {
-		usbd_close_pipe(sc->sc_bulk_out_pipe);
-		sc->sc_intr_in_pipe = NULL;
-	}
+	mtx_destroy(&sc->sc_mtx);
 
 	return (0);
-}
+} /* ubtbcmfw_detach */
 
 /*
- * Open endpoint device
- * XXX FIXME softc locking
+ * USB write callback
  */
 
-static int
-ubtbcmfw_open(struct cdev *dev, int flag, int mode, struct thread *p)
+static void
+ubtbcmfw_write_callback(struct usb2_xfer *xfer)
 {
-	ubtbcmfw_softc_p	sc = dev->si_drv1;
-	int			error = 0;
+	struct ubtbcmfw_softc	*sc = xfer->priv_sc;
+	struct usb2_fifo	*f = sc->sc_fifo.fp[USB_FIFO_TX];
+	uint32_t		actlen;
 
-	if (sc->sc_dying)
-		return (ENXIO);
-
-	switch (dev2unit(dev)) {
-	case USB_CONTROL_ENDPOINT:
-		if (!(sc->sc_flags & UBTBCMFW_CTRL_DEV))
-			sc->sc_flags |= UBTBCMFW_CTRL_DEV;
-		else
-			error = EBUSY;
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_SETUP:
+	case USB_ST_TRANSFERRED:
+setup_next:
+		if (usb2_fifo_get_data(f, xfer->frbuffers, 0,
+				xfer->max_data_length, &actlen, 0)) {
+			xfer->frlengths[0] = actlen;
+			usb2_start_hardware(xfer);
+		}
 		break;
 
-	case UBTBCMFW_INTR_IN:
-		if (!(sc->sc_flags & UBTBCMFW_INTR_IN_DEV)) {
-			if (sc->sc_intr_in_pipe != NULL)
-				sc->sc_flags |= UBTBCMFW_INTR_IN_DEV;
-			else
-				error = ENXIO;
-		} else
-			error = EBUSY;
+	default: /* Error */
+		if (xfer->error != USB_ERR_CANCELLED) {
+			/* try to clear stall first */
+			xfer->flags.stall_pipe = 1;
+			goto setup_next;
+		}
 		break;
-
-	case UBTBCMFW_BULK_OUT:
-		if (!(sc->sc_flags & UBTBCMFW_BULK_OUT_DEV)) {
-			if (sc->sc_bulk_out_pipe != NULL)
-				sc->sc_flags |= UBTBCMFW_BULK_OUT_DEV;
-			else
-				error = ENXIO;
-		} else
-			error = EBUSY;
-		break;
-
-	default:
-		error = ENXIO;
-		break;
 	}
+} /* ubtbcmfw_write_callback */
 
-	return (error);
-}
-
 /*
- * Close endpoint device
- * XXX FIXME softc locking
+ * USB read callback
  */
 
-static int
-ubtbcmfw_close(struct cdev *dev, int flag, int mode, struct thread *p)
+static void
+ubtbcmfw_read_callback(struct usb2_xfer *xfer)
 {
-	ubtbcmfw_softc_p	sc = dev->si_drv1;
+	struct ubtbcmfw_softc	*sc = xfer->priv_sc;
+	struct usb2_fifo	*fifo = sc->sc_fifo.fp[USB_FIFO_RX];
 
-	switch (dev2unit(dev)) {
-	case USB_CONTROL_ENDPOINT:
-		sc->sc_flags &= ~UBTBCMFW_CTRL_DEV;
-		break;
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		usb2_fifo_put_data(fifo, xfer->frbuffers, 0, xfer->actlen, 1);
+		/* FALLTHROUGH */
 
-	case UBTBCMFW_INTR_IN:
-		if (sc->sc_intr_in_pipe != NULL)
-			usbd_abort_pipe(sc->sc_intr_in_pipe);
-
-		sc->sc_flags &= ~UBTBCMFW_INTR_IN_DEV;
+	case USB_ST_SETUP:
+setup_next:
+		if (usb2_fifo_put_bytes_max(fifo) > 0) {
+			xfer->frlengths[0] = xfer->max_data_length;
+			usb2_start_hardware(xfer);
+		}
 		break;
 
-	case UBTBCMFW_BULK_OUT:
-		if (sc->sc_bulk_out_pipe != NULL)
-			usbd_abort_pipe(sc->sc_bulk_out_pipe);
-
-		sc->sc_flags &= ~UBTBCMFW_BULK_OUT_DEV;
+	default: /* Error */
+		if (xfer->error != USB_ERR_CANCELLED) {
+			/* try to clear stall first */
+			xfer->flags.stall_pipe = 1;
+			goto setup_next;
+		}
 		break;
 	}
+} /* ubtbcmfw_read_callback */
 
-	return (0);
-}
-
 /*
- * Read from the endpoint device
- * XXX FIXME softc locking
+ * Called when we about to start read()ing from the device
  */
 
-static int
-ubtbcmfw_read(struct cdev *dev, struct uio *uio, int flag)
+static void
+ubtbcmfw_start_read(struct usb2_fifo *fifo)
 {
-	ubtbcmfw_softc_p	sc = dev->si_drv1;
-	u_int8_t		buf[UBTBCMFW_BSIZE];
-	usbd_xfer_handle	xfer;
-	usbd_status		err;
-	int			n, tn, error = 0;
+	struct ubtbcmfw_softc	*sc = fifo->priv_sc0;
 
-	if (sc->sc_dying)
-		return (ENXIO);
+	usb2_transfer_start(sc->sc_xfer[UBTBCMFW_INTR_DT_RD]);
+} /* ubtbcmfw_start_read */
 
-	if (dev2unit(dev) != UBTBCMFW_INTR_IN)
-		return (EOPNOTSUPP);
-	if (sc->sc_intr_in_pipe == NULL)
-		return (ENXIO);
+/*
+ * Called when we about to stop reading (i.e. closing fifo)
+ */
 
-	xfer = usbd_alloc_xfer(sc->sc_udev);
-	if (xfer == NULL)
-		return (ENOMEM);
+static void
+ubtbcmfw_stop_read(struct usb2_fifo *fifo)
+{
+	struct ubtbcmfw_softc	*sc = fifo->priv_sc0;
 
-	sc->sc_refcnt ++;
+	usb2_transfer_stop(sc->sc_xfer[UBTBCMFW_INTR_DT_RD]);
+} /* ubtbcmfw_stop_read */
 
-	while ((n = min(sizeof(buf), uio->uio_resid)) != 0) {
-		tn = n;
-		err = usbd_bulk_transfer(xfer, sc->sc_intr_in_pipe,
-				USBD_SHORT_XFER_OK, USBD_DEFAULT_TIMEOUT,
-				buf, &tn, "bcmrd");
-		switch (err) {
-		case USBD_NORMAL_COMPLETION:
-			error = uiomove(buf, tn, uio);
-			break;
+/*
+ * Called when we about to start write()ing to the device, poll()ing
+ * for write or flushing fifo
+ */
 
-		case USBD_INTERRUPTED:
-			error = EINTR;
-			break;
+static void
+ubtbcmfw_start_write(struct usb2_fifo *fifo)
+{
+	struct ubtbcmfw_softc	*sc = fifo->priv_sc0;
 
-		case USBD_TIMEOUT:
-			error = ETIMEDOUT;
-			break;
+	usb2_transfer_start(sc->sc_xfer[UBTBCMFW_BULK_DT_WR]);
+} /* ubtbcmfw_start_write */
 
-		default:
-			error = EIO;
-			break;
-		}
+/*
+ * Called when we about to stop writing (i.e. closing fifo)
+ */
 
-		if (error != 0 || tn < n)
-			break;
-	}
+static void
+ubtbcmfw_stop_write(struct usb2_fifo *fifo)
+{
+	struct ubtbcmfw_softc	*sc = fifo->priv_sc0;
 
-	usbd_free_xfer(xfer);
+	usb2_transfer_stop(sc->sc_xfer[UBTBCMFW_BULK_DT_WR]);
+} /* ubtbcmfw_stop_write */
 
-	if (-- sc->sc_refcnt < 0)
-		usb_detach_wakeup(sc->sc_dev);
-
-	return (error);
-}
-
 /*
- * Write into the endpoint device
- * XXX FIXME softc locking
+ * Called when fifo is open
  */
 
 static int
-ubtbcmfw_write(struct cdev *dev, struct uio *uio, int flag)
+ubtbcmfw_open(struct usb2_fifo *fifo, int fflags)
 {
-	ubtbcmfw_softc_p	sc = dev->si_drv1;
-	u_int8_t		buf[UBTBCMFW_BSIZE];
-	usbd_xfer_handle	xfer;
-	usbd_status		err;
-	int			n, error = 0;
+	struct ubtbcmfw_softc	*sc = fifo->priv_sc0;
+	struct usb2_xfer	*xfer;
 
-	if (sc->sc_dying)
-		return (ENXIO);
+	/*
+	 * f_open fifo method can only be called with either FREAD
+	 * or FWRITE flag set at one time.
+	 */
 
-	if (dev2unit(dev) != UBTBCMFW_BULK_OUT)
-		return (EOPNOTSUPP);
-	if (sc->sc_bulk_out_pipe == NULL)
-		return (ENXIO);
+	if (fflags & FREAD)
+		xfer = sc->sc_xfer[UBTBCMFW_INTR_DT_RD];
+	else if (fflags & FWRITE)
+		xfer = sc->sc_xfer[UBTBCMFW_BULK_DT_WR];
+	else
+		return (EINVAL);	/* should not happen */
 
-	xfer = usbd_alloc_xfer(sc->sc_udev);
-	if (xfer == NULL)
+	if (usb2_fifo_alloc_buffer(fifo, xfer->max_data_length,
+			UBTBCMFW_IFQ_MAXLEN) != 0)
 		return (ENOMEM);
 
-	sc->sc_refcnt ++;
+	return (0);
+} /* ubtbcmfw_open */
 
-	while ((n = min(sizeof(buf), uio->uio_resid)) != 0) {
-		error = uiomove(buf, n, uio);
-		if (error != 0)
-			break;
+/* 
+ * Called when fifo is closed
+ */
 
-		err = usbd_bulk_transfer(xfer, sc->sc_bulk_out_pipe,
-				0, USBD_DEFAULT_TIMEOUT, buf, &n, "bcmwr");
-		switch (err) {
-		case USBD_NORMAL_COMPLETION:
-			break;
-
-		case USBD_INTERRUPTED:
-			error = EINTR;
-			break;
+static void
+ubtbcmfw_close(struct usb2_fifo *fifo, int fflags)
+{
+	if (fflags & (FREAD | FWRITE))
+		usb2_fifo_free_buffer(fifo);
+} /* ubtbcmfw_close */
 
-		case USBD_TIMEOUT:
-			error = ETIMEDOUT;
-			break;
-
-		default:
-			error = EIO;
-			break;
-		}
-
-		if (error != 0)
-			break;
-	}
-
-	usbd_free_xfer(xfer);
-
-	if (-- sc->sc_refcnt < 0)
-		usb_detach_wakeup(sc->sc_dev);
-
-	return (error);
-}
-
 /*
- * Process ioctl on the endpoint device
- * XXX FIXME softc locking
+ * Process ioctl() on USB device
  */
 
 static int
-ubtbcmfw_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
-  struct thread *p)
+ubtbcmfw_ioctl(struct usb2_fifo *fifo, u_long cmd, void *data,
+    int fflags)
 {
-	ubtbcmfw_softc_p	sc = dev->si_drv1;
+	struct ubtbcmfw_softc	*sc = fifo->priv_sc0;
 	int			error = 0;
 
-	if (sc->sc_dying)
-		return (ENXIO);
-
-	if (dev2unit(dev) != USB_CONTROL_ENDPOINT)
-		return (EOPNOTSUPP);
-
-	sc->sc_refcnt ++;
-
 	switch (cmd) {
 	case USB_GET_DEVICE_DESC:
-		*(usb_device_descriptor_t *) data =
-				*usbd_get_device_descriptor(sc->sc_udev);
+		memcpy(data, usb2_get_device_descriptor(sc->sc_udev),
+			sizeof(struct usb2_device_descriptor));
 		break;
 
 	default:
@@ -518,42 +423,5 @@
 		break;
 	}
 
-	if (-- sc->sc_refcnt < 0)
-		usb_detach_wakeup(sc->sc_dev);
-
 	return (error);
-}
-
-/*
- * Poll the endpoint device
- * XXX FIXME softc locking
- */
-
-static int
-ubtbcmfw_poll(struct cdev *dev, int events, struct thread *p)
-{
-	ubtbcmfw_softc_p	sc = dev->si_drv1;
-	int			revents = 0;
-

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list