Module Name: src
Committed By: skrll
Date: Mon May 30 06:54:17 UTC 2016
Modified Files:
src/sys/dev/usb [nick-nhusb]: ucom.c ucomvar.h umct.c
Log Message:
WIP ucom support for devices with interrupt endpoints like umct
To generate a diff of this commit:
cvs rdiff -u -r1.108.2.14 -r1.108.2.15 src/sys/dev/usb/ucom.c
cvs rdiff -u -r1.20.24.4 -r1.20.24.5 src/sys/dev/usb/ucomvar.h
cvs rdiff -u -r1.32.24.12 -r1.32.24.13 src/sys/dev/usb/umct.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/usb/ucom.c
diff -u src/sys/dev/usb/ucom.c:1.108.2.14 src/sys/dev/usb/ucom.c:1.108.2.15
--- src/sys/dev/usb/ucom.c:1.108.2.14 Sun May 29 08:44:31 2016
+++ src/sys/dev/usb/ucom.c Mon May 30 06:54:17 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: ucom.c,v 1.108.2.14 2016/05/29 08:44:31 skrll Exp $ */
+/* $NetBSD: ucom.c,v 1.108.2.15 2016/05/30 06:54:17 skrll Exp $ */
/*
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.108.2.14 2016/05/29 08:44:31 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.108.2.15 2016/05/30 06:54:17 skrll Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -158,6 +158,11 @@ struct ucom_softc {
SIMPLEQ_HEAD(, ucom_buffer) sc_obuff_free;
SIMPLEQ_HEAD(, ucom_buffer) sc_obuff_full;
+ struct usbd_pipe *sc_ipipe;
+ struct usbd_xfer *sc_ixfer;
+ struct usbd_pipe *sc_opipe;
+ struct usbd_xfer *sc_oxfer;
+
void *sc_si;
const struct ucom_methods *sc_methods;
@@ -224,7 +229,6 @@ static void ucom_break(struct ucom_softc
static void tiocm_to_ucom(struct ucom_softc *, u_long, int);
static int ucom_to_tiocm(struct ucom_softc *);
-static void ucomreadcb(struct usbd_xfer *, void *, usbd_status);
static void ucom_submit_write(struct ucom_softc *, struct ucom_buffer *);
static void ucom_write_status(struct ucom_softc *, struct ucom_buffer *,
usbd_status);
@@ -264,6 +268,9 @@ ucom_attach(device_t parent, device_t se
prop_dictionary_set_int32(device_properties(self), "port",
ucaa->ucaa_portno);
+ KASSERT(ucaa->ucaa_bulkin != -1 || (ucaa->ucaa_ipipe && ucaa->ucaa_ixfer));
+ KASSERT(ucaa->ucaa_bulkout != -1 || (ucaa->ucaa_opipe && ucaa->ucaa_oxfer));
+
sc->sc_dev = self;
sc->sc_udev = ucaa->ucaa_device;
sc->sc_iface = ucaa->ucaa_iface;
@@ -307,41 +314,57 @@ ucom_attach(device_t parent, device_t se
usbd_status err;
int error;
- /* Open the bulk pipes */
- err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe);
- if (err) {
- DPRINTF("open bulk in error (addr %d), err=%d",
- sc->sc_bulkin_no, err, 0, 0);
- error = EIO;
- goto fail_0;
- }
- err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
- if (err) {
- DPRINTF("open bulk out error (addr %d), err=%d",
- sc->sc_bulkout_no, err, 0, 0);
- error = EIO;
- goto fail_1;
+ if (sc->sc_bulkin_no != -1) {
+ /* Open the bulk pipes */
+ err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no,
+ USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe);
+ if (err) {
+ DPRINTF("open bulk in error (addr %d), err=%d",
+ sc->sc_bulkin_no, err, 0, 0);
+ error = EIO;
+ goto fail_0;
+ }
+ /* Allocate input buffers */
+ for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS];
+ ub++) {
+ error = usbd_create_xfer(sc->sc_bulkin_pipe,
+ sc->sc_ibufsizepad, USBD_SHORT_XFER_OK, 0,
+ &ub->ub_xfer);
+ if (error)
+ goto fail_1;
+ ub->ub_data = usbd_get_buffer(ub->ub_xfer);
+ }
+
}
- /* Allocate input buffers */
- for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS];
- ub++) {
- error = usbd_create_xfer(sc->sc_bulkin_pipe, sc->sc_ibufsizepad,
- USBD_SHORT_XFER_OK, 0, &ub->ub_xfer);
- if (error)
- goto fail_2;
- ub->ub_data = usbd_get_buffer(ub->ub_xfer);
+ if (sc->sc_bulkout_no != -1) {
+ err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no,
+ USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
+ if (err) {
+ DPRINTF("open bulk out error (addr %d), err=%d",
+ sc->sc_bulkout_no, err, 0, 0);
+ error = EIO;
+ goto fail_1;
+ }
+ for (ub = &sc->sc_obuff[0]; ub != &sc->sc_obuff[UCOM_OUT_BUFFS];
+ ub++) {
+ error = usbd_create_xfer(sc->sc_bulkout_pipe,
+ sc->sc_obufsize, 0, 0, &ub->ub_xfer);
+ if (error)
+ goto fail_2;
+ ub->ub_data = usbd_get_buffer(ub->ub_xfer);
+ SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_free, ub, ub_link);
+ }
}
- for (ub = &sc->sc_obuff[0]; ub != &sc->sc_obuff[UCOM_OUT_BUFFS];
- ub++) {
- error = usbd_create_xfer(sc->sc_bulkout_pipe, sc->sc_obufsize,
- 0, 0, &ub->ub_xfer);
- if (error)
- goto fail_2;
- ub->ub_data = usbd_get_buffer(ub->ub_xfer);
+ if (sc->sc_ipipe && sc->sc_ixfer) {
+ ub = &sc->sc_ibuff[0];
+ ub->ub_data = usbd_get_buffer(sc->sc_ixfer);
+ SIMPLEQ_INSERT_TAIL(&sc->sc_ibuff_empty, ub, ub_link);
+ }
+ if (sc->sc_opipe && sc->sc_oxfer) {
+ ub = &sc->sc_obuff[0];
+ ub->ub_data = usbd_get_buffer(sc->sc_oxfer);
SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_free, ub, ub_link);
}
@@ -362,18 +385,20 @@ ucom_attach(device_t parent, device_t se
return;
fail_2:
- for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS];
+ for (ub = &sc->sc_obuff[0]; ub != &sc->sc_obuff[UCOM_OUT_BUFFS];
ub++) {
if (ub->ub_xfer)
usbd_destroy_xfer(ub->ub_xfer);
}
- for (ub = &sc->sc_obuff[0]; ub != &sc->sc_obuff[UCOM_OUT_BUFFS];
+
+ usbd_close_pipe(sc->sc_bulkout_pipe);
+
+fail_1:
+ for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS];
ub++) {
if (ub->ub_xfer)
usbd_destroy_xfer(ub->ub_xfer);
}
-
-fail_1:
usbd_close_pipe(sc->sc_bulkin_pipe);
fail_0:
@@ -620,6 +645,9 @@ ucomopen(dev_t dev, int flag, int mode,
sc->sc_rx_stopped = 0;
sc->sc_tx_stopped = 0;
+ /*
+ * ucomsubmitread handles bulk vs other
+ */
for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS];
ub++) {
if (ucomsubmitread(sc, ub) != USBD_NORMAL_COMPLETION) {
@@ -643,8 +671,10 @@ ucomopen(dev_t dev, int flag, int mode,
return 0;
fail_2:
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- usbd_abort_pipe(sc->sc_bulkout_pipe);
+ if (sc->sc_bulkin_no != -1)
+ usbd_abort_pipe(sc->sc_bulkin_pipe);
+ if (sc->sc_bulkout_no != -1)
+ usbd_abort_pipe(sc->sc_bulkout_pipe);
mutex_enter(&sc->sc_lock);
sc->sc_opening = 0;
@@ -1381,13 +1411,15 @@ ucomsubmitread(struct ucom_softc *sc, st
{
usbd_status err;
- usbd_setup_xfer(ub->ub_xfer, sc, ub->ub_data, sc->sc_ibufsize,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ucomreadcb);
-
- if ((err = usbd_transfer(ub->ub_xfer)) != USBD_IN_PROGRESS) {
- /* XXX: Recover from this, please! */
- printf("ucomsubmitread: err=%s\n", usbd_errstr(err));
- return err;
+ if (sc->sc_bulkin_no != -1) {
+ usbd_setup_xfer(ub->ub_xfer, sc, ub->ub_data, sc->sc_ibufsize,
+ USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ucomreadcb);
+
+ if ((err = usbd_transfer(ub->ub_xfer)) != USBD_IN_PROGRESS) {
+ /* XXX: Recover from this, please! */
+ printf("%s: err=%s\n", __func__, usbd_errstr(err));
+ return err;
+ }
}
SIMPLEQ_INSERT_TAIL(&sc->sc_ibuff_empty, ub, ub_link);
@@ -1395,7 +1427,7 @@ ucomsubmitread(struct ucom_softc *sc, st
return USBD_NORMAL_COMPLETION;
}
-static void
+void
ucomreadcb(struct usbd_xfer *xfer, void *p, usbd_status status)
{
struct ucom_softc *sc = (struct ucom_softc *)p;
@@ -1426,7 +1458,10 @@ ucomreadcb(struct usbd_xfer *xfer, void
SIMPLEQ_REMOVE_HEAD(&sc->sc_ibuff_empty, ub_link);
if (status == USBD_STALLED) {
- usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
+ if (sc->sc_bulkin_no != -1)
+ usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
+ if (sc->sc_ipipe)
+ usbd_clear_endpoint_stall_async(sc->sc_ipipe);
ucomsubmitread(sc, ub);
mutex_exit(&sc->sc_lock);
return;
Index: src/sys/dev/usb/ucomvar.h
diff -u src/sys/dev/usb/ucomvar.h:1.20.24.4 src/sys/dev/usb/ucomvar.h:1.20.24.5
--- src/sys/dev/usb/ucomvar.h:1.20.24.4 Sat Apr 16 13:22:00 2016
+++ src/sys/dev/usb/ucomvar.h Mon May 30 06:54:17 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: ucomvar.h,v 1.20.24.4 2016/04/16 13:22:00 skrll Exp $ */
+/* $NetBSD: ucomvar.h,v 1.20.24.5 2016/05/30 06:54:17 skrll Exp $ */
/*
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -93,6 +93,10 @@ struct ucom_attach_args {
int ucaa_portno;
int ucaa_bulkin;
int ucaa_bulkout;
+ struct usbd_xfer *ucaa_ixfer;
+ struct usbd_pipe *ucaa_ipipe;
+ struct usbd_xfer *ucaa_oxfer;
+ struct usbd_pipe *ucaa_opipe;
u_int ucaa_ibufsize;
u_int ucaa_ibufsizepad;
u_int ucaa_obufsize;
@@ -107,3 +111,5 @@ struct ucom_attach_args {
int ucomprint(void *, const char *);
int ucomsubmatch(device_t t, cfdata_t, const int *, void *);
void ucom_status_change(struct ucom_softc *);
+void ucomreadcb(struct usbd_xfer *, void *, usbd_status);
+
Index: src/sys/dev/usb/umct.c
diff -u src/sys/dev/usb/umct.c:1.32.24.12 src/sys/dev/usb/umct.c:1.32.24.13
--- src/sys/dev/usb/umct.c:1.32.24.12 Sat Apr 16 13:30:35 2016
+++ src/sys/dev/usb/umct.c Mon May 30 06:54:17 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: umct.c,v 1.32.24.12 2016/04/16 13:30:35 skrll Exp $ */
+/* $NetBSD: umct.c,v 1.32.24.13 2016/05/30 06:54:17 skrll Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umct.c,v 1.32.24.12 2016/04/16 13:30:35 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umct.c,v 1.32.24.13 2016/05/30 06:54:17 skrll Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -74,13 +74,17 @@ int umctdebug = 0;
struct umct_softc {
device_t sc_dev; /* base device */
- struct usbd_device * sc_udev; /* USB device */
- struct usbd_interface * sc_iface; /* interface */
+ struct usbd_device *sc_udev; /* USB device */
+ struct usbd_interface *sc_iface; /* interface */
int sc_iface_number; /* interface number */
uint16_t sc_product;
+ int sc_inendpt; /* data in endpoint */
+ struct usbd_pipe *sc_inpipe; /* data in pipe */
+ u_char *sc_inbuf; /* interrupt buffer */
+
int sc_intr_number; /* interrupt number */
- struct usbd_pipe * sc_intr_pipe; /* interrupt pipe */
+ struct usbd_pipe *sc_intr_pipe; /* interrupt pipe */
u_char *sc_intr_buf; /* interrupt buffer */
int sc_isize;
@@ -113,6 +117,8 @@ Static void umct_set_baudrate(struct umc
Static void umct_set_lcr(struct umct_softc *, u_int);
Static void umct_intr(struct usbd_xfer *, void *, usbd_status);
+Static void umct_rxintr(struct usbd_xfer *, void *, usbd_status);
+
Static void umct_set(void *, int, int, int);
Static void umct_dtr(struct umct_softc *, int);
Static void umct_rts(struct umct_softc *, int);
@@ -242,14 +248,15 @@ umct_attach(device_t parent, device_t se
}
/*
- * The Bulkin endpoint is marked as an interrupt. Since
+ * Input is done via an interrupt endpoint, so we handle
+ * the pipe and pass RX characters up to ucom. Since
* we can't rely on the endpoint descriptor order, we'll
* check the wMaxPacketSize field to differentiate.
*/
if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT &&
UGETW(ed->wMaxPacketSize) != 0x2) {
- ucaa.ucaa_bulkin = ed->bEndpointAddress;
+ sc->sc_inendpt = ed->bEndpointAddress;
} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
ucaa.ucaa_bulkout = ed->bEndpointAddress;
@@ -260,8 +267,8 @@ umct_attach(device_t parent, device_t se
}
}
- if (ucaa.ucaa_bulkin == -1) {
- aprint_error_dev(self, "Could not find data bulk in\n");
+ if (sc->sc_inendpt == -1) {
+ aprint_error_dev(self, "Could not find data in\n");
sc->sc_dying = 1;
return;
}
@@ -278,6 +285,16 @@ umct_attach(device_t parent, device_t se
return;
}
+ if (sc->sc_inendpt != -1) {
+ err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_inendpt,
+ USBD_SHORT_XFER_OK, &sc->sc_inpipe, sc, sc->sc_inbuf,
+ sc->sc_isize, umct_rxintr, USBD_DEFAULT_INTERVAL);
+ if (err) {
+ DPRINTF(("%s: cannot open interrupt pipe (addr %d)\n",
+ device_xname(sc->sc_dev), sc->sc_inendpt));
+ return EIO;
+ }
+ }
sc->sc_dtr = sc->sc_rts = 0;
ucaa.ucaa_portno = UCOM_UNK_PORTNO;
/* ucaa_bulkin, ucaa_bulkout set above */
@@ -592,8 +609,18 @@ umct_close(void *addr, int portno)
}
void
-umct_intr(struct usbd_xfer *xfer, void *priv,
- usbd_status status)
+umct_rxintr(struct usbd_xfer *xfer, void *priv, usbd_status status)
+{
+ struct umct_softc *sc = priv;
+
+ if (sc->sc_dying)
+ return;
+
+ ucomreadcb(xfer, device_private(sc->sc_subdev), status);
+}
+
+void
+umct_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
{
struct umct_softc *sc = priv;
u_char *tbuf = sc->sc_intr_buf;