usb/122621: New driver for Sierra Wireless 3G USM modem 875U

JOSE MARIA ROMERO GORDON romerogordon at telefonica.net
Thu Apr 10 12:30:02 UTC 2008


>Number:         122621
>Category:       usb
>Synopsis:       New driver for Sierra Wireless 3G USM modem 875U
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-usb
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 10 12:30:01 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     JOSE MARIA ROMERO GORDON
>Release:        7.0
>Organization:
RG
>Environment:
FreeBSD acer.paquito.org 7.0-RELEASE FreeBSD 7.0-RELEASE #2: Mon Mar 31 11:39:47 UTC 2008     root at acer.paquito.org:/usr/obj/usr/src/sys/ACER  i386
>Description:
This is a new driver (uswt) for the Sierra Wireless 3G USM modem 875U. It can be included into the kernel or added as a loadable module called uswt.ko. It creates an USB serial port which can be accessed as a common /dev/cuaUx. The associated serial port is the simplest one, without flow control, break signal neither selection of baudrates. The carrier detect has been set always high since this signal is not reported by the card and was the cause of many linkdowns with the ppp daemon. Nevertheless, the ppp daemon works nicely and even faster than working under Windows (download rates over 1.4 Mbps).

The source code is split into several "diff" patches plus a "sh" script which must be run in order to recreate a sys/modules/uswt directory. All the files have been packed by means of the "shar" utility.


>How-To-Repeat:

>Fix:


Patch attached with submission follows:

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	./patch1.txt
#	./patch2.txt
#	./patch3.txt
#	./patch4.txt
#	./patch5.txt
#	./patch6.txt
#	./patch7.txt
#	./patch8.sh
#
echo x - ./patch1.txt
sed 's/^X//' >./patch1.txt << 'END-of-./patch1.txt'
X--- /usr/src/share/man/man4/Makefile	2008-02-06 03:38:47.000000000 +0000
X+++ ./share/man/man4/Makefile	2008-04-10 09:23:19.000000000 +0000
X@@ -365,6 +365,7 @@
X 	uark.4 \
X 	uart.4 \
X 	ubsa.4 \
X+	uswt.4 \
X 	ubsec.4 \
X 	ubser.4 \
X 	ubtbcmfw.4 \
END-of-./patch1.txt
echo x - ./patch2.txt
sed 's/^X//' >./patch2.txt << 'END-of-./patch2.txt'
X--- /dev/null	2008-04-10 09:22:00.000000000 +0000
X+++ ./share/man/man4/uswt.4	2008-04-10 08:55:22.000000000 +0000
X@@ -0,0 +1,111 @@
X+.\"
X+.\" Copyright (c) 2001 The NetBSD Foundation, Inc.
X+.\" All rights reserved.
X+.\"
X+.\" This code is derived from software contributed to The NetBSD Foundation
X+.\" by Lennart Augustsson.
X+.\"
X+.\" Redistribution and use in source and binary forms, with or without
X+.\" modification, are permitted provided that the following conditions
X+.\" are met:
X+.\" 1. Redistributions of source code must retain the above copyright
X+.\"    notice, this list of conditions and the following disclaimer.
X+.\" 2. Redistributions in binary form must reproduce the above copyright
X+.\"    notice, this list of conditions and the following disclaimer in the
X+.\"    documentation and/or other materials provided with the distribution.
X+.\" 3. All advertising materials mentioning features or use of this software
X+.\"    must display the following acknowledgment:
X+.\"        This product includes software developed by the NetBSD
X+.\"        Foundation, Inc. and its contributors.
X+.\" 4. Neither the name of The NetBSD Foundation nor the names of its
X+.\"    contributors may be used to endorse or promote products derived
X+.\"    from this software without specific prior written permission.
X+.\"
X+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
X+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
X+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
X+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
X+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
X+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
X+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
X+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
X+.\" POSSIBILITY OF SUCH DAMAGE.
X+.\"
X+.\" $FreeBSD: src/share/man/man4/ubsa.4,v 1.10 2007/05/08 18:51:40 maxim Exp $
X+.\"
X+.Dd April 3, 2008
X+.Dt USWT 4
X+.Os
X+.Sh NAME
X+.Nm uswt
X+.Nd USB support for Sierra Wireless USB 3G modems
X+.Sh SYNOPSIS
X+To compile this driver into the kernel,
X+place the following lines in your
X+kernel configuration file:
X+.Bd -ragged -offset indent
X+.Cd "device uswt"
X+.Cd "device ucom"
X+.Ed
X+.Pp
X+Alternatively, to load the driver as a
X+module at boot time, place the following line in
X+.Xr loader.conf 5 :
X+.Bd -literal -offset indent
X+uswt_load="YES"
X+.Ed
X+.Sh DESCRIPTION
X+The
X+.Nm
X+driver provides support for Sierra Wireless 3G USB modems (875U model).
X+.Pp
X+The device is accessed through the
X+.Xr ucom 4
X+driver which makes it behave like a
X+.Xr tty 4 .
X+.Sh HARDWARE
X+The
X+.Nm
X+driver supports the following adapters:
X+.Pp
X+.Bl -bullet -compact
X+.It
X+Sierra Wireless 875U 3G USB modem
X+.El
X+.Pp
X+The supported 3G card provide the necessary modem port for ppp,
X+pppd, or mpd connections; other functions of these cards (diagnostic port,
X+SIM toolkit port, WLAN) are not supported.
X+.Pp
X+The associated serial port is the simplest one, without flow control,
X+break signal neither selection of baudrates. The carrier detect has
X+been set always high since this signal is not reported by the card and
X+was the cause of many linkdowns with the ppp daemon. Nevertheless, the
X+ppp daemon works nicely and even faster than working under Windows
X+(download rates over 1.4 Mbps).  
X+.Sh SEE ALSO
X+.Xr tty 4 ,
X+.Xr ucom 4 ,
X+.Xr usb 4
X+.Sh HISTORY
X+The
X+.Nm
X+driver
X+appeared in
X+.Fx 7.0 .
X+The
X+.Xr ubsa 4
X+manual page was writen by
X+.An Alexander Kabaev Aq kan at FreeBSD.org
X+in May 2007 and modified for the
X+.Nm
X+driver by
X+.An Jose Gordon Aq romerogordon at telefonica.net
X+in April 2008.
X+.Sh AUTHORS
X+The
X+.Nm
X+driver was written by
X+.An Jose Gordon Aq romerogordon at telefonica.net .
END-of-./patch2.txt
echo x - ./patch3.txt
sed 's/^X//' >./patch3.txt << 'END-of-./patch3.txt'
X--- /usr/src/sys/conf/files	2007-12-06 10:15:29.000000000 +0000
X+++ ./sys/conf/files	2008-04-10 09:00:52.000000000 +0000
X@@ -1113,6 +1113,7 @@
X dev/usb/slhci_pccard.c		optional slhci pccard
X dev/usb/uark.c			optional uark
X dev/usb/ubsa.c			optional ubsa
X+dev/usb/uswt.c                  optional uswt
X dev/usb/ubser.c			optional ubser
X dev/usb/ucom.c			optional ucom
X dev/usb/ucycom.c		optional ucycom
END-of-./patch3.txt
echo x - ./patch4.txt
sed 's/^X//' >./patch4.txt << 'END-of-./patch4.txt'
X--- /usr/src/sys/conf/NOTES	2007-09-26 21:14:17.000000000 +0000
X+++ ./sys/conf/NOTES	2008-04-10 09:00:48.000000000 +0000
X@@ -2442,6 +2442,8 @@
X device		uvisor
X # USB serial support for DDI pocket's PHS
X device		uvscom
X+# USB support for Sierra Wireless USB 3G modems (875U)
X+device		uswt
X #
X # ADMtek USB ethernet. Supports the LinkSys USB100TX,
X # the Billionton USB100, the Melco LU-ATX, the D-Link DSB-650TX
END-of-./patch4.txt
echo x - ./patch5.txt
sed 's/^X//' >./patch5.txt << 'END-of-./patch5.txt'
X--- /usr/src/sys/dev/usb/usbdevs	2008-01-07 23:12:45.000000000 +0000
X+++ ./sys/dev/usb/usbdevs	2008-04-10 08:49:36.000000000 +0000
X@@ -1381,6 +1381,7 @@
X 
X /* HUAWEI products */
X product HUAWEI MOBILE		0x1001	Huawei Mobile
X+product HUAWEI E220             0x1003  Huawei E220 HSDPA USB Modem
X 
X /* HUAWEI 3com products */
X product HUAWEI3COM WUB320G	0x0009	Aolynk WUB320g
X@@ -2021,6 +2022,7 @@
X /* Sierra Wireless products */
X product SIERRA AIRCARD580	0x0112	Sierra Wireless AirCard 580
X product SIERRA MC5720		0x0218	MC5720 Wireless Modem
X+product SIERRA 875U             0x6812  Sierra Wireless AirCard 875U HSDPA USB Modem
X 
X /* Sigmatel products */
X product SIGMATEL I_BEAD100	0x8008	i-Bead 100 MP3 Player
END-of-./patch5.txt
echo x - ./patch6.txt
sed 's/^X//' >./patch6.txt << 'END-of-./patch6.txt'
X--- /dev/null	2008-04-10 09:22:00.000000000 +0000
X+++ ./sys/dev/usb/uswt.c	2008-04-10 08:49:23.000000000 +0000
X@@ -0,0 +1,503 @@
X+/*-
X+ * Copyright (c) 2008, Jose Gordon <romerogordon at telefonica.net>.
X+ * All rights reserved.
X+ *
X+ * Redistribution and use in source and binary forms, with or without
X+ * modification, are permitted provided that the following conditions
X+ * are met:
X+ * 1. Redistributions of source code must retain the above copyright
X+ *    notice, this list of conditions and the following disclaimer.
X+ * 2. Redistributions in binary form must reproduce the above copyright
X+ *    notice, this list of conditions and the following disclaimer in the
X+ *    documentation and/or other materials provided with the distribution.
X+ *
X+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
X+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
X+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X+ * SUCH DAMAGE.
X+ */
X+/*-
X+ * Copyright (c) 2002, Alexander Kabaev <kan.FreeBSD.org>.
X+ * All rights reserved.
X+ *
X+ * Redistribution and use in source and binary forms, with or without
X+ * modification, are permitted provided that the following conditions
X+ * are met:
X+ * 1. Redistributions of source code must retain the above copyright
X+ *    notice, this list of conditions and the following disclaimer.
X+ * 2. Redistributions in binary form must reproduce the above copyright
X+ *    notice, this list of conditions and the following disclaimer in the
X+ *    documentation and/or other materials provided with the distribution.
X+ *
X+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
X+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
X+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X+ * SUCH DAMAGE.
X+ */
X+
X+#include <sys/cdefs.h>
X+__FBSDID("$FreeBSD: src/sys/dev/usb/uswt.c,v 1.32 2007/06/22 05:56:05 imp Exp $");
X+/*-
X+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
X+ * All rights reserved.
X+ *
X+ * This code is derived from software contributed to The NetBSD Foundation
X+ * by Ichiro FUKUHARA (ichiro at ichiro.org).
X+ *
X+ * Redistribution and use in source and binary forms, with or without
X+ * modification, are permitted provided that the following conditions
X+ * are met:
X+ * 1. Redistributions of source code must retain the above copyright
X+ *    notice, this list of conditions and the following disclaimer.
X+ * 2. Redistributions in binary form must reproduce the above copyright
X+ *    notice, this list of conditions and the following disclaimer in the
X+ *    documentation and/or other materials provided with the distribution.
X+ * 3. All advertising materials mentioning features or use of this software
X+ *    must display the following acknowledgement:
X+ *        This product includes software developed by the NetBSD
X+ *        Foundation, Inc. and its contributors.
X+ * 4. Neither the name of The NetBSD Foundation nor the names of its
X+ *    contributors may be used to endorse or promote products derived
X+ *    from this software without specific prior written permission.
X+ *
X+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
X+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
X+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
X+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
X+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
X+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
X+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
X+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
X+ * POSSIBILITY OF SUCH DAMAGE.
X+ */
X+
X+#include <sys/param.h>
X+#include <sys/systm.h>
X+#include <sys/kernel.h>
X+#include <sys/malloc.h>
X+#include <sys/module.h>
X+#include <sys/bus.h>
X+#include <sys/ioccom.h>
X+#include <sys/fcntl.h>
X+#include <sys/taskqueue.h>
X+#include <sys/conf.h>
X+#include <sys/tty.h>
X+#include <sys/file.h>
X+#include <sys/selinfo.h>
X+#include <sys/proc.h>
X+#include <sys/poll.h>
X+#include <sys/sysctl.h>
X+#include <sys/serial.h>
X+
X+#include <dev/usb/usb.h>
X+#include <dev/usb/usbcdc.h>
X+
X+#include <dev/usb/usbdi.h>
X+#include <dev/usb/usbdi_util.h>
X+#include "usbdevs.h"
X+#include <dev/usb/usb_quirks.h>
X+
X+#include <dev/usb/ucomvar.h>
X+
X+#define USWTBUFSZ	4096
X+
X+#ifndef USB_DEBUG
X+static int	uswtdebug = 0;
X+SYSCTL_NODE(_hw_usb, OID_AUTO, uswt, CTLFLAG_RW, 0, "USB uswt");
X+SYSCTL_INT(_hw_usb_uswt, OID_AUTO, debug, CTLFLAG_RW,
X+	   &uswtdebug, 0, "uswt debug level");
X+
X+#define	DPRINTFN(n, x)	do { \
X+				if (uswtdebug > (n)) \
X+					printf x; \
X+			} while (0)
X+#else
X+#define	DPRINTFN(n, x)
X+#endif
X+#define	DPRINTF(x) DPRINTFN(0, x)
X+
X+#define	USWT_MODVER		1	/* module version */
X+
X+#define	USWT_CONFIG_INDEX	1
X+#define	USWT_IFACE_INDEX	0
X+
X+#define	USWT_INTR_INTERVAL	100	/* ms */
X+
X+struct	uswt_softc {
X+	struct ucom_softc	sc_ucom;
X+
X+	int			sc_iface_number;	/* interface number */
X+
X+	usbd_interface_handle	sc_intr_iface;	/* interrupt interface */
X+	int			sc_intr_number;	/* interrupt number */
X+	usbd_pipe_handle	sc_intr_pipe;	/* interrupt pipe */
X+	u_char			*sc_intr_buf;	/* interrupt buffer */
X+	int			sc_isize;
X+
X+	u_char			sc_dtr;		/* current DTR state */
X+	u_char			sc_rts;		/* current RTS state */
X+
X+	u_char			sc_lsr;		/* Local status register */
X+	u_char			sc_msr;		/* uswt status register */
X+	struct task		sc_task;
X+};
X+
X+static	void uswt_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
X+static	void uswt_notify(void *, int count);
X+
X+static	void uswt_get_status(void *, int, u_char *, u_char *);
X+static	int  uswt_open(void *, int);
X+static	void uswt_close(void *, int);
X+
X+struct ucom_callback uswt_callback = {
X+	uswt_get_status,
X+	NULL,
X+	NULL,
X+	NULL,
X+	uswt_open,
X+	uswt_close,
X+	NULL,
X+	NULL
X+};
X+
X+static const struct uswt_product {
X+	uint16_t	vendor;
X+	uint16_t	product;
X+} uswt_products [] = {
X+	/* Sierra Wireless USB HSDPA 875U */
X+	{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_875U },
X+	{ 0, 0 }
X+};
X+
X+static device_probe_t uswt_match;
X+static device_attach_t uswt_attach;
X+static device_detach_t uswt_detach;
X+
X+static device_method_t uswt_methods[] = {
X+	/* Device interface */
X+	DEVMETHOD(device_probe, uswt_match),
X+	DEVMETHOD(device_attach, uswt_attach),
X+	DEVMETHOD(device_detach, uswt_detach),
X+	{ 0, 0 }
X+};
X+
X+static driver_t uswt_driver = {
X+	"ucom",
X+	uswt_methods,
X+	sizeof (struct uswt_softc)
X+};
X+
X+DRIVER_MODULE(uswt, uhub, uswt_driver, ucom_devclass, usbd_driver_load, 0);
X+MODULE_DEPEND(uswt, usb, 1, 1, 1);
X+MODULE_DEPEND(uswt, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
X+MODULE_VERSION(uswt, USWT_MODVER);
X+
X+static int
X+uswt_match(device_t self)
X+{
X+	struct usb_attach_arg *uaa = device_get_ivars(self);
X+	int i;
X+
X+	if (uaa->iface != NULL)
X+		return (UMATCH_NONE);
X+
X+	for (i = 0; uswt_products[i].vendor != 0; i++) {
X+		if (uswt_products[i].vendor == uaa->vendor &&
X+		    uswt_products[i].product == uaa->product) {
X+			return (UMATCH_VENDOR_PRODUCT);
X+		}
X+	}
X+	return (UMATCH_NONE);
X+}
X+
X+static int
X+uswt_attach(device_t self)
X+{
X+	struct uswt_softc *sc = device_get_softc(self);
X+	struct usb_attach_arg *uaa = device_get_ivars(self);
X+	usbd_device_handle dev;
X+	struct ucom_softc *ucom;
X+	usb_config_descriptor_t *cdesc;
X+	usb_interface_descriptor_t *id;
X+	usb_endpoint_descriptor_t *ed;
X+	usbd_status err;
X+	int i;
X+
X+	dev = uaa->device;
X+	ucom = &sc->sc_ucom;
X+
X+	/*
X+	 * initialize rts, dtr variables to something
X+	 * different from boolean 0, 1
X+	 */
X+	sc->sc_dtr = -1;
X+	sc->sc_rts = -1;
X+
X+	ucom->sc_dev = self;
X+	ucom->sc_udev = dev;
X+	ucom->sc_iface = uaa->iface;
X+
X+	DPRINTF(("uswt attach: sc = %p\n", sc));
X+
X+	/* initialize endpoints */
X+	ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
X+	sc->sc_intr_number = -1;
X+	sc->sc_intr_pipe = NULL;
X+
X+	/* Move the device into the configured state. */
X+	err = usbd_set_config_index(dev, USWT_CONFIG_INDEX, 1);
X+	if (err) {
X+		device_printf(ucom->sc_dev, "failed to set configuration: %s\n",
X+		    usbd_errstr(err));
X+		ucom->sc_dying = 1;
X+		goto error;
X+	}
X+
X+	/* get the config descriptor */
X+	cdesc = usbd_get_config_descriptor(ucom->sc_udev);
X+
X+	if (cdesc == NULL) {
X+		device_printf(ucom->sc_dev,
X+		    "failed to get configuration descriptor\n");
X+		ucom->sc_dying = 1;
X+		goto error;
X+	}
X+
X+	/* get the first interface */
X+	err = usbd_device2interface_handle(dev, USWT_IFACE_INDEX,
X+	    &ucom->sc_iface);
X+	if (err) {
X+		device_printf(ucom->sc_dev, "failed to get interface: %s\n",
X+		    usbd_errstr(err));
X+		ucom->sc_dying = 1;
X+		goto error;
X+	}
X+
X+	/* Find the endpoints */
X+
X+	id = usbd_get_interface_descriptor(ucom->sc_iface);
X+	sc->sc_iface_number = id->bInterfaceNumber;
X+
X+	for (i = 0; i < id->bNumEndpoints; i++) {
X+		ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
X+		if (ed == NULL) {
X+			device_printf(ucom->sc_dev,
X+			    "no endpoint descriptor for %d\n", i);
X+			ucom->sc_dying = 1;
X+			goto error;
X+		}
X+
X+		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
X+		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
X+			sc->sc_intr_number = ed->bEndpointAddress;
X+			sc->sc_isize = UGETW(ed->wMaxPacketSize);
X+		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
X+		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
X+			ucom->sc_bulkin_no = ed->bEndpointAddress;
X+			ucom->sc_ibufsize = USWTBUFSZ /* UGETW(ed->wMaxPacketSize) */;
X+		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
X+		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
X+			ucom->sc_bulkout_no = ed->bEndpointAddress;
X+			ucom->sc_obufsize = USWTBUFSZ /* UGETW(ed->wMaxPacketSize) */;
X+		}
X+	}
X+
X+	if (sc->sc_intr_number == -1) {
X+		device_printf(ucom->sc_dev, "Could not find interrupt in\n");
X+		ucom->sc_dying = 1;
X+		goto error;
X+	}
X+
X+	/* keep interface for interrupt */
X+	sc->sc_intr_iface = ucom->sc_iface;
X+
X+	if (ucom->sc_bulkin_no == -1) {
X+		device_printf(ucom->sc_dev, "Could not find data bulk in\n");
X+		ucom->sc_dying = 1;
X+		goto error;
X+	}
X+
X+	if (ucom->sc_bulkout_no == -1) {
X+		device_printf(ucom->sc_dev, "Could not find data bulk out\n");
X+		ucom->sc_dying = 1;
X+		goto error;
X+	}
X+
X+	ucom->sc_parent = sc;
X+	ucom->sc_portno = UCOM_UNK_PORTNO;
X+	/* bulkin, bulkout set above */
X+	ucom->sc_ibufsizepad = USWTBUFSZ /* ucom->sc_ibufsize */ ;
X+	ucom->sc_opkthdrlen = 0;
X+	ucom->sc_callback = &uswt_callback;
X+
X+	DPRINTF(("uswt: in = 0x%x, out = 0x%x, intr = 0x%x\n",
X+	    ucom->sc_bulkin_no, ucom->sc_bulkout_no, sc->sc_intr_number));
X+
X+	TASK_INIT(&sc->sc_task, 0, uswt_notify, sc); 
X+	ucom_attach(ucom);
X+	return 0;
X+
X+error:
X+	return ENXIO;
X+}
X+
X+static int
X+uswt_detach(device_t self)
X+{
X+	struct uswt_softc *sc = device_get_softc(self);
X+	int rv;
X+
X+	DPRINTF(("uswt_detach: sc = %p\n", sc));
X+
X+	if (sc->sc_intr_pipe != NULL) {
X+		usbd_abort_pipe(sc->sc_intr_pipe);
X+		usbd_close_pipe(sc->sc_intr_pipe);
X+		free(sc->sc_intr_buf, M_USBDEV);
X+		sc->sc_intr_pipe = NULL;
X+	}
X+
X+	sc->sc_ucom.sc_dying = 1;
X+#if 0
X+	taskqueue_drain(taskqueue_swi_giant);
X+#endif
X+	rv = ucom_detach(&sc->sc_ucom);
X+
X+	return (rv);
X+}
X+
X+static int
X+uswt_open(void *addr, int portno)
X+{
X+	struct uswt_softc *sc;
X+	int err;
X+
X+	sc = addr;
X+	if (sc->sc_ucom.sc_dying)
X+		return (ENXIO);
X+
X+	DPRINTF(("uswt_open: sc = %p\n", sc));
X+
X+	if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
X+		sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
X+		err = usbd_open_pipe_intr(sc->sc_intr_iface,
X+		    sc->sc_intr_number,
X+		    USBD_SHORT_XFER_OK,
X+		    &sc->sc_intr_pipe,
X+		    sc,
X+		    sc->sc_intr_buf,
X+		    sc->sc_isize,
X+		    uswt_intr,
X+		    USWT_INTR_INTERVAL);
X+		if (err) {
X+			device_printf(sc->sc_ucom.sc_dev,
X+			    "cannot open interrupt pipe (addr %d)\n",
X+			    sc->sc_intr_number);
X+			return (EIO);
X+		}
X+	}
X+
X+	return (0);
X+}
X+
X+static void
X+uswt_close(void *addr, int portno)
X+{
X+	struct uswt_softc *sc;
X+	int err;
X+
X+	sc = addr;
X+	if (sc->sc_ucom.sc_dying)
X+		return;
X+
X+	DPRINTF(("uswt_close: close\n"));
X+
X+	if (sc->sc_intr_pipe != NULL) {
X+		err = usbd_abort_pipe(sc->sc_intr_pipe);
X+		if (err)
X+			device_printf(sc->sc_ucom.sc_dev,
X+			    "abort interrupt pipe failed: %s\n",
X+			    usbd_errstr(err));
X+		err = usbd_close_pipe(sc->sc_intr_pipe);
X+		if (err)
X+			device_printf(sc->sc_ucom.sc_dev,
X+			    "close interrupt pipe failed: %s\n",
X+			    usbd_errstr(err));
X+		free(sc->sc_intr_buf, M_USBDEV);
X+		sc->sc_intr_pipe = NULL;
X+	}
X+}
X+
X+static void
X+uswt_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
X+{
X+	struct uswt_softc *sc;
X+	u_char *buf;
X+
X+	sc = priv;
X+	buf = sc->sc_intr_buf;
X+	if (sc->sc_ucom.sc_dying)
X+		return;
X+
X+	if (status != USBD_NORMAL_COMPLETION) {
X+		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
X+			return;
X+
X+		DPRINTF(("%s: uswt_intr: abnormal status: %s\n",
X+		    device_get_nameunit(sc->sc_ucom.sc_dev),
X+		    usbd_errstr(status)));
X+		usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
X+		return;
X+	}
X+
X+	/* incidentally, Belkin adapter status bits match UART 16550 bits */
X+	sc->sc_lsr = buf[2];
X+	sc->sc_msr = buf[3];
X+
X+	/* Sets DCD by default */
X+	sc->sc_msr |= SER_DCD;
X+
X+	DPRINTF(("%s: uswt lsr = 0x%02x, msr = 0x%02x\n",
X+	    device_get_nameunit(sc->sc_ucom.sc_dev), sc->sc_lsr, sc->sc_msr));
X+
X+	taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
X+}
X+
X+/* Handle delayed events. */
X+static void
X+uswt_notify(void *arg, int count)
X+{
X+	struct uswt_softc *sc;
X+
X+	sc = arg;
X+	ucom_status_change(&sc->sc_ucom);
X+}
X+
X+static void
X+uswt_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
X+{
X+	struct uswt_softc *sc;
X+
X+	DPRINTF(("uswt_get_status\n"));
X+
X+	sc = addr;
X+	if (lsr != NULL)
X+		*lsr = sc->sc_lsr;
X+	if (msr != NULL)
X+		*msr = sc->sc_msr;
X+}
END-of-./patch6.txt
echo x - ./patch7.txt
sed 's/^X//' >./patch7.txt << 'END-of-./patch7.txt'
X--- /usr/src/sys/modules/Makefile	2008-02-06 03:24:27.000000000 +0000
X+++ ./sys/modules/Makefile	2008-04-10 09:30:22.000000000 +0000
X@@ -262,6 +262,7 @@
X 	uark \
X 	uart \
X 	ubsa \
X+	uswt \
X 	ubsec \
X 	ubser \
X 	ucom \
END-of-./patch7.txt
echo x - ./patch8.sh
sed 's/^X//' >./patch8.sh << 'END-of-./patch8.sh'
X# This is a shell archive.  Save it in a file, remove anything before
X# this line, and then unpack it by entering "sh file".  Note, it may
X# create directories; files and directories will be owned by you and
X# have default permissions.
X#
X# This archive contains:
X#
X#	./sys/modules/uswt
X#	./sys/modules/uswt/@
X#	./sys/modules/uswt/Makefile
X#	./sys/modules/uswt/machine
X#
Xecho c - ./sys/modules/uswt
Xmkdir -p ./sys/modules/uswt > /dev/null 2>&1
Xecho c - ./sys/modules/uswt/@
Xln -s /usr/src/sys ./sys/modules/uswt/@ 
X#mkdir -p ./sys/modules/uswt/@ > /dev/null 2>&1
Xecho x - ./sys/modules/uswt/Makefile
Xsed 's/^X//' >./sys/modules/uswt/Makefile << 'END-of-./sys/modules/uswt/Makefile'
XX# $FreeBSD: src/sys/modules/ubsa/Makefile,v 1.4 2004/12/29 08:49:49 imp Exp $
XX
XXS=	${.CURDIR}/../..
XX.PATH: $S/dev/usb
XX
XXKMOD=	uswt
XXSRCS=	uswt.c ucomvar.h opt_usb.h device_if.h bus_if.h usbdevs.h
XX
XX.include <bsd.kmod.mk>
XEND-of-./sys/modules/uswt/Makefile
Xecho c - ./sys/modules/uswt/machine
X#mkdir -p ./sys/modules/uswt/machine > /dev/null 2>&1
Xln -s /usr/src/sys/i386/include ./sys/modules/uswt/machine
Xexit
X
END-of-./patch8.sh
exit



>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-usb mailing list