>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     [EMAIL PROTECTED]:/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 [EMAIL PROTECTED]
X+in May 2007 and modified for the
X+.Nm
X+driver by
X+.An Jose Gordon Aq [EMAIL PROTECTED]
X+in April 2008.
X+.Sh AUTHORS
X+The
X+.Nm
X+driver was written by
X+.An Jose Gordon Aq [EMAIL PROTECTED] .
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 <[EMAIL PROTECTED]>.
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 ([EMAIL PROTECTED]).
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:
_______________________________________________
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to