Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Mar 2007 19:54:12 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 116960 for review
Message-ID:  <200703301954.l2UJsCR1080075@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=116960

Change 116960 by hselasky@hselasky_mini_itx on 2007/03/30 19:54:03

	This is a bigger cleanup in the UCOM layer. The goal is
	to create a context for all the callbacks so that they
	can call sleeping functions. This is achieved using
	the USB config thread system. The reason for this
	is that the code becomes simpler when synchronous
	operation is applied versus asynchronous. But
	asynchronous behaviour is the most secure, hence then 
	all USB resources are preallocated for each transfer.
	After the changes, only data transfers are done
	asynchronously. All configuration is now done synchronously.
	This makes the USB device drivers look more like in the old
	USB stack. Else some cleanup and bugfixes have been made.
	Please test!

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/ubsa.c#14 edit
.. //depot/projects/usb/src/sys/dev/usb/ubser.c#9 edit
.. //depot/projects/usb/src/sys/dev/usb/ucom.c#14 edit
.. //depot/projects/usb/src/sys/dev/usb/ucomvar.h#10 edit
.. //depot/projects/usb/src/sys/dev/usb/ucycom.c#9 edit
.. //depot/projects/usb/src/sys/dev/usb/ufoma.c#12 edit
.. //depot/projects/usb/src/sys/dev/usb/uftdi.c#13 edit
.. //depot/projects/usb/src/sys/dev/usb/umct.c#11 edit
.. //depot/projects/usb/src/sys/dev/usb/umodem.c#15 edit
.. //depot/projects/usb/src/sys/dev/usb/uplcom.c#16 edit
.. //depot/projects/usb/src/sys/dev/usb/uvisor.c#12 edit
.. //depot/projects/usb/src/sys/dev/usb/uvscom.c#16 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/ubsa.c#14 (text+ko) ====

@@ -26,6 +26,7 @@
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/sys/dev/usb/ubsa.c,v 1.20 2006/10/31 02:27:24 kevlo Exp $");
+
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -67,7 +68,6 @@
 #include <sys/kernel.h>
 #include <sys/termios.h>
 #include <sys/serial.h>
-#include <sys/taskqueue.h>
 
 #include <dev/usb/usb_port.h>
 #include <dev/usb/usb.h>
@@ -92,25 +92,20 @@
 #define	DPRINTF(...)
 #endif
 
-#define UBSA_MODVER		1 /* module version */
+#define UBSA_N_TRANSFER           6 /* units */
+#define UBSA_BSIZE              256 /* bytes */
 
-#define UBSA_N_TRANSFER         14 /* units */
-#define UBSA_BSIZE              64 /* bytes */
-
 #define UBSA_CONFIG_INDEX	1
 #define UBSA_IFACE_INDEX	0
 
-enum {
-  UBSA_REG_BAUDRATE,
-  UBSA_REG_STOP_BITS,
-  UBSA_REG_DATA_BITS,
-  UBSA_REG_PARITY,
-  UBSA_REG_DTR,
-  UBSA_REG_RTS,
-  UBSA_REG_BREAK,
-  UBSA_REG_FLOW_CTRL,
-  USBA_N_REG
-};
+#define	UBSA_REG_BAUDRATE	0x00
+#define	UBSA_REG_STOP_BITS	0x01
+#define	UBSA_REG_DATA_BITS	0x02
+#define	UBSA_REG_PARITY		0x03
+#define	UBSA_REG_DTR		0x0A
+#define	UBSA_REG_RTS		0x0B
+#define	UBSA_REG_BREAK		0x0C
+#define	UBSA_REG_FLOW_CTRL	0x10
 
 #define UBSA_PARITY_NONE	0x00
 #define UBSA_PARITY_EVEN	0x01
@@ -151,22 +146,19 @@
 #define UBSA_MSR_DCTS		0x01	/* CTS has changed state */
 
 struct	ubsa_softc {
+	struct ucom_super_softc	sc_super_ucom;
 	struct ucom_softc	sc_ucom;
 
 	struct usbd_xfer *	sc_xfer[UBSA_N_TRANSFER];
+	struct usbd_device	*sc_udev;
 
 	u_int16_t		sc_flag;
 #define UBSA_FLAG_WRITE_STALL   0x0001
 #define UBSA_FLAG_READ_STALL    0x0002
 #define UBSA_FLAG_INTR_STALL    0x0004
 
-	u_int16_t		sc_reg_flag;
-	u_int16_t		sc_reg[USBA_N_REG];
-
 	u_int8_t		sc_iface_no; /* interface number */
 	u_int8_t		sc_iface_index; /* interface index */
-	u_int8_t		sc_dtr; /* current DTR state */
-	u_int8_t		sc_rts; /* current RTS state */
 	u_int8_t		sc_lsr; /* local status register */
 	u_int8_t		sc_msr; /* UBSA status register */
 };
@@ -175,101 +167,23 @@
 static device_attach_t ubsa_attach;
 static device_detach_t ubsa_detach;
 
-static void
-ubsa_request(struct ubsa_softc *sc, u_int8_t index, u_int16_t value);
-
-static void
-ubsa_set_dtr(struct ucom_softc *ucom, u_int8_t onoff);
-
-static void
-ubsa_set_rts(struct ucom_softc *ucom, u_int8_t onoff);
-
-static void
-ubsa_set_break(struct ucom_softc *ucom, u_int8_t onoff);
-
-static u_int8_t
-ubsa_baudrate(struct ubsa_softc *sc, speed_t speed);
-
-static void
-ubsa_parity(struct ubsa_softc *sc, tcflag_t cflag);
-
-static void
-ubsa_databits(struct ubsa_softc *sc, tcflag_t cflag);
-
-static void
-ubsa_stopbits(struct ubsa_softc *sc, tcflag_t cflag);
-
-static void
-ubsa_flow(struct ubsa_softc *sc, tcflag_t cflag, tcflag_t iflag);
-
-static int
-ubsa_param(struct ucom_softc *ucom, struct termios *ti);
-
-static int
-ubsa_open(struct ucom_softc *ucom);
-
-static void
-ubsa_close(struct ucom_softc *ucom);
-
-static void
-ubsa_start_read(struct ucom_softc *ucom);
-
-static void
-ubsa_stop_read(struct ucom_softc *ucom);
-
-static void
-ubsa_start_write(struct ucom_softc *ucom);
-
-static void
-ubsa_stop_write(struct ucom_softc *ucom);
-
-static void
-ubsa_get_status(struct ucom_softc *ucom, u_int8_t *lsr, u_int8_t *msr);
-
-static void
-ubsa_write_callback(struct usbd_xfer *xfer);
-
-static void
-ubsa_write_clear_stall_callback(struct usbd_xfer *xfer);
-
-static void
-ubsa_read_callback(struct usbd_xfer *xfer);
-
-static void
-ubsa_read_clear_stall_callback(struct usbd_xfer *xfer);
-
-static void
-ubsa_intr_callback(struct usbd_xfer *xfer);
-
-static void
-ubsa_intr_clear_stall_callback(struct usbd_xfer *xfer);
-
-static void
-ubsa_request_callback(struct usbd_xfer *xfer, u_int8_t index);
-
-static void
-ubsa_set_baudrate_callback(struct usbd_xfer *xfer);
-
-static void
-ubsa_set_stop_bits_callback(struct usbd_xfer *xfer);
-
-static void
-ubsa_set_data_bits_callback(struct usbd_xfer *xfer);
-
-static void
-ubsa_set_parity_callback(struct usbd_xfer *xfer);
-
-static void
-ubsa_set_dtr_callback(struct usbd_xfer *xfer);
-
-static void
-ubsa_set_rts_callback(struct usbd_xfer *xfer);
-
-static void
-ubsa_set_break_callback(struct usbd_xfer *xfer);
-
-static void
-ubsa_set_flow_ctrl_callback(struct usbd_xfer *xfer);
+static void	ubsa_cfg_request(struct ubsa_softc *sc, u_int8_t index, u_int16_t value);
+static void	ubsa_cfg_set_dtr(struct ucom_softc *ucom, u_int8_t onoff);
+static void	ubsa_cfg_set_rts(struct ucom_softc *ucom, u_int8_t onoff);
+static void	ubsa_cfg_set_break(struct ucom_softc *ucom, u_int8_t onoff);
+static int	ubsa_pre_param(struct ucom_softc *ucom, struct termios *t);
+static void	ubsa_cfg_param(struct ucom_softc *ucom, struct termios *t);
+static void	ubsa_start_read(struct ucom_softc *ucom);
+static void	ubsa_stop_read(struct ucom_softc *ucom);
+static void	ubsa_start_write(struct ucom_softc *ucom);
+static void	ubsa_stop_write(struct ucom_softc *ucom);
+static void	ubsa_cfg_get_status(struct ucom_softc *ucom, u_int8_t *lsr, u_int8_t *msr);
+static void	ubsa_write_callback(struct usbd_xfer *xfer);
+static void	ubsa_write_clear_stall_callback(struct usbd_xfer *xfer);
+static void	ubsa_read_callback(struct usbd_xfer *xfer);
+static void	ubsa_read_clear_stall_callback(struct usbd_xfer *xfer);
+static void	ubsa_intr_callback(struct usbd_xfer *xfer);
+static void	ubsa_intr_clear_stall_callback(struct usbd_xfer *xfer);
 
 static const struct usbd_config ubsa_config[UBSA_N_TRANSFER] = {
 
@@ -326,92 +240,19 @@
       .callback  = &ubsa_intr_clear_stall_callback,
       .timeout   = 1000, /* 1 second */
     },
-
-    [6+UBSA_REG_BAUDRATE] = {
-      .type      = UE_CONTROL,
-      .endpoint  = 0x00, /* Control pipe */
-      .direction = -1,
-      .bufsize   = sizeof(usb_device_request_t),
-      .callback  = &ubsa_set_baudrate_callback,
-      .timeout   = 1000, /* 1 second */
-    },
-
-    [6+UBSA_REG_STOP_BITS] = {
-      .type      = UE_CONTROL,
-      .endpoint  = 0x00, /* Control pipe */
-      .direction = -1,
-      .bufsize   = sizeof(usb_device_request_t),
-      .callback  = &ubsa_set_stop_bits_callback,
-      .timeout   = 1000, /* 1 second */
-    },
-
-    [6+UBSA_REG_DATA_BITS] = {
-      .type      = UE_CONTROL,
-      .endpoint  = 0x00, /* Control pipe */
-      .direction = -1,
-      .bufsize   = sizeof(usb_device_request_t),
-      .callback  = &ubsa_set_data_bits_callback,
-      .timeout   = 1000, /* 1 second */
-    },
-
-    [6+UBSA_REG_PARITY] = {
-      .type      = UE_CONTROL,
-      .endpoint  = 0x00, /* Control pipe */
-      .direction = -1,
-      .bufsize   = sizeof(usb_device_request_t),
-      .callback  = &ubsa_set_parity_callback,
-      .timeout   = 1000, /* 1 second */
-    },
-
-    [6+UBSA_REG_DTR] = {
-      .type      = UE_CONTROL,
-      .endpoint  = 0x00, /* Control pipe */
-      .direction = -1,
-      .bufsize   = sizeof(usb_device_request_t),
-      .callback  = &ubsa_set_dtr_callback,
-      .timeout   = 1000, /* 1 second */
-    },
-
-    [6+UBSA_REG_RTS] = {
-      .type      = UE_CONTROL,
-      .endpoint  = 0x00, /* Control pipe */
-      .direction = -1,
-      .bufsize   = sizeof(usb_device_request_t),
-      .callback  = &ubsa_set_rts_callback,
-      .timeout   = 1000, /* 1 second */
-    },
-
-    [6+UBSA_REG_BREAK] = {
-      .type      = UE_CONTROL,
-      .endpoint  = 0x00, /* Control pipe */
-      .direction = -1,
-      .bufsize   = sizeof(usb_device_request_t),
-      .callback  = &ubsa_set_break_callback,
-      .timeout   = 1000, /* 1 second */
-    },
-
-    [6+UBSA_REG_FLOW_CTRL] = {
-      .type      = UE_CONTROL,
-      .endpoint  = 0x00, /* Control pipe */
-      .direction = -1,
-      .bufsize   = sizeof(usb_device_request_t),
-      .callback  = &ubsa_set_flow_ctrl_callback,
-      .timeout   = 1000, /* 1 second */
-    },
 };
 
 static const struct ucom_callback ubsa_callback = {
-    .ucom_get_status  = &ubsa_get_status,
-    .ucom_set_dtr     = &ubsa_set_dtr,
-    .ucom_set_rts     = &ubsa_set_rts,
-    .ucom_set_break   = &ubsa_set_break,
-    .ucom_param       = &ubsa_param,
-    .ucom_open        = &ubsa_open,
-    .ucom_close       = &ubsa_close,
-    .ucom_start_read  = &ubsa_start_read,
-    .ucom_stop_read   = &ubsa_stop_read,
-    .ucom_start_write = &ubsa_start_write,
-    .ucom_stop_write  = &ubsa_stop_write,
+    .ucom_cfg_get_status  = &ubsa_cfg_get_status,
+    .ucom_cfg_set_dtr     = &ubsa_cfg_set_dtr,
+    .ucom_cfg_set_rts     = &ubsa_cfg_set_rts,
+    .ucom_cfg_set_break   = &ubsa_cfg_set_break,
+    .ucom_cfg_param       = &ubsa_cfg_param,
+    .ucom_pre_param       = &ubsa_pre_param,
+    .ucom_start_read      = &ubsa_start_read,
+    .ucom_stop_read       = &ubsa_stop_read,
+    .ucom_start_write     = &ubsa_start_write,
+    .ucom_stop_write      = &ubsa_stop_write,
 };
 
 static const struct ubsa_product {
@@ -455,7 +296,6 @@
 DRIVER_MODULE(ubsa, uhub, ubsa_driver, ubsa_devclass, usbd_driver_load, 0);
 MODULE_DEPEND(ubsa, usb, 1, 1, 1);
 MODULE_DEPEND(ubsa, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(ubsa, UBSA_MODVER);
 
 static int
 ubsa_probe(device_t dev)
@@ -494,6 +334,8 @@
 
 	usbd_set_desc(dev, uaa->device);
 
+	sc->sc_udev = uaa->device;
+
 	/* configure the device */
 
 	error = usbd_set_config_index(uaa->device, UBSA_CONFIG_INDEX, 1);
@@ -529,10 +371,11 @@
 	    goto detach;
 	}
 
-	sc->sc_dtr = -1;
-	sc->sc_rts = -1;
+	/* clear stall at first run */
+	sc->sc_flag |= (UBSA_FLAG_WRITE_STALL|
+			UBSA_FLAG_READ_STALL);
 
-	error = ucom_attach(&(sc->sc_ucom), 1, sc,
+	error = ucom_attach(&(sc->sc_super_ucom), &(sc->sc_ucom), 1, sc,
 			    &ubsa_callback, &Giant);
 	if (error) {
 	    DPRINTF(0, "ucom_attach failed\n");
@@ -553,7 +396,7 @@
 
 	DPRINTF(0, "sc=%p\n", sc);
 
-	ucom_detach(&(sc->sc_ucom), 1);
+	ucom_detach(&(sc->sc_super_ucom), &(sc->sc_ucom), 1);
 
 	usbd_transfer_unsetup(sc->sc_xfer, UBSA_N_TRANSFER);
 
@@ -561,66 +404,73 @@
 }
 
 static void
-ubsa_request(struct ubsa_softc *sc, u_int8_t index, u_int16_t value)
+ubsa_cfg_request(struct ubsa_softc *sc, u_int8_t index, u_int16_t value)
 {
-	if (index >= USBA_N_REG) {
-	    panic("invalid register index!");
+	usb_device_request_t req;
+	usbd_status err;
+
+	if (ucom_cfg_is_gone(&(sc->sc_ucom))) {
+	    return;
+	}
+
+	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+	req.bRequest = index;
+	USETW(req.wValue, value);
+	req.wIndex[0] = sc->sc_iface_no;
+	req.wIndex[1] = 0;
+	USETW(req.wLength, 0);
+
+	err = usbd_do_request_flags_mtx(sc->sc_udev, &Giant, &req, 
+					NULL, 0, NULL, 1000);
+	if (err) {
+	    DPRINTF(-1, "device request failed, err=%s "
+		    "(ignored)\n", usbd_errstr(err));
 	}
-	sc->sc_reg_flag |= (1 << index);
-	sc->sc_reg[index] = value;
-	usbd_transfer_start(sc->sc_xfer[6+index]);
 	return;
 }
 
 static void
-ubsa_set_dtr(struct ucom_softc *ucom, u_int8_t onoff)
+ubsa_cfg_set_dtr(struct ucom_softc *ucom, u_int8_t onoff)
 {
 	struct ubsa_softc *sc = ucom->sc_parent;
 
 	DPRINTF(0, "onoff = %d\n", onoff);
 
-	if (sc->sc_dtr != onoff) {
-	    sc->sc_dtr = onoff;
-	    ubsa_request(sc, UBSA_REG_DTR, onoff ? 1 : 0);
-	}
+	ubsa_cfg_request(sc, UBSA_REG_DTR, onoff ? 1 : 0);
 	return;
 }
 
 static void
-ubsa_set_rts(struct ucom_softc *ucom, u_int8_t onoff)
+ubsa_cfg_set_rts(struct ucom_softc *ucom, u_int8_t onoff)
 {
 	struct ubsa_softc *sc = ucom->sc_parent;
 
 	DPRINTF(0, "onoff = %d\n", onoff);
 
-	if (sc->sc_rts != onoff) {
-	    sc->sc_rts = onoff;
-	    ubsa_request(sc, UBSA_REG_RTS, onoff ? 1 : 0);
-	}
+	ubsa_cfg_request(sc, UBSA_REG_RTS, onoff ? 1 : 0);
 	return;
 }
 
 static void
-ubsa_set_break(struct ucom_softc *ucom, u_int8_t onoff)
+ubsa_cfg_set_break(struct ucom_softc *ucom, u_int8_t onoff)
 {
 	struct ubsa_softc *sc = ucom->sc_parent;
 
 	DPRINTF(0, "onoff = %d\n", onoff);
 
-	ubsa_request(sc, UBSA_REG_BREAK, onoff ? 1 : 0);
+	ubsa_cfg_request(sc, UBSA_REG_BREAK, onoff ? 1 : 0);
 	return;
 }
 
-static u_int8_t
-ubsa_baudrate(struct ubsa_softc *sc, speed_t speed)
+static int
+ubsa_pre_param(struct ucom_softc *ucom, struct termios *t)
 {
-	u_int16_t value = 0;
+	struct ubsa_softc *sc = ucom->sc_parent;
 
-	DPRINTF(0, "speed = %d\n", speed);
+	DPRINTF(0, "sc = %p\n", sc);
 
-	switch(speed) {
+	switch(t->c_ospeed) {
 	case B0:
-		break;
 	case B300:
 	case B600:
 	case B1200:
@@ -632,136 +482,86 @@
 	case B57600:
 	case B115200:
 	case B230400:
-	    value = B230400 / speed;
 	    break;
-
 	default:
-	    DPRINTF(0, "unsupported baudrate\n");
-	    return 1;
-	};
-
-	if (speed == B0) {
-	    ubsa_flow(sc, 0, 0);
-	    ubsa_set_dtr(&(sc->sc_ucom), 0);
-	    ubsa_set_rts(&(sc->sc_ucom), 0);
-	} else {
-	    ubsa_request(sc, UBSA_REG_BAUDRATE, value);
+	    return EINVAL;
 	}
 	return 0;
 }
 
 static void
-ubsa_parity(struct ubsa_softc *sc, tcflag_t cflag)
+ubsa_cfg_param(struct ucom_softc *ucom, struct termios *t)
 {
-	u_int16_t value;
+	struct ubsa_softc *sc = ucom->sc_parent;
+	u_int16_t value = 0;
+
+	DPRINTF(0, "sc = %p\n", sc);
 
-	DPRINTF(0, "flag = 0x%x\n", cflag);
+	switch(t->c_ospeed) {
+	case B0:
+	    ubsa_cfg_request(sc, UBSA_REG_FLOW_CTRL, 0);
+	    ubsa_cfg_set_dtr(&(sc->sc_ucom), 0);
+	    ubsa_cfg_set_rts(&(sc->sc_ucom), 0);
+	    break;
+	case B300:
+	case B600:
+	case B1200:
+	case B2400:
+	case B4800:
+	case B9600:
+	case B19200:
+	case B38400:
+	case B57600:
+	case B115200:
+	case B230400:
+	    value = B230400 / t->c_ospeed;
+	    ubsa_cfg_request(sc, UBSA_REG_BAUDRATE, value);
+	    break;
+	default:
+	    return;
+	}
 
-	if (cflag & PARENB)
-		value = (cflag & PARODD) ? UBSA_PARITY_ODD : UBSA_PARITY_EVEN;
+	if (t->c_cflag & PARENB)
+		value = (t->c_cflag & PARODD) ? UBSA_PARITY_ODD : UBSA_PARITY_EVEN;
 	else
 		value = UBSA_PARITY_NONE;
 
-	ubsa_request(sc, UBSA_REG_PARITY, value);
-	return;
-}
+	ubsa_cfg_request(sc, UBSA_REG_PARITY, value);
 
-static void
-ubsa_databits(struct ubsa_softc *sc, tcflag_t cflag)
-{
-	u_int16_t value;
-
-	DPRINTF(0, "cflag = 0x%x\n", cflag);
-
-	switch (cflag & CSIZE) {
+	switch (t->c_cflag & CSIZE) {
 	case CS5: value = 0; break;
 	case CS6: value = 1; break;
 	case CS7: value = 2; break;
+	default:
 	case CS8: value = 3; break;
-	default:
-	    DPRINTF(0, "unsupported databits requested, "
-		    "forcing default of 8\n");
-	    value = 3;
 	}
 
-	ubsa_request(sc, UBSA_REG_DATA_BITS, value);
-	return;
-}
+	ubsa_cfg_request(sc, UBSA_REG_DATA_BITS, value);
+
+	value = (t->c_cflag & CSTOPB) ? 1 : 0;
 
-static void
-ubsa_stopbits(struct ubsa_softc *sc, tcflag_t cflag)
-{
-	u_int16_t value;
+	ubsa_cfg_request(sc, UBSA_REG_STOP_BITS, value);
 
-	DPRINTF(0, "cflag = 0x%x\n", cflag);
+	value = 0;
+	if (t->c_cflag & CRTSCTS)
+	    value |= UBSA_FLOW_OCTS | UBSA_FLOW_IRTS;
 
-	value = (cflag & CSTOPB) ? 1 : 0;
+	if (t->c_iflag & (IXON|IXOFF))
+	    value |= UBSA_FLOW_OXON | UBSA_FLOW_IXON;
 
-	ubsa_request(sc, UBSA_REG_STOP_BITS, value);
+	ubsa_cfg_request(sc, UBSA_REG_FLOW_CTRL, value);
 	return;
 }
 
 static void
-ubsa_flow(struct ubsa_softc *sc, tcflag_t cflag, tcflag_t iflag)
+ubsa_start_read(struct ucom_softc *ucom)
 {
-	u_int16_t value;
-
-	DPRINTF(0, "cflag = 0x%x, iflag = 0x%x\n", cflag, iflag);
-
-	value = 0;
-	if (cflag & CRTSCTS)
-		value |= UBSA_FLOW_OCTS | UBSA_FLOW_IRTS;
-	if (iflag & (IXON|IXOFF))
-		value |= UBSA_FLOW_OXON | UBSA_FLOW_IXON;
-
-	ubsa_request(sc, UBSA_REG_FLOW_CTRL, value);
-	return;
-}
-
-static int
-ubsa_param(struct ucom_softc *ucom, struct termios *ti)
-{
 	struct ubsa_softc *sc = ucom->sc_parent;
 
-	DPRINTF(0, "sc = %p\n", sc);
-
-	if (ubsa_baudrate(sc, ti->c_ospeed)) {
-	    return EIO;
-	}
-	ubsa_parity(sc, ti->c_cflag);
-	ubsa_databits(sc, ti->c_cflag);
-	ubsa_stopbits(sc, ti->c_cflag);
-	ubsa_flow(sc, ti->c_cflag, ti->c_iflag);
-
-	return (0);
-}
-
-static int
-ubsa_open(struct ucom_softc *ucom)
-{
-	struct ubsa_softc *sc = ucom->sc_parent;
-
-	/* clear stall first: */
-	sc->sc_flag |= (UBSA_FLAG_WRITE_STALL|
-			UBSA_FLAG_READ_STALL);
-
+	/* start interrupt endpoint */
 	usbd_transfer_start(sc->sc_xfer[4]);
-	return 0;
-}
 
-static void
-ubsa_close(struct ucom_softc *ucom)
-{
-	struct ubsa_softc *sc = ucom->sc_parent;
-	usbd_transfer_stop(sc->sc_xfer[5]);
-	usbd_transfer_stop(sc->sc_xfer[4]);
-	return;
-}
-
-static void
-ubsa_start_read(struct ucom_softc *ucom)
-{
-	struct ubsa_softc *sc = ucom->sc_parent;
+	/* start read endpoint */
 	usbd_transfer_start(sc->sc_xfer[1]);
 	return;
 }
@@ -770,6 +570,11 @@
 ubsa_stop_read(struct ucom_softc *ucom)
 {
 	struct ubsa_softc *sc = ucom->sc_parent;
+	/* stop interrupt endpoint */
+	usbd_transfer_stop(sc->sc_xfer[5]);
+	usbd_transfer_stop(sc->sc_xfer[4]);
+
+	/* stop read endpoint */
 	usbd_transfer_stop(sc->sc_xfer[3]);
 	usbd_transfer_stop(sc->sc_xfer[1]);
 	return;
@@ -793,19 +598,14 @@
 }
 
 static void
-ubsa_get_status(struct ucom_softc *ucom, u_int8_t *lsr, u_int8_t *msr)
+ubsa_cfg_get_status(struct ucom_softc *ucom, u_int8_t *lsr, u_int8_t *msr)
 {
 	struct ubsa_softc *sc = ucom->sc_parent;
 
 	DPRINTF(0, "\n");
 
-	if (lsr) {
-	    *lsr = sc->sc_lsr;
-	}
-
-	if (msr) {
-	    *msr = sc->sc_msr;
-	}
+	*lsr = sc->sc_lsr;
+	*msr = sc->sc_msr;
 	return;
 }
 
@@ -816,6 +616,7 @@
 	u_int32_t actlen;
 
 	USBD_CHECK_STATUS(xfer);
+
 tr_error:
 	if (xfer->error != USBD_CANCELLED) {
 	    sc->sc_flag |= UBSA_FLAG_WRITE_STALL;
@@ -980,100 +781,3 @@
 		usbd_errstr(xfer->error));
 	return;
 }
-
-static void
-ubsa_request_callback(struct usbd_xfer *xfer, u_int8_t index)
-{
-	static const u_int8_t mapping[USBA_N_REG] = {
-	  [UBSA_REG_BAUDRATE]  = 0x00,
-	  [UBSA_REG_STOP_BITS] = 0x01,
-	  [UBSA_REG_DATA_BITS] = 0x02,
-	  [UBSA_REG_PARITY]    = 0x03,
-	  [UBSA_REG_DTR]       = 0x0A,
-	  [UBSA_REG_RTS]       = 0x0B,
-	  [UBSA_REG_BREAK]     = 0x0C,
-	  [UBSA_REG_FLOW_CTRL] = 0x10,
-	};
-
-	usb_device_request_t *req = xfer->buffer;
-	struct ubsa_softc *sc = xfer->priv_sc;
-	u_int8_t request = mapping[index];
-	u_int16_t value = sc->sc_reg[index];
-	u_int16_t bitmask = (1 << index);
-
-	USBD_CHECK_STATUS(xfer);
-
- tr_error:
-	DPRINTF(0, "transfer failed, "
-		"error=%s\n", usbd_errstr(xfer->error));
- tr_setup:
- tr_transferred:
-	if (sc->sc_reg_flag &   bitmask) {
-	    sc->sc_reg_flag &= ~bitmask;
-
-	    req->bmRequestType = UT_WRITE_VENDOR_DEVICE;
-	    req->bRequest = request;
-	    USETW(req->wValue, value);
-	    USETW(req->wIndex, sc->sc_iface_no);
-	    USETW(req->wLength, 0);
-
-	    usbd_start_hardware(xfer);
-	}
-	return;
-}
-
-static void
-ubsa_set_baudrate_callback(struct usbd_xfer *xfer)
-{
-    ubsa_request_callback(xfer, UBSA_REG_BAUDRATE);
-    return;
-}
-
-static void
-ubsa_set_stop_bits_callback(struct usbd_xfer *xfer)
-{
-    ubsa_request_callback(xfer, UBSA_REG_STOP_BITS);
-    return;
-}
-
-static void
-ubsa_set_data_bits_callback(struct usbd_xfer *xfer)
-{
-    ubsa_request_callback(xfer, UBSA_REG_DATA_BITS);
-    return;
-}
-
-static void
-ubsa_set_parity_callback(struct usbd_xfer *xfer)
-{
-    ubsa_request_callback(xfer, UBSA_REG_PARITY);
-    return;
-}
-
-static void
-ubsa_set_dtr_callback(struct usbd_xfer *xfer)
-{
-    ubsa_request_callback(xfer, UBSA_REG_DTR);
-    return;
-}
-
-static void
-ubsa_set_rts_callback(struct usbd_xfer *xfer)
-{
-    ubsa_request_callback(xfer, UBSA_REG_RTS);
-    return;
-}
-
-static void
-ubsa_set_break_callback(struct usbd_xfer *xfer)
-{
-    ubsa_request_callback(xfer, UBSA_REG_BREAK);
-    return;
-}
-
-static void
-ubsa_set_flow_ctrl_callback(struct usbd_xfer *xfer)
-{
-    ubsa_request_callback(xfer, UBSA_REG_FLOW_CTRL);
-    return;
-}

==== //depot/projects/usb/src/sys/dev/usb/ubser.c#9 (text+ko) ====

@@ -81,7 +81,6 @@
 #include <sys/kernel.h>
 #include <sys/termios.h>
 #include <sys/serial.h>
-#include <sys/taskqueue.h>
 
 #include <dev/usb/usb_port.h>
 #include <dev/usb/usb.h>
@@ -115,18 +114,18 @@
 #define UBSER_TR_DT_READ  1
 #define UBSER_TR_CS_WRITE 2
 #define UBSER_TR_CS_READ  3
-#define UBSER_TR_DT_BREAK 4
-#define UBSER_TR_MAX      5
+#define UBSER_TR_MAX      4
 
 struct ubser_softc {
+	struct ucom_super_softc	sc_super_ucom;
 	struct ucom_softc	sc_ucom[UBSER_UNIT_MAX];
 
 	struct usbd_xfer	*sc_xfer[UBSER_TR_MAX];
+	struct usbd_device	*sc_udev;
 
 	uint16_t		sc_tx_size;
 
 	uint8_t			sc_numser;
-	uint8_t			sc_send_break[(UBSER_UNIT_MAX+7)/8];
 	uint8_t			sc_flags;
 #define UBSER_FLAG_READ_STALL  0x01
 #define UBSER_FLAG_WRITE_STALL 0x02
@@ -134,7 +133,6 @@
 	uint8_t			sc_iface_no;
 	uint8_t			sc_iface_index;
 	uint8_t			sc_curr_tx_unit;
-	uint8_t			sc_curr_break_unit;
 	uint8_t			sc_name[16];
 };
 
@@ -142,15 +140,17 @@
 static device_attach_t ubser_attach;
 static device_detach_t ubser_detach;
 
-static int   ubser_param(struct ucom_softc *ucom, struct termios *t);
+static int   ubser_pre_param(struct ucom_softc *ucom, struct termios *t);
 static void  ubser_write_clear_stall_callback(struct usbd_xfer *xfer);
 static void  ubser_write_callback(struct usbd_xfer *xfer);
 static void  ubser_read_clear_stall_callback(struct usbd_xfer *xfer);
 static void  ubser_read_callback(struct usbd_xfer *xfer);
-static void  ubser_set_break(struct ucom_softc *ucom, u_int8_t onoff);
-static void  ubser_send_break_callback(struct usbd_xfer *xfer);
-static int   ubser_open(struct ucom_softc *ucom);
+static void  ubser_cfg_set_break(struct ucom_softc *ucom, u_int8_t onoff);
+static void  ubser_cfg_get_status(struct ucom_softc *ucom, u_int8_t *lsr, u_int8_t *msr);
+static void  ubser_start_read(struct ucom_softc *ucom);
+static void  ubser_stop_read(struct ucom_softc *ucom);
 static void  ubser_start_write(struct ucom_softc *ucom);
+static void  ubser_stop_write(struct ucom_softc *ucom);
 
 static const struct usbd_config ubser_config[UBSER_TR_MAX] = {
 
@@ -191,23 +191,16 @@
       .callback  = &ubser_read_clear_stall_callback,
       .timeout   = 1000, /* 1 second */
     },
-
-    [UBSER_TR_DT_BREAK] = {
-      .type      = UE_CONTROL,
-      .endpoint  = 0x00, /* Control pipe */
-      .direction = -1,
-      .bufsize   = sizeof(usb_device_request_t),
-      .flags     = 0,
-      .callback  = &ubser_send_break_callback,
-      .timeout   = 1000, /* 1 second */
-    },
 };
 
 static const struct ucom_callback ubser_callback = {
-  .ucom_open        = &ubser_open,
-  .ucom_set_break   = &ubser_set_break,
-  .ucom_param       = &ubser_param,
-  .ucom_start_write = &ubser_start_write,
+  .ucom_cfg_set_break   = &ubser_cfg_set_break,
+  .ucom_cfg_get_status  = &ubser_cfg_get_status,
+  .ucom_pre_param       = &ubser_pre_param,
+  .ucom_start_read      = &ubser_start_read,
+  .ucom_stop_read       = &ubser_stop_read,
+  .ucom_start_write     = &ubser_start_write,
+  .ucom_stop_write      = &ubser_stop_write,
 };
 
 static device_method_t ubser_methods[] = {
@@ -288,12 +281,14 @@
 
 	sc->sc_iface_no = id->bInterfaceNumber;
 	sc->sc_iface_index = uaa->iface_index;
+	sc->sc_udev = uaa->device;
 
 	/* get number of serials */
 	req.bmRequestType = UT_READ_VENDOR_INTERFACE;
 	req.bRequest = VENDOR_GET_NUMSER;
 	USETW(req.wValue, 0);
-	USETW(req.wIndex, sc->sc_iface_no);
+	req.wIndex[0] = sc->sc_iface_no;
+	req.wIndex[1] = 0;
 	USETW(req.wLength, 1);
 	error = usbd_do_request_flags(uaa->device, &req, &sc->sc_numser,
 				    0, NULL, USBD_DEFAULT_TIMEOUT);
@@ -329,7 +324,7 @@
 	    sc->sc_ucom[n].sc_portno = n;
 	}
 
-	error = ucom_attach(sc->sc_ucom, sc->sc_numser, sc,
+	error = ucom_attach(&(sc->sc_super_ucom), sc->sc_ucom, sc->sc_numser, sc,
 			    &ubser_callback, &Giant);
 	if (error) {
 	    goto detach;
@@ -359,7 +354,7 @@
 
 	DPRINTF(sc, 0, "\n");
 
-	ucom_detach(sc->sc_ucom, sc->sc_numser);
+	ucom_detach(&(sc->sc_super_ucom), sc->sc_ucom, sc->sc_numser);
 
 	/* need to stop all transfers atomically,
 	 * hence when clear stall completes, it
@@ -379,7 +374,7 @@
 }
 
 static int
-ubser_param(struct ucom_softc *ucom, struct termios *t)
+ubser_pre_param(struct ucom_softc *ucom, struct termios *t)
 {
 	struct ubser_softc *sc = ucom->sc_parent;
 
@@ -391,7 +386,7 @@
 	 * We refuse to accept other configurations.
 	 */
 
-	/* enshure 9600bps */
+	/* ensure 9600bps */
 	switch (t->c_ospeed) {
 	case 9600:
 		break;
@@ -576,76 +571,57 @@
 }
 
 static void
-ubser_set_break(struct ucom_softc *ucom, u_int8_t onoff)
+ubser_cfg_set_break(struct ucom_softc *ucom, u_int8_t onoff)
 {
 	struct ubser_softc *sc = ucom->sc_parent;
 	uint8_t x = ucom->sc_portno;
+	usb_device_request_t req;
+	usbd_status err;
 
 	if (onoff) {
-	    sc->sc_send_break[x/8] |= (1<<(x%8));
-	    usbd_transfer_start(sc->sc_xfer[UBSER_TR_DT_BREAK]);
+
+	    req.bmRequestType = UT_READ_VENDOR_INTERFACE;
+	    req.bRequest = VENDOR_SET_BREAK;
+	    req.wValue[0] = x;
+	    req.wValue[1] = 0;
+	    req.wIndex[0] = sc->sc_iface_no;
+	    req.wIndex[1] = 0;
+	    USETW(req.wLength, 0);
+
+	    err = usbd_do_request_flags_mtx(sc->sc_udev, &Giant, &req, 
+					    NULL, 0, NULL, 1000);
+	    if (err) {
+	        DPRINTF(sc, -1, "send break failed, error=%s\n",
+			usbd_errstr(err));
+	    }
 	}
 	return;
 }
 
-static __inline void
-ubser_inc_break_unit(struct ubser_softc *sc)
+static void
+ubser_cfg_get_status(struct ucom_softc *ucom, u_int8_t *lsr, u_int8_t *msr)
 {
-	sc->sc_curr_break_unit ++;
-	if (sc->sc_curr_break_unit >= sc->sc_numser) {
-	    sc->sc_curr_break_unit = 0;
-	}
+	/* fake status bits */
+	*lsr = 0;
+	*msr = SER_DCD;
 	return;
 }
 
 static void
-ubser_send_break_callback(struct usbd_xfer *xfer)
+ubser_start_read(struct ucom_softc *ucom)
 {

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200703301954.l2UJsCR1080075>