Module Name: src
Committed By: simonb
Date: Sun Apr 12 01:10:54 UTC 2020
Modified Files:
src/distrib/sets/lists/man: mi
src/share/man/man4: Makefile ucom.4
src/sys/dev/usb: files.usb ukyopon.c umodem.c umodem_common.c
usbdevices.config usbdevs
Added Files:
src/share/man/man4: uxrcom.4
src/sys/dev/usb: uxrcom.c
Log Message:
Add uxrcom driver for Exar XR21V141x USB serial adapters. Based in part
on the OpenBSD single-port XR21V1410 uxrcom driver, but adds support
for multi-port chipsets and uses the common umodem framework instead of
being a standalone driver.
Thanks to skrll@ for much USB clue and mrg@ for financing the
development of this driver.
To generate a diff of this commit:
cvs rdiff -u -r1.1686 -r1.1687 src/distrib/sets/lists/man/mi
cvs rdiff -u -r1.703 -r1.704 src/share/man/man4/Makefile
cvs rdiff -u -r1.27 -r1.28 src/share/man/man4/ucom.4
cvs rdiff -u -r0 -r1.1 src/share/man/man4/uxrcom.4
cvs rdiff -u -r1.172 -r1.173 src/sys/dev/usb/files.usb
cvs rdiff -u -r1.25 -r1.26 src/sys/dev/usb/ukyopon.c
cvs rdiff -u -r1.73 -r1.74 src/sys/dev/usb/umodem.c
cvs rdiff -u -r1.32 -r1.33 src/sys/dev/usb/umodem_common.c
cvs rdiff -u -r1.37 -r1.38 src/sys/dev/usb/usbdevices.config
cvs rdiff -u -r1.780 -r1.781 src/sys/dev/usb/usbdevs
cvs rdiff -u -r0 -r1.1 src/sys/dev/usb/uxrcom.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/distrib/sets/lists/man/mi
diff -u src/distrib/sets/lists/man/mi:1.1686 src/distrib/sets/lists/man/mi:1.1687
--- src/distrib/sets/lists/man/mi:1.1686 Sat Apr 4 15:39:16 2020
+++ src/distrib/sets/lists/man/mi Sun Apr 12 01:10:53 2020
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1686 2020/04/04 15:39:16 jdolecek Exp $
+# $NetBSD: mi,v 1.1687 2020/04/12 01:10:53 simonb Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@@ -1957,6 +1957,7 @@
./usr/share/man/cat4/uvideo.0 man-sys-catman .cat
./usr/share/man/cat4/uvisor.0 man-sys-catman .cat
./usr/share/man/cat4/uvscom.0 man-sys-catman .cat
+./usr/share/man/cat4/uxrcom.0 man-sys-catman .cat
./usr/share/man/cat4/uyap.0 man-sys-catman .cat
./usr/share/man/cat4/uyurex.0 man-obsolete obsolete
./usr/share/man/cat4/vald.0 man-sys-catman .cat
@@ -5101,6 +5102,7 @@
./usr/share/man/html4/uvideo.html man-sys-htmlman html
./usr/share/man/html4/uvisor.html man-sys-htmlman html
./usr/share/man/html4/uvscom.html man-sys-htmlman html
+./usr/share/man/html4/uxrcom.html man-sys-htmlman html
./usr/share/man/html4/uyap.html man-sys-htmlman html
./usr/share/man/html4/uyurex.html man-obsolete obsolete
./usr/share/man/html4/vald.html man-sys-htmlman html
@@ -8169,6 +8171,7 @@
./usr/share/man/man4/uvideo.4 man-sys-man .man
./usr/share/man/man4/uvisor.4 man-sys-man .man
./usr/share/man/man4/uvscom.4 man-sys-man .man
+./usr/share/man/man4/uxrcom.4 man-sys-man .man
./usr/share/man/man4/uyap.4 man-sys-man .man
./usr/share/man/man4/uyurex.4 man-obsolete obsolete
./usr/share/man/man4/vald.4 man-sys-man .man
Index: src/share/man/man4/Makefile
diff -u src/share/man/man4/Makefile:1.703 src/share/man/man4/Makefile:1.704
--- src/share/man/man4/Makefile:1.703 Sat Apr 4 15:39:13 2020
+++ src/share/man/man4/Makefile Sun Apr 12 01:10:54 2020
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.703 2020/04/04 15:39:13 jdolecek Exp $
+# $NetBSD: Makefile,v 1.704 2020/04/12 01:10:54 simonb Exp $
# @(#)Makefile 8.1 (Berkeley) 6/18/93
MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 \
@@ -87,8 +87,8 @@ MAN+= atu.4 aubtfwl.4 aue.4 axe.4 axen.4
ulpt.4 umass.4 umcs.4 umct.4 umidi.4 umodem.4 ums.4 upgt.4 upl.4 \
uplcom.4 ure.4 url.4 urndis.4 urtw.4 urtwn.4 \
usb.4 usbnet.4 uscanner.4 uslsa.4 usmsc.4 usscanner.4 \
- ustir.4 uthum.4 utoppy.4 uts.4 uvideo.4 uvisor.4 uvscom.4 uyap.4 \
- xhci.4 \
+ ustir.4 uthum.4 utoppy.4 uts.4 uvideo.4 uvisor.4 uvscom.4 uxrcom.4 \
+ uyap.4 xhci.4 \
# Ir devices
MAN+= irframe.4 cir.4 irframetty.4 oboe.4
Index: src/share/man/man4/ucom.4
diff -u src/share/man/man4/ucom.4:1.27 src/share/man/man4/ucom.4:1.28
--- src/share/man/man4/ucom.4:1.27 Sun May 5 00:12:34 2019
+++ src/share/man/man4/ucom.4 Sun Apr 12 01:10:54 2020
@@ -1,4 +1,4 @@
-.\" $NetBSD: ucom.4,v 1.27 2019/05/05 00:12:34 pgoyette Exp $
+.\" $NetBSD: ucom.4,v 1.28 2020/04/12 01:10:54 simonb Exp $
.\"
.\" Copyright (c) 1999 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -50,6 +50,7 @@
.Cd "ucom* at uslsa?"
.Cd "ucom* at uvisor? portno ?"
.Cd "ucom* at uvscom?"
+.Cd "ucom* at uxrcom?"
.Sh DESCRIPTION
The
.Nm
@@ -103,7 +104,8 @@ are used for dial-out.
.Xr usb 4 ,
.Xr uslsa 4 ,
.Xr uvisor 4 ,
-.Xr uvscom 4
+.Xr uvscom 4 ,
+.Xr uxrcom 4
.Sh HISTORY
The
.Nm
Index: src/sys/dev/usb/files.usb
diff -u src/sys/dev/usb/files.usb:1.172 src/sys/dev/usb/files.usb:1.173
--- src/sys/dev/usb/files.usb:1.172 Sun Feb 9 15:46:15 2020
+++ src/sys/dev/usb/files.usb Sun Apr 12 01:10:54 2020
@@ -1,4 +1,4 @@
-# $NetBSD: files.usb,v 1.172 2020/02/09 15:46:15 maya Exp $
+# $NetBSD: files.usb,v 1.173 2020/04/12 01:10:54 simonb Exp $
#
# Config file and device description for machine-independent USB code.
# Included by ports that need it. Ports that use it must provide
@@ -429,6 +429,11 @@ device uvscom: ucombus
attach uvscom at usbdevif
file dev/usb/uvscom.c uvscom
+# Exar XR21V141x serial driver (mostly CDC)
+device uxrcom: ucombus, umodem_common
+attach uxrcom at usbifif
+file dev/usb/uxrcom.c uxrcom
+
# Belkin & other serial driver
define ubsa_common
file dev/usb/ubsa_common.c ubsa_common
Index: src/sys/dev/usb/ukyopon.c
diff -u src/sys/dev/usb/ukyopon.c:1.25 src/sys/dev/usb/ukyopon.c:1.26
--- src/sys/dev/usb/ukyopon.c:1.25 Tue Jan 7 06:42:26 2020
+++ src/sys/dev/usb/ukyopon.c Sun Apr 12 01:10:54 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ukyopon.c,v 1.25 2020/01/07 06:42:26 maxv Exp $ */
+/* $NetBSD: ukyopon.c,v 1.26 2020/04/12 01:10:54 simonb Exp $ */
/*
* Copyright (c) 1998, 2005 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ukyopon.c,v 1.25 2020/01/07 06:42:26 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ukyopon.c,v 1.26 2020/04/12 01:10:54 simonb Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -130,6 +130,8 @@ ukyopon_attach(device_t parent, device_t
struct usbif_attach_arg *uiaa = aux;
struct ucom_attach_args ucaa;
+ memset(&ucaa, 0, sizeof(ucaa));
+
ucaa.ucaa_portno = (uiaa->uiaa_ifaceno == UKYOPON_MODEM_IFACE_INDEX) ?
UKYOPON_PORT_MODEM : UKYOPON_PORT_DATA;
ucaa.ucaa_methods = &ukyopon_methods;
Index: src/sys/dev/usb/umodem.c
diff -u src/sys/dev/usb/umodem.c:1.73 src/sys/dev/usb/umodem.c:1.74
--- src/sys/dev/usb/umodem.c:1.73 Tue Jan 7 06:42:26 2020
+++ src/sys/dev/usb/umodem.c Sun Apr 12 01:10:54 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: umodem.c,v 1.73 2020/01/07 06:42:26 maxv Exp $ */
+/* $NetBSD: umodem.c,v 1.74 2020/04/12 01:10:54 simonb Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -44,7 +44,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umodem.c,v 1.73 2020/01/07 06:42:26 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umodem.c,v 1.74 2020/04/12 01:10:54 simonb Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -114,6 +114,8 @@ umodem_attach(device_t parent, device_t
struct usbif_attach_arg *uiaa = aux;
struct ucom_attach_args ucaa;
+ memset(&ucaa, 0, sizeof(ucaa));
+
ucaa.ucaa_portno = UCOM_UNK_PORTNO;
ucaa.ucaa_methods = &umodem_methods;
ucaa.ucaa_info = NULL;
Index: src/sys/dev/usb/umodem_common.c
diff -u src/sys/dev/usb/umodem_common.c:1.32 src/sys/dev/usb/umodem_common.c:1.33
--- src/sys/dev/usb/umodem_common.c:1.32 Sat Mar 14 02:35:33 2020
+++ src/sys/dev/usb/umodem_common.c Sun Apr 12 01:10:54 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: umodem_common.c,v 1.32 2020/03/14 02:35:33 christos Exp $ */
+/* $NetBSD: umodem_common.c,v 1.33 2020/04/12 01:10:54 simonb Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -44,7 +44,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umodem_common.c,v 1.32 2020/03/14 02:35:33 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umodem_common.c,v 1.33 2020/04/12 01:10:54 simonb Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -105,6 +105,12 @@ static void umodem_break(struct umodem_s
static void umodem_set_line_state(struct umodem_softc *);
static void umodem_intr(struct usbd_xfer *, void *, usbd_status);
+/*
+ * NOTE: Callers of umodem_common_attach() should initialise their ucaa
+ * to 0 before assigning any fields. ucaa_ibufsize, ucaa_ibufsize and
+ * ucaa_obufsize may be set by the caller, but if 0 are set to default
+ * umodem values.
+ */
int
umodem_common_attach(device_t self, struct umodem_softc *sc,
struct usbif_attach_arg *uiaa, struct ucom_attach_args *ucaa)
@@ -239,10 +245,16 @@ umodem_common_attach(device_t self, stru
sc->sc_dtr = -1;
- /* ucaa_bulkin, ucaa_bulkout set above */
- ucaa->ucaa_ibufsize = UMODEMIBUFSIZE;
- ucaa->ucaa_obufsize = UMODEMOBUFSIZE;
- ucaa->ucaa_ibufsizepad = UMODEMIBUFSIZE;
+ /*
+ * ucaa_bulkin, ucaa_bulkout set above. ucaa_ibufsize,
+ * ucaa_ibufsize, ucaa_obufsize may be initialised by caller
+ */
+ if (ucaa->ucaa_ibufsize == 0)
+ ucaa->ucaa_ibufsize = UMODEMIBUFSIZE;
+ if (ucaa->ucaa_obufsize == 0)
+ ucaa->ucaa_obufsize = UMODEMOBUFSIZE;
+ if (ucaa->ucaa_ibufsizepad == 0)
+ ucaa->ucaa_ibufsizepad = UMODEMIBUFSIZE;
ucaa->ucaa_opkthdrlen = 0;
ucaa->ucaa_device = sc->sc_udev;
ucaa->ucaa_iface = sc->sc_data_iface;
@@ -356,7 +368,7 @@ umodem_intr(struct usbd_xfer *xfer, void
sc->sc_notify_buf.data[0],
sc->sc_notify_buf.data[1]));
/* Currently, lsr is always zero. */
- sc->sc_lsr = sc->sc_msr = 0;
+ sc->sc_lsr = sc->sc_msr = 0;
mstatus = sc->sc_notify_buf.data[0];
if (ISSET(mstatus, UCDC_N_SERIAL_RI))
Index: src/sys/dev/usb/usbdevices.config
diff -u src/sys/dev/usb/usbdevices.config:1.37 src/sys/dev/usb/usbdevices.config:1.38
--- src/sys/dev/usb/usbdevices.config:1.37 Wed Jan 29 18:39:04 2020
+++ src/sys/dev/usb/usbdevices.config Sun Apr 12 01:10:54 2020
@@ -1,4 +1,4 @@
-# $NetBSD: usbdevices.config,v 1.37 2020/01/29 18:39:04 maya Exp $
+# $NetBSD: usbdevices.config,v 1.38 2020/04/12 01:10:54 simonb Exp $
#
# This file contains all USB related configuration.
# It is suitable for inclusion in a kernel config(5) file.
@@ -189,6 +189,9 @@ ucom* at uvscom? portno ?
umcs* at uhub? port ? # Moschip MCS7xxx serial adapter
ucom* at umcs? portno ?
+uxrcom* at uhub? port ? # Exar XR21V141x serial adapter
+ucom* at uxrcom? portno ?
+
# RIM BlackBerry
uberry* at uhub? port ?
Index: src/sys/dev/usb/usbdevs
diff -u src/sys/dev/usb/usbdevs:1.780 src/sys/dev/usb/usbdevs:1.781
--- src/sys/dev/usb/usbdevs:1.780 Sat Apr 11 06:54:59 2020
+++ src/sys/dev/usb/usbdevs Sun Apr 12 01:10:54 2020
@@ -1,4 +1,4 @@
-$NetBSD: usbdevs,v 1.780 2020/04/11 06:54:59 jdolecek Exp $
+$NetBSD: usbdevs,v 1.781 2020/04/12 01:10:54 simonb Exp $
/*-
* Copyright (c) 1998-2004 The NetBSD Foundation, Inc.
@@ -153,6 +153,7 @@ vendor PANASONIC 0x04da Panasonic (Matsu
vendor HUANHSIN 0x04dc Huan Hsin
vendor SHARP 0x04dd Sharp
vendor IIYAMA 0x04e1 Iiyama
+vendor EXAR 0x04e2 Exar
vendor SHUTTLE 0x04e6 Shuttle Technology
vendor SAMSUNG 0x04e8 Samsung Electronics
vendor ANNABOOKS 0x04ed Annabooks
@@ -1583,6 +1584,11 @@ product EPSON 1670 0x011f Perfection 16
/* e-TEK Labs products */
product ETEK 1COM 0x8007 Serial port
+/* Exar products */
+product EXAR XR21V1410 0x1410 XR21V1410 1 channel UART
+product EXAR XR21V1412 0x1412 XR21V1412 2 channel UART
+product EXAR XR21V1414 0x1414 XR21V1414 4 channel UART
+
/* Extended Systems products */
product EXTENDED XTNDACCESS 0x0100 XTNDAccess IrDA
Added files:
Index: src/share/man/man4/uxrcom.4
diff -u /dev/null src/share/man/man4/uxrcom.4:1.1
--- /dev/null Sun Apr 12 01:10:54 2020
+++ src/share/man/man4/uxrcom.4 Sun Apr 12 01:10:54 2020
@@ -0,0 +1,79 @@
+.\" $OpenBSD: uxrcom.4,v 1.1 2019/03/27 22:11:21 kettenis Exp $
+.\"
+.\" Copyright (c) 2019 Mark Kettenis <[email protected]>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: March 27 2019 $
+.Dt UXRCOM 4
+.Os
+.Sh NAME
+.Nm uxrcom
+.Nd Exar XR21V141x USB serial adapter
+.Sh SYNOPSIS
+.Cd "uxrcom* at uhub?"
+.Cd "ucom* at uxrcom?"
+.Sh HARDWARE
+The
+.Nm
+driver supports serial adapters based on the
+XR21V1410, XR21V1412 and XR21V1414 chipsets.
+Devices range from single port to eight port (implemented as a
+USB hub and two
+.Nm
+four port instances behind it).
+Examples of hardware known to work with this driver are:
+.Pp
+.Bl -tag -width Dv -offset indent -compact
+.It Gearmo GM-U28RS232 8 Port USB to Serial DB9 RS232 Adapter
+.El
+.Sh DESCRIPTION
+The
+.Nm
+driver attaches the Exar XR21V141x multiport chipset with individual
+port drivers via
+.Xr ucom 4 ,
+which makes it behave like a
+.Xr tty 4 .
+.Sh SEE ALSO
+.Xr tty 4 ,
+.Xr ucom 4 ,
+.Xr uhub 4 ,
+.Xr modem 4 ,
+.Xr usb 4
+.Sh HISTORY
+The
+.Nm
+device driver first appeared in
+.Ox 6.5
+and in
+.Nx 9.1 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver for the single port XR21V1410 was written by
+.An Mark Kettenis Aq Mt [email protected] .
+The multi-port
+.Nx
+driver is based on the
+.Ox
+driver but uses the common
+.Xr umodem 4
+framework.
+The
+.Nx
+driver was written by
+by
+.An Simon Burge
+.Aq [email protected] .
Index: src/sys/dev/usb/uxrcom.c
diff -u /dev/null src/sys/dev/usb/uxrcom.c:1.1
--- /dev/null Sun Apr 12 01:10:54 2020
+++ src/sys/dev/usb/uxrcom.c Sun Apr 12 01:10:54 2020
@@ -0,0 +1,323 @@
+/* $NetBSD: uxrcom.c,v 1.1 2020/04/12 01:10:54 simonb Exp $ */
+/* $OpenBSD: uxrcom.c,v 1.1 2019/03/27 22:08:51 kettenis Exp $ */
+
+/*
+ * Copyright (c) 1998, 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson ([email protected]) at
+ * Carlstedt Research & Technology and Simon Burge.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2006 Jonathan Gray <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: uxrcom.c,v 1.1 2020/04/12 01:10:54 simonb Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/tty.h>
+#include <sys/device.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbcdc.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdi_util.h>
+#include <dev/usb/usbdevs.h>
+#include <dev/usb/usbhist.h>
+
+#include <dev/usb/usbdevs.h>
+#include <dev/usb/ucomvar.h>
+#include <dev/usb/umodemvar.h>
+
+
+#define UXRCOMBUFSZ 64
+
+/* XXX uxrcomreg.h */
+#define XR_SET_REG 0
+#define XR_GET_REGN 1
+
+#define XR_FLOW_CONTROL 0x000c
+#define XR_FLOW_CONTROL_ON 1
+#define XR_FLOW_CONTROL_OFF 0
+#define XR_TX_BREAK 0x0014
+#define XR_TX_BREAK_ON 1
+#define XR_TX_BREAK_OFF 0
+#define XR_GPIO_SET 0x001d
+#define XR_GPIO_CLEAR 0x001e
+#define XR_GPIO3 (1 << 3)
+#define XR_GPIO5 (1 << 5)
+
+/* for XR_SET_REG/XR_GET_REGN specify which uart block to use */
+#define XR_UART_BLOCK(sc) (((sc)->sc_ctl_iface_no / 2) << NBBY)
+
+#ifdef UXRCOM_DEBUG
+#define DPRINTF(x) if (uxrcomdebug) printf x
+int uxrcomdebug = 0;
+#else
+#define DPRINTF(x)
+#endif
+
+
+static void uxrcom_set(void *, int, int, int);
+static int uxrcom_param(void *, int, struct termios *);
+static void uxrcom_break(void *, int, int);
+
+static const struct ucom_methods uxrcom_methods = {
+ .ucom_get_status = umodem_get_status,
+ .ucom_set = uxrcom_set,
+ .ucom_param = uxrcom_param,
+ .ucom_ioctl = NULL, /* TODO */
+ .ucom_open = umodem_open,
+ .ucom_close = umodem_close,
+};
+
+static const struct usb_devno uxrcom_devs[] = {
+ { USB_VENDOR_EXAR, USB_PRODUCT_EXAR_XR21V1410 },
+ { USB_VENDOR_EXAR, USB_PRODUCT_EXAR_XR21V1412 },
+ { USB_VENDOR_EXAR, USB_PRODUCT_EXAR_XR21V1414 },
+};
+#define uxrcom_lookup(v, p) usb_lookup(uxrcom_devs, v, p)
+
+static int uxrcom_match(device_t, cfdata_t, void *);
+static void uxrcom_attach(device_t, device_t, void *);
+static int uxrcom_detach(device_t, int);
+
+CFATTACH_DECL_NEW(uxrcom, sizeof(struct umodem_softc), uxrcom_match,
+ uxrcom_attach, uxrcom_detach, NULL);
+
+static int
+uxrcom_match(device_t parent, cfdata_t match, void *aux)
+{
+ struct usbif_attach_arg *uiaa = aux;
+
+ if (uiaa->uiaa_class != UICLASS_CDC ||
+ uiaa->uiaa_subclass != UISUBCLASS_ABSTRACT_CONTROL_MODEL ||
+ !(uiaa->uiaa_proto == UIPROTO_CDC_NOCLASS ||
+ uiaa->uiaa_proto == UIPROTO_CDC_AT))
+ return UMATCH_NONE;
+
+ return uxrcom_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL ?
+ UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
+}
+
+static void
+uxrcom_attach(device_t parent, device_t self, void *aux)
+{
+ struct umodem_softc *sc = device_private(self);
+ struct usbif_attach_arg *uiaa = aux;
+ struct ucom_attach_args ucaa;
+
+ memset(&ucaa, 0, sizeof(ucaa));
+
+ ucaa.ucaa_portno = UCOM_UNK_PORTNO;
+ ucaa.ucaa_methods = &uxrcom_methods;
+ ucaa.ucaa_info = NULL;
+
+ ucaa.ucaa_ibufsize = UXRCOMBUFSZ;
+ ucaa.ucaa_obufsize = UXRCOMBUFSZ;
+ ucaa.ucaa_ibufsizepad = UXRCOMBUFSZ;
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler");
+
+ if (umodem_common_attach(self, sc, uiaa, &ucaa))
+ return;
+ return;
+}
+
+static int
+uxrcom_detach(device_t self, int flags)
+{
+ struct umodem_softc *sc = device_private(self);
+
+ pmf_device_deregister(self);
+
+ return umodem_common_detach(sc, flags);
+}
+
+static void
+uxrcom_set(void *addr, int portno, int reg, int onoff)
+{
+ struct umodem_softc *sc = addr;
+ usb_device_request_t req;
+ uint16_t index;
+ uint8_t value;
+
+ if (sc->sc_dying)
+ return;
+
+ index = onoff ? XR_GPIO_SET : XR_GPIO_CLEAR;
+
+ switch (reg) {
+ case UCOM_SET_DTR:
+ value = XR_GPIO3;
+ break;
+ case UCOM_SET_RTS:
+ value = XR_GPIO5;
+ break;
+ case UCOM_SET_BREAK:
+ uxrcom_break(sc, portno, onoff);
+ return;
+ default:
+ return;
+ }
+ req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req.bRequest = XR_SET_REG;
+ USETW(req.wValue, value);
+ USETW(req.wIndex, index | XR_UART_BLOCK(sc));
+ USETW(req.wLength, 0);
+ usbd_do_request(sc->sc_udev, &req, NULL);
+}
+
+static usbd_status
+uxrcom_set_line_coding(struct umodem_softc *sc, usb_cdc_line_state_t *state)
+{
+ usb_device_request_t req;
+ usbd_status err;
+
+ DPRINTF(("%s: rate=%d fmt=%d parity=%d bits=%d\n", __func__,
+ UGETDW(state->dwDTERate), state->bCharFormat,
+ state->bParityType, state->bDataBits));
+
+ if (memcmp(state, &sc->sc_line_state, UCDC_LINE_STATE_LENGTH) == 0) {
+ DPRINTF(("%s: already set\n", __func__));
+ return USBD_NORMAL_COMPLETION;
+ }
+
+ req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+ req.bRequest = UCDC_SET_LINE_CODING;
+ USETW(req.wValue, 0);
+ USETW(req.wIndex, sc->sc_ctl_iface_no);
+ USETW(req.wLength, UCDC_LINE_STATE_LENGTH);
+
+ err = usbd_do_request(sc->sc_udev, &req, state);
+ if (err) {
+ DPRINTF(("%s: failed, err=%u\n", __func__, err));
+ return err;
+ }
+
+ sc->sc_line_state = *state;
+
+ return USBD_NORMAL_COMPLETION;
+}
+
+static int
+uxrcom_param(void *addr, int portno, struct termios *t)
+{
+ struct umodem_softc *sc = addr;
+ usb_device_request_t req;
+ usbd_status err;
+ usb_cdc_line_state_t ls;
+ uint8_t flowctrl;
+
+ if (sc->sc_dying)
+ return EIO;
+
+ /* slowest supported baud rate is 1200 bps, max is 12 Mbps */
+ if (t->c_ospeed < 1200 || t->c_ospeed > 12000000)
+ return (EINVAL);
+
+ USETDW(ls.dwDTERate, t->c_ospeed);
+ if (ISSET(t->c_cflag, CSTOPB))
+ ls.bCharFormat = UCDC_STOP_BIT_2;
+ else
+ ls.bCharFormat = UCDC_STOP_BIT_1;
+ if (ISSET(t->c_cflag, PARENB)) {
+ if (ISSET(t->c_cflag, PARODD))
+ ls.bParityType = UCDC_PARITY_ODD;
+ else
+ ls.bParityType = UCDC_PARITY_EVEN;
+ } else
+ ls.bParityType = UCDC_PARITY_NONE;
+ switch (ISSET(t->c_cflag, CSIZE)) {
+ case CS5:
+ ls.bDataBits = 5;
+ break;
+ case CS6:
+ ls.bDataBits = 6;
+ break;
+ case CS7:
+ ls.bDataBits = 7;
+ break;
+ case CS8:
+ ls.bDataBits = 8;
+ break;
+ }
+
+ err = uxrcom_set_line_coding(sc, &ls);
+ if (err) {
+ DPRINTF(("%s: err=%u\n", __func__, err));
+ return EIO;
+ }
+
+ if (ISSET(t->c_cflag, CRTSCTS)) {
+ /* rts/cts flow ctl */
+ flowctrl = XR_FLOW_CONTROL_ON;
+ } else {
+ /* disable flow ctl */
+ flowctrl = XR_FLOW_CONTROL_OFF;
+ }
+ req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req.bRequest = XR_SET_REG;
+ USETW(req.wValue, flowctrl);
+ USETW(req.wIndex, XR_FLOW_CONTROL | XR_UART_BLOCK(sc));
+ USETW(req.wLength, 0);
+ usbd_do_request(sc->sc_udev, &req, NULL);
+
+ return (0);
+}
+
+static void
+uxrcom_break(void *addr, int portno, int onoff)
+{
+ struct umodem_softc *sc = addr;
+ usb_device_request_t req;
+ uint8_t brk = onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF;
+
+ DPRINTF(("%s: port=%d onoff=%d\n", __func__, portno, onoff));
+
+ req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req.bRequest = XR_SET_REG;
+ USETW(req.wValue, brk);
+ USETW(req.wIndex, XR_TX_BREAK | XR_UART_BLOCK(sc));
+ USETW(req.wLength, 0);
+
+ (void)usbd_do_request(sc->sc_udev, &req, 0);
+}