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