Clean up the USB driver directories, remove unbuilt source.
authorSascha Wildner <saw@online.de>
Sat, 5 Jan 2019 13:25:45 +0000 (14:25 +0100)
committerSascha Wildner <saw@online.de>
Sat, 5 Jan 2019 13:25:45 +0000 (14:25 +0100)
Remove old source that has not (yet) been ported. If any of these
drivers would get ported in the future, it would be from current
FreeBSD source anyway. Keeping the old source around just confuses
when grepping in /usr/src.

43 files changed:
Makefile_upgrade.inc
etc/devd.conf
etc/devd/Makefile
etc/devd/uath.conf [deleted file]
share/man/man4/Makefile
share/man/man4/miibus.4
share/man/man4/usb.4
share/man/man4/wlan.4
share/man/man4/wlan_amrr.4
sys/boot/dloader/loader-bootp.conf
sys/boot/dloader/loader.conf
sys/bus/u4b/input/atp.c [deleted file]
sys/bus/u4b/misc/udbp.c [deleted file]
sys/bus/u4b/misc/udbp.h [deleted file]
sys/bus/u4b/net/Makefile
sys/bus/u4b/net/if_rue.c [deleted file]
sys/bus/u4b/net/if_ruereg.h [deleted file]
sys/bus/u4b/net/if_usie.c [deleted file]
sys/bus/u4b/net/if_usievar.h [deleted file]
sys/bus/u4b/net/uhso.c [deleted file]
sys/bus/u4b/usb/Makefile
sys/bus/u4b/usb_compat_linux.c [deleted file]
sys/bus/u4b/usb_compat_linux.h [deleted file]
sys/bus/u4b/video/udl.c [deleted file]
sys/bus/u4b/video/udl.h [deleted file]
sys/bus/u4b/wlan/if_uath.c [deleted file]
sys/bus/u4b/wlan/if_uathreg.h [deleted file]
sys/bus/u4b/wlan/if_uathvar.h [deleted file]
sys/bus/u4b/wlan/if_upgt.c [deleted file]
sys/bus/u4b/wlan/if_upgtvar.h [deleted file]
sys/bus/u4b/wlan/if_ural.c [deleted file]
sys/bus/u4b/wlan/if_uralreg.h [deleted file]
sys/bus/u4b/wlan/if_uralvar.h [deleted file]
sys/bus/u4b/wlan/if_urtw.c [deleted file]
sys/bus/u4b/wlan/if_urtwreg.h [deleted file]
sys/bus/u4b/wlan/if_urtwvar.h [deleted file]
sys/bus/u4b/wlan/if_zyd.c [deleted file]
sys/bus/u4b/wlan/if_zydfw.h [deleted file]
sys/bus/u4b/wlan/if_zydreg.h [deleted file]
sys/dev/misc/ipmi/Makefile
sys/dev/misc/ipmi/ipmi_linux.c [deleted file]
sys/dev/misc/ipmi/ipmi_linux/Makefile [deleted file]
usr.sbin/802_11/wpa_supplicant/wpa_supplicant.8

index 46045a1..9f101e6 100644 (file)
@@ -3444,6 +3444,7 @@ TO_REMOVE+=/usr/include/sys/clist.h
 TO_REMOVE+=/usr/share/man/man2/sigstack.2.gz
 TO_REMOVE+=/usr/include/sys/input.h
 TO_REMOVE+=/usr/include/sys/linux_types.h
+TO_REMOVE+=/etc/devd/uath.conf
 
 .if !defined(WANT_INSTALLER)
 TO_REMOVE+=/usr/sbin/dfuibe_installer
index b83ed24..a686aea 100644 (file)
@@ -23,8 +23,8 @@ options {
                ida|iir|ips|isp|mlx|mly|mpr|mps|mpt|ncr|sym|trm)\
                [0-9]+";
        set wifi-driver-regex
-               "(ath|bwi|bwn|ipw|iwi|iwn|malo|mwl|ral|rsu|rum|run|uath|upgt|\
-               ural|urtw|urtwn|wi|wpi|wtap|zyd)[0-9]+";
+               "(ath|bwi|bwn|ipw|iwi|iwn|malo|mwl|ral|rsu|rum|run|\
+               urtw|urtwn|wi|wpi|wtap)[0-9]+";
 };
 
 # Note that the attach/detach with the highest value wins, so that one can
index 3ce6aa5..38a5166 100644 (file)
@@ -1,6 +1,6 @@
 # $FreeBSD: head/etc/devd/Makefile 261894 2014-02-14 15:31:48Z avg $
 
-FILES= uath.conf usb.conf
+FILES= usb.conf
 
 .if ${MACHINE_ARCH} == "x86_64"
 FILES+=        asus.conf
diff --git a/etc/devd/uath.conf b/etc/devd/uath.conf
deleted file mode 100644 (file)
index b2a9afa..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-# $FreeBSD: head/etc/devd/uath.conf 223566 2011-06-26 11:37:24Z gavin $
-#
-# Atheros USB wireless network device specific devd events
-
-# Accton
-#   SMCWUSBT-G2
-notify 100 {
-       match "system"          "USB";
-       match "subsystem"       "DEVICE";
-       match "type"            "ATTACH";
-       match "vendor"          "0x083a";
-       match "product"         "0x4507";
-       action "/usr/sbin/uathload -d /dev/$cdev";
-};
-
-# Atheros Communications
-#   AR5523
-notify 100 {
-       match "system"          "USB";
-       match "subsystem"       "DEVICE";
-       match "type"            "ATTACH";
-       match "vendor"          "0x168c";
-       match "product"         "0x0002";
-       action "/usr/sbin/uathload -d /dev/$cdev";
-};
-
-# Atheros Communications
-#   AR5523
-notify 100 {
-       match "system"          "USB";
-       match "subsystem"       "DEVICE";
-       match "type"            "ATTACH";
-       match "vendor"          "0x0cf3";
-       match "product"         "(0x0002|0x0004|0x0006)";
-       action "/usr/sbin/uathload -d /dev/$cdev";
-};
-
-# Conceptronic
-#   AR5523
-notify 100 {
-       match "system"          "USB";
-       match "subsystem"       "DEVICE";
-       match "type"            "ATTACH";
-       match "vendor"          "0x0d8e";
-       match "product"         "(0x7802|0x7812)";
-       action "/usr/sbin/uathload -d /dev/$cdev";
-};
-
-# D-Link
-#   DWL-AG132, DWL-G132 and DWL-AG122
-notify 100 {
-       match "system"          "USB";
-       match "subsystem"       "DEVICE";
-       match "type"            "ATTACH";
-       match "vendor"          "0x2001";
-       match "product"         "(0x3a01|0x3a03|0x3a05)";
-       action "/usr/sbin/uathload -d /dev/$cdev";
-};
-
-# D-Link
-#  DWA-120
-notify 100 {
-       match "system"          "USB";
-       match "subsystem"       "DEVICE";
-       match "type"            "ATTACH";
-       match "vendor"          "0x07d1";
-       match "product"         "0x3a0c";
-       action "/usr/sbin/uathload -d /dev/$cdev";
-};
-
-# Gigaset
-#   SMCWUSBT-G
-notify 100 {
-       match "system"          "USB";
-       match "subsystem"       "DEVICE";
-       match "type"            "ATTACH";
-       match "vendor"          "0x1690";
-       match "product"         "(0x0711|0x0713)";
-       action "/usr/sbin/uathload -d /dev/$cdev";
-};
-
-# Global Sun Technology
-#   AR5523
-notify 100 {
-       match "system"          "USB";
-       match "subsystem"       "DEVICE";
-       match "type"            "ATTACH";
-       match "vendor"          "0x16ab";
-       match "product"         "(0x7802|0x7812)";
-       action "/usr/sbin/uathload -d /dev/$cdev";
-};
-
-# BayNETGEAR
-#   WG111U
-notify 100 {
-       match "system"          "USB";
-       match "subsystem"       "DEVICE";
-       match "type"            "ATTACH";
-       match "vendor"          "0x0846";
-       match "product"         "0x4301";
-       action "/usr/sbin/uathload -d /dev/$cdev";
-};
-
-# Netgear
-#   WG111T and WPN111
-notify 100 {
-       match "system"          "USB";
-       match "subsystem"       "DEVICE";
-       match "type"            "ATTACH";
-       match "vendor"          "0x1385";
-       match "product"         "(0x4251|0x5f01)";
-       action "/usr/sbin/uathload -d /dev/$cdev";
-};
-
-# U-MEDIA Communications
-#   TEW-444UB and AR5523
-notify 100 {
-       match "system"          "USB";
-       match "subsystem"       "DEVICE";
-       match "type"            "ATTACH";
-       match "vendor"          "0x157e";
-       match "product"         "(0x3007|0x3206)";
-       action "/usr/sbin/uathload -d /dev/$cdev";
-};
-
-# Wistron NeWeb
-#   AR5523
-notify 100 {
-       match "system"          "USB";
-       match "subsystem"       "DEVICE";
-       match "type"            "ATTACH";
-       match "vendor"          "0x1435";
-       match "product"         "(0x0827|0x0829)";
-       action "/usr/sbin/uathload -d /dev/$cdev";
-};
-
-# Z-Com
-#   AR5523
-notify 100 {
-       match "system"          "USB";
-       match "subsystem"       "DEVICE";
-       match "type"            "ATTACH";
-       match "vendor"          "0x0cde";
-       match "product"         "0x0013";
-       action "/usr/sbin/uathload -d /dev/$cdev";
-};
index d6e41f3..e3d4afa 100644 (file)
@@ -497,7 +497,6 @@ MLINKS+=ral.4 if_ral.4
 MLINKS+=random.4 urandom.4
 MLINKS+=re.4 if_re.4
 MLINKS+=rl.4 if_rl.4
-#MLINKS+=rue.4 if_rue.4
 MLINKS+=rum.4 if_rum.4
 MLINKS+=run.4 if_run.4
 MLINKS+=sbsh.4 if_sbsh.4
@@ -546,7 +545,6 @@ MLINKS+=tx.4 if_tx.4
 MLINKS+=txp.4 if_txp.4
 MLINKS+=udav.4 if_udav.4
 MLINKS+=upmap.4 kpmap.4
-#MLINKS+=ural.4 if_ural.4
 MLINKS+=urndis.4 if_urndis.4
 MLINKS+=urtwn.4 if_urtwn.4
 MLINKS+=vga_switcheroo.4 apple_gmux.4
index c775590..6a59fdb 100644 (file)
@@ -93,8 +93,6 @@ AMD Am79C97x PCI 10/100
 RealTek 8139C+/8169/8169S/8110S
 .It Xr rl 4
 RealTek 8129/8139
-.\".It Xr rue 4
-.\"RealTek RTL8150 USB To Fast Ethernet
 .It Xr sf 4
 Adaptec AIC-6915
 .It Xr sis 4
@@ -155,7 +153,6 @@ but as a result are not well behaved newbus device drivers.
 .Xr pcn 4 ,
 .Xr re 4 ,
 .Xr rl 4 ,
-.\".Xr rue 4 ,
 .Xr sf 4 ,
 .Xr sis 4 ,
 .Xr sk 4 ,
index 4c459bb..3867ada 100644 (file)
@@ -112,8 +112,6 @@ USB Apple iPhone/iPad tethered Ethernet driver
 Kawasaki LSI KL5KUSB101B Ethernet driver
 .It Xr mos 4
 Moschip MCS7730/MCS7830/MCS7832 USB Ethernet driver
-.\".It Xr rue 4
-.\"RealTek RTL8150 Ethernet driver
 .It Xr udav 4
 Davicom DM9601 USB Ethernet driver
 .El
@@ -127,8 +125,6 @@ Ralink Technology RT2501USB/RT2601USB IEEE 802.11 driver
 Ralink Technology RT2700U/RT2800U/RT3000U IEEE 802.11 driver
 .\".It Xr ubt 4
 .\"Bluetooth adapters
-.\".It Xr ural 4
-.\"Ralink Technology RT2500USB IEEE 802.11 driver
 .It Xr urndis 4
 RNDIS USB ethernet driver
 .It Xr urtwn 4
@@ -274,7 +270,6 @@ specifications can be found at:
 .Xr ndis 4 ,
 .Xr ohci 4 ,
 .Xr pci 4 ,
-.\".Xr rue 4 ,
 .Xr rum 4 ,
 .Xr run 4 ,
 .Xr u3g 4 ,
index 37839be..425af52 100644 (file)
@@ -186,10 +186,6 @@ may not interoperate.
 .\".Xr rsu 4 ,
 .Xr rum 4 ,
 .Xr run 4 ,
-.\".Xr uath 4 ,
-.\".Xr upgt 4 ,
-.\".Xr ural 4 ,
-.\".Xr urtw 4 ,
 .Xr urtwn 4 ,
 .Xr wi 4 ,
 .Xr wlan_acl 4 ,
@@ -198,7 +194,6 @@ may not interoperate.
 .Xr wlan_wep 4 ,
 .Xr wlan_xauth 4 ,
 .Xr wpi 4
-.\".Xr zyd 4
 .Sh STANDARDS
 More information can be found in the IEEE 802.11 Standards.
 .Sh HISTORY
index b568f56..f1973f7 100644 (file)
@@ -44,10 +44,8 @@ algorithm for use by 802.11 device drivers.
 .Xr iwn 4 ,
 .Xr ral 4 ,
 .Xr rum 4 ,
-.\".Xr ural 4 ,
 .Xr wlan 4 ,
 .Xr wpi 4
-.\".Xr zyd 4
 .Sh STANDARDS
 More information can be found in the paper describing the
 .Em AMRR
index 0983948..e1f1d6a 100644 (file)
@@ -273,9 +273,7 @@ if_aue_load="NO"            # ADMtek USB ethernet
 if_axe_load="NO"               # ASIX Electronics AX88172 USB ethernet
 if_cue_load="NO"               # CATC USB ethernet
 if_kue_load="NO"               # Kawasaki LSI USB ethernet
-if_rue_load="NO"               # RealTek RTL8150 USB fast ethernet
 if_rum_load="NO"               # Ralink RT2501USB/RT2601USB 802.11 wireless NICs
-if_ural_load="NO"              # Ralink RT2500USB 802.11 wireless NICs
 snd_uaudio_load="NO"           # USB audio
 
 
index ec556b7..a2e5827 100644 (file)
@@ -277,9 +277,7 @@ if_aue_load="NO"            # ADMtek USB ethernet
 if_axe_load="NO"               # ASIX Electronics AX88172 USB ethernet
 if_cue_load="NO"               # CATC USB ethernet
 if_kue_load="NO"               # Kawasaki LSI USB ethernet
-if_rue_load="NO"               # RealTek RTL8150 USB fast ethernet
 if_rum_load="NO"               # Ralink RT2501USB/RT2601USB 802.11 wireless NICs
-if_ural_load="NO"              # Ralink RT2500USB 802.11 wireless NICs
 snd_uaudio_load="NO"           # USB audio
 
 
diff --git a/sys/bus/u4b/input/atp.c b/sys/bus/u4b/input/atp.c
deleted file mode 100644 (file)
index de02b38..0000000
+++ /dev/null
@@ -1,2233 +0,0 @@
-/*-
- * Copyright (c) 2009 Rohit Grover
- * All rights reserved.
- *
- * 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 AUTHOR 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 AUTHOR 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbhid.h>
-#include "usbdevs.h"
-
-#define USB_DEBUG_VAR atp_debug
-#include <dev/usb/usb_debug.h>
-
-#include <sys/mouse.h>
-
-#define ATP_DRIVER_NAME "atp"
-
-/*
- * Driver specific options: the following options may be set by
- * `options' statements in the kernel configuration file.
- */
-
-/* The multiplier used to translate sensor reported positions to mickeys. */
-#ifndef ATP_SCALE_FACTOR
-#define ATP_SCALE_FACTOR 48
-#endif
-
-/*
- * This is the age (in microseconds) beyond which a touch is
- * considered to be a slide; and therefore a tap event isn't registered.
- */
-#ifndef ATP_TOUCH_TIMEOUT
-#define ATP_TOUCH_TIMEOUT 125000
-#endif
-
-/*
- * A double-tap followed by a single-finger slide is treated as a
- * special gesture. The driver responds to this gesture by assuming a
- * virtual button-press for the lifetime of the slide. The following
- * threshold is the maximum time gap (in microseconds) between the two
- * tap events preceding the slide for such a gesture.
- */
-#ifndef ATP_DOUBLE_TAP_N_DRAG_THRESHOLD
-#define ATP_DOUBLE_TAP_N_DRAG_THRESHOLD 200000
-#endif
-
-/*
- * The device provides us only with pressure readings from an array of
- * X and Y sensors; for our algorithms, we need to interpret groups
- * (typically pairs) of X and Y readings as being related to a single
- * finger stroke. We can relate X and Y readings based on their times
- * of incidence. The coincidence window should be at least 10000us
- * since it is used against values from getmicrotime(), which has a
- * precision of around 10ms.
- */
-#ifndef ATP_COINCIDENCE_THRESHOLD
-#define ATP_COINCIDENCE_THRESHOLD  40000 /* unit: microseconds */
-#if ATP_COINCIDENCE_THRESHOLD > 100000
-#error "ATP_COINCIDENCE_THRESHOLD too large"
-#endif
-#endif /* #ifndef ATP_COINCIDENCE_THRESHOLD */
-
-/*
- * The wait duration (in microseconds) after losing a touch contact
- * before zombied strokes are reaped and turned into button events.
- */
-#define ATP_ZOMBIE_STROKE_REAP_WINDOW   50000
-#if ATP_ZOMBIE_STROKE_REAP_WINDOW > 100000
-#error "ATP_ZOMBIE_STROKE_REAP_WINDOW too large"
-#endif
-
-/* end of driver specific options */
-
-
-/* Tunables */
-static SYSCTL_NODE(_hw_usb, OID_AUTO, atp, CTLFLAG_RW, 0, "USB atp");
-
-#ifdef USB_DEBUG
-enum atp_log_level {
-       ATP_LLEVEL_DISABLED = 0,
-       ATP_LLEVEL_ERROR,
-       ATP_LLEVEL_DEBUG,       /* for troubleshooting */
-       ATP_LLEVEL_INFO,        /* for diagnostics */
-};
-static int atp_debug = ATP_LLEVEL_ERROR; /* the default is to only log errors */
-SYSCTL_INT(_hw_usb_atp, OID_AUTO, debug, CTLFLAG_RW,
-    &atp_debug, ATP_LLEVEL_ERROR, "ATP debug level");
-TUNABLE_INT("hw.usb.atp.debug", &atp_debug);
-#endif /* USB_DEBUG */
-
-static u_int atp_touch_timeout = ATP_TOUCH_TIMEOUT;
-SYSCTL_UINT(_hw_usb_atp, OID_AUTO, touch_timeout, CTLFLAG_RW,
-    &atp_touch_timeout, 125000, "age threshold (in micros) for a touch");
-TUNABLE_INT("hw.usb.atp.touch_timeout", &atp_touch_timeout);
-
-static u_int atp_double_tap_threshold = ATP_DOUBLE_TAP_N_DRAG_THRESHOLD;
-SYSCTL_UINT(_hw_usb_atp, OID_AUTO, double_tap_threshold, CTLFLAG_RW,
-    &atp_double_tap_threshold, ATP_DOUBLE_TAP_N_DRAG_THRESHOLD,
-    "maximum time (in micros) between a double-tap");
-TUNABLE_INT("hw.usb.atp.double_tap_threshold", &atp_double_tap_threshold);
-
-static u_int atp_mickeys_scale_factor = ATP_SCALE_FACTOR;
-static int atp_sysctl_scale_factor_handler(SYSCTL_HANDLER_ARGS);
-SYSCTL_PROC(_hw_usb_atp, OID_AUTO, scale_factor, CTLTYPE_UINT | CTLFLAG_RW,
-    &atp_mickeys_scale_factor, sizeof(atp_mickeys_scale_factor),
-    atp_sysctl_scale_factor_handler, "IU", "movement scale factor");
-TUNABLE_INT("hw.usb.atp.scale_factor", &atp_mickeys_scale_factor);
-
-static u_int atp_small_movement_threshold = ATP_SCALE_FACTOR >> 3;
-SYSCTL_UINT(_hw_usb_atp, OID_AUTO, small_movement, CTLFLAG_RW,
-    &atp_small_movement_threshold, ATP_SCALE_FACTOR >> 3,
-    "the small movement black-hole for filtering noise");
-TUNABLE_INT("hw.usb.atp.small_movement", &atp_small_movement_threshold);
-
-/*
- * The movement threshold for a stroke; this is the maximum difference
- * in position which will be resolved as a continuation of a stroke
- * component.
- */
-static u_int atp_max_delta_mickeys = ((3 * ATP_SCALE_FACTOR) >> 1);
-SYSCTL_UINT(_hw_usb_atp, OID_AUTO, max_delta_mickeys, CTLFLAG_RW,
-    &atp_max_delta_mickeys, ((3 * ATP_SCALE_FACTOR) >> 1),
-    "max. mickeys-delta which will match against an existing stroke");
-/*
- * Strokes which accumulate at least this amount of absolute movement
- * from the aggregate of their components are considered as
- * slides. Unit: mickeys.
- */
-static u_int atp_slide_min_movement = (ATP_SCALE_FACTOR >> 3);
-SYSCTL_UINT(_hw_usb_atp, OID_AUTO, slide_min_movement, CTLFLAG_RW,
-    &atp_slide_min_movement, (ATP_SCALE_FACTOR >> 3),
-    "strokes with at least this amt. of movement are considered slides");
-TUNABLE_INT("hw.usb.atp.slide_min_movement", &atp_slide_min_movement);
-
-/*
- * The minimum age of a stroke for it to be considered mature; this
- * helps filter movements (noise) from immature strokes. Units: interrupts.
- */
-static u_int atp_stroke_maturity_threshold = 2;
-SYSCTL_UINT(_hw_usb_atp, OID_AUTO, stroke_maturity_threshold, CTLFLAG_RW,
-    &atp_stroke_maturity_threshold, 2,
-    "the minimum age of a stroke for it to be considered mature");
-TUNABLE_INT("hw.usb.atp.stroke_maturity_threshold",
-               &atp_stroke_maturity_threshold);
-
-/* Accept pressure readings from sensors only if above this value. */
-static u_int atp_sensor_noise_threshold = 2;
-SYSCTL_UINT(_hw_usb_atp, OID_AUTO, sensor_noise_threshold, CTLFLAG_RW,
-    &atp_sensor_noise_threshold, 2,
-    "accept pressure readings from sensors only if above this value");
-
-/* Ignore pressure spans with cumulative press. below this value. */
-static u_int atp_pspan_min_cum_pressure = 10;
-SYSCTL_UINT(_hw_usb_atp, OID_AUTO, pspan_min_cum_pressure, CTLFLAG_RW,
-    &atp_pspan_min_cum_pressure, 10,
-    "ignore pressure spans with cumulative press. below this value");
-
-/* Maximum allowed width for pressure-spans.*/
-static u_int atp_pspan_max_width = 4;
-SYSCTL_UINT(_hw_usb_atp, OID_AUTO, pspan_max_width, CTLFLAG_RW,
-    &atp_pspan_max_width, 4,
-    "maximum allowed width (in sensors) for pressure-spans");
-
-/* We support three payload protocols */
-typedef enum {
-       ATP_PROT_GEYSER1,
-       ATP_PROT_GEYSER2,
-       ATP_PROT_GEYSER3,
-} atp_protocol;
-
-/* Define the various flavours of devices supported by this driver. */
-enum {
-       ATP_DEV_PARAMS_0,
-       ATP_DEV_PARAMS_PBOOK,
-       ATP_DEV_PARAMS_PBOOK_15A,
-       ATP_DEV_PARAMS_PBOOK_17,
-       ATP_N_DEV_PARAMS
-};
-struct atp_dev_params {
-       u_int            data_len;   /* for sensor data */
-       u_int            n_xsensors;
-       u_int            n_ysensors;
-       atp_protocol     prot;
-} atp_dev_params[ATP_N_DEV_PARAMS] = {
-       [ATP_DEV_PARAMS_0] = {
-               .data_len   = 64,
-               .n_xsensors = 20,
-               .n_ysensors = 10,
-               .prot       = ATP_PROT_GEYSER3
-       },
-       [ATP_DEV_PARAMS_PBOOK] = {
-               .data_len   = 81,
-               .n_xsensors = 16,
-               .n_ysensors = 16,
-               .prot       = ATP_PROT_GEYSER1
-       },
-       [ATP_DEV_PARAMS_PBOOK_15A] = {
-               .data_len   = 64,
-               .n_xsensors = 15,
-               .n_ysensors = 9,
-               .prot       = ATP_PROT_GEYSER2
-       },
-       [ATP_DEV_PARAMS_PBOOK_17] = {
-               .data_len   = 81,
-               .n_xsensors = 26,
-               .n_ysensors = 16,
-               .prot       = ATP_PROT_GEYSER1
-       },
-};
-
-static const STRUCT_USB_HOST_ID atp_devs[] = {
-       /* Core Duo MacBook & MacBook Pro */
-       { USB_VPI(USB_VENDOR_APPLE, 0x0217, ATP_DEV_PARAMS_0) },
-       { USB_VPI(USB_VENDOR_APPLE, 0x0218, ATP_DEV_PARAMS_0) },
-       { USB_VPI(USB_VENDOR_APPLE, 0x0219, ATP_DEV_PARAMS_0) },
-
-       /* Core2 Duo MacBook & MacBook Pro */
-       { USB_VPI(USB_VENDOR_APPLE, 0x021a, ATP_DEV_PARAMS_0) },
-       { USB_VPI(USB_VENDOR_APPLE, 0x021b, ATP_DEV_PARAMS_0) },
-       { USB_VPI(USB_VENDOR_APPLE, 0x021c, ATP_DEV_PARAMS_0) },
-
-       /* Core2 Duo MacBook3,1 */
-       { USB_VPI(USB_VENDOR_APPLE, 0x0229, ATP_DEV_PARAMS_0) },
-       { USB_VPI(USB_VENDOR_APPLE, 0x022a, ATP_DEV_PARAMS_0) },
-       { USB_VPI(USB_VENDOR_APPLE, 0x022b, ATP_DEV_PARAMS_0) },
-
-       /* 12 inch PowerBook and iBook */
-       { USB_VPI(USB_VENDOR_APPLE, 0x030a, ATP_DEV_PARAMS_PBOOK) },
-       { USB_VPI(USB_VENDOR_APPLE, 0x030b, ATP_DEV_PARAMS_PBOOK) },
-
-       /* 15 inch PowerBook */
-       { USB_VPI(USB_VENDOR_APPLE, 0x020e, ATP_DEV_PARAMS_PBOOK) },
-       { USB_VPI(USB_VENDOR_APPLE, 0x020f, ATP_DEV_PARAMS_PBOOK) },
-       { USB_VPI(USB_VENDOR_APPLE, 0x0215, ATP_DEV_PARAMS_PBOOK_15A) },
-
-       /* 17 inch PowerBook */
-       { USB_VPI(USB_VENDOR_APPLE, 0x020d, ATP_DEV_PARAMS_PBOOK_17) },
-
-};
-
-/*
- * The following structure captures the state of a pressure span along
- * an axis. Each contact with the touchpad results in separate
- * pressure spans along the two axes.
- */
-typedef struct atp_pspan {
-       u_int width;   /* in units of sensors */
-       u_int cum;     /* cumulative compression (from all sensors) */
-       u_int cog;     /* center of gravity */
-       u_int loc;     /* location (scaled using the mickeys factor) */
-       boolean_t matched; /* to track pspans as they match against strokes. */
-} atp_pspan;
-
-typedef enum atp_stroke_type {
-       ATP_STROKE_TOUCH,
-       ATP_STROKE_SLIDE,
-} atp_stroke_type;
-
-#define ATP_MAX_PSPANS_PER_AXIS 3
-
-typedef struct atp_stroke_component {
-       /* Fields encapsulating the pressure-span. */
-       u_int loc;              /* location (scaled) */
-       u_int cum_pressure;     /* cumulative compression */
-       u_int max_cum_pressure; /* max cumulative compression */
-       boolean_t matched; /*to track components as they match against pspans.*/
-
-       /* Fields containing information about movement. */
-       int   delta_mickeys;    /* change in location (un-smoothened movement)*/
-       int   pending;          /* cum. of pending short movements */
-       int   movement;         /* current smoothened movement */
-} atp_stroke_component;
-
-typedef enum atp_axis {
-       X = 0,
-       Y = 1
-} atp_axis;
-
-#define ATP_MAX_STROKES         (2 * ATP_MAX_PSPANS_PER_AXIS)
-
-/*
- * The following structure captures a finger contact with the
- * touchpad. A stroke comprises two p-span components and some state.
- */
-typedef struct atp_stroke {
-       atp_stroke_type      type;
-       struct timeval       ctime; /* create time; for coincident siblings. */
-       u_int                age;   /*
-                                    * Unit: interrupts; we maintain
-                                    * this value in addition to
-                                    * 'ctime' in order to avoid the
-                                    * expensive call to microtime()
-                                    * at every interrupt.
-                                    */
-
-       atp_stroke_component components[2];
-       u_int                velocity_squared; /*
-                                               * Average magnitude (squared)
-                                               * of recent velocity.
-                                               */
-       u_int                cum_movement; /* cum. absolute movement so far */
-
-       uint32_t             flags;  /* the state of this stroke */
-#define ATSF_ZOMBIE          0x1
-} atp_stroke;
-
-#define ATP_FIFO_BUF_SIZE        8 /* bytes */
-#define ATP_FIFO_QUEUE_MAXLEN   50 /* units */
-
-enum {
-       ATP_INTR_DT,
-       ATP_RESET,
-       ATP_N_TRANSFER,
-};
-
-struct atp_softc {
-       device_t               sc_dev;
-       struct usb_device     *sc_usb_device;
-#define MODE_LENGTH 8
-       char                   sc_mode_bytes[MODE_LENGTH]; /* device mode */
-       struct mtx             sc_mutex; /* for synchronization */
-       struct usb_xfer       *sc_xfer[ATP_N_TRANSFER];
-       struct usb_fifo_sc     sc_fifo;
-
-       struct atp_dev_params *sc_params;
-
-       mousehw_t              sc_hw;
-       mousemode_t            sc_mode;
-       u_int                  sc_pollrate;
-       mousestatus_t          sc_status;
-       u_int                  sc_state;
-#define ATP_ENABLED            0x01
-#define ATP_ZOMBIES_EXIST      0x02
-#define ATP_DOUBLE_TAP_DRAG    0x04
-#define ATP_VALID              0x08
-
-       u_int                  sc_left_margin;
-       u_int                  sc_right_margin;
-
-       atp_stroke             sc_strokes[ATP_MAX_STROKES];
-       u_int                  sc_n_strokes;
-
-       int8_t                *sensor_data; /* from interrupt packet */
-       int                   *base_x;      /* base sensor readings */
-       int                   *base_y;
-       int                   *cur_x;       /* current sensor readings */
-       int                   *cur_y;
-       int                   *pressure_x;  /* computed pressures */
-       int                   *pressure_y;
-
-       u_int                  sc_idlecount; /* preceding idle interrupts */
-#define ATP_IDLENESS_THRESHOLD 10
-
-       struct timeval         sc_reap_time;
-       struct timeval         sc_reap_ctime; /*ctime of siblings to be reaped*/
-};
-
-/*
- * The last byte of the sensor data contains status bits; the
- * following values define the meanings of these bits.
- */
-enum atp_status_bits {
-       ATP_STATUS_BUTTON      = (uint8_t)0x01, /* The button was pressed */
-       ATP_STATUS_BASE_UPDATE = (uint8_t)0x04, /* Data from an untouched pad.*/
-};
-
-typedef enum interface_mode {
-       RAW_SENSOR_MODE = (uint8_t)0x04,
-       HID_MODE        = (uint8_t)0x08
-} interface_mode;
-
-/*
- * function prototypes
- */
-static usb_fifo_cmd_t   atp_start_read;
-static usb_fifo_cmd_t   atp_stop_read;
-static usb_fifo_open_t  atp_open;
-static usb_fifo_close_t atp_close;
-static usb_fifo_ioctl_t atp_ioctl;
-
-static struct usb_fifo_methods atp_fifo_methods = {
-       .f_open       = &atp_open,
-       .f_close      = &atp_close,
-       .f_ioctl      = &atp_ioctl,
-       .f_start_read = &atp_start_read,
-       .f_stop_read  = &atp_stop_read,
-       .basename[0]  = ATP_DRIVER_NAME,
-};
-
-/* device initialization and shutdown */
-static usb_error_t   atp_req_get_report(struct usb_device *udev, void *data);
-static int           atp_set_device_mode(device_t dev, interface_mode mode);
-static void          atp_reset_callback(struct usb_xfer *, usb_error_t);
-static int           atp_enable(struct atp_softc *sc);
-static void          atp_disable(struct atp_softc *sc);
-static int           atp_softc_populate(struct atp_softc *);
-static void          atp_softc_unpopulate(struct atp_softc *);
-
-/* sensor interpretation */
-static __inline void atp_interpret_sensor_data(const int8_t *, u_int, atp_axis,
-                        int *, atp_protocol);
-static __inline void atp_get_pressures(int *, const int *, const int *, int);
-static void          atp_detect_pspans(int *, u_int, u_int, atp_pspan *,
-                        u_int *);
-
-/* movement detection */
-static boolean_t     atp_match_stroke_component(atp_stroke_component *,
-                         const atp_pspan *, atp_stroke_type);
-static void          atp_match_strokes_against_pspans(struct atp_softc *,
-                        atp_axis, atp_pspan *, u_int, u_int);
-static boolean_t     atp_update_strokes(struct atp_softc *,
-                        atp_pspan *, u_int, atp_pspan *, u_int);
-static __inline void atp_add_stroke(struct atp_softc *, const atp_pspan *,
-                        const atp_pspan *);
-static void          atp_add_new_strokes(struct atp_softc *, atp_pspan *,
-                        u_int, atp_pspan *, u_int);
-static void          atp_advance_stroke_state(struct atp_softc *,
-                        atp_stroke *, boolean_t *);
-static void          atp_terminate_stroke(struct atp_softc *, u_int);
-static __inline boolean_t atp_stroke_has_small_movement(const atp_stroke *);
-static __inline void atp_update_pending_mickeys(atp_stroke_component *);
-static void          atp_compute_smoothening_scale_ratio(atp_stroke *, int *,
-                        int *);
-static boolean_t     atp_compute_stroke_movement(atp_stroke *);
-
-/* tap detection */
-static __inline void atp_setup_reap_time(struct atp_softc *, struct timeval *);
-static void          atp_reap_zombies(struct atp_softc *, u_int *, u_int *);
-static void          atp_convert_to_slide(struct atp_softc *, atp_stroke *);
-
-/* updating fifo */
-static void          atp_reset_buf(struct atp_softc *sc);
-static void          atp_add_to_queue(struct atp_softc *, int, int, uint32_t);
-
-
-usb_error_t
-atp_req_get_report(struct usb_device *udev, void *data)
-{
-       struct usb_device_request req;
-
-       req.bmRequestType = UT_READ_CLASS_INTERFACE;
-       req.bRequest = UR_GET_REPORT;
-       USETW2(req.wValue, (uint8_t)0x03 /* type */, (uint8_t)0x00 /* id */);
-       USETW(req.wIndex, 0);
-       USETW(req.wLength, MODE_LENGTH);
-
-       return (usbd_do_request(udev, NULL /* mutex */, &req, data));
-}
-
-static int
-atp_set_device_mode(device_t dev, interface_mode mode)
-{
-       struct atp_softc     *sc;
-       usb_device_request_t  req;
-       usb_error_t           err;
-
-       if ((mode != RAW_SENSOR_MODE) && (mode != HID_MODE))
-               return (ENXIO);
-
-       sc = device_get_softc(dev);
-
-       sc->sc_mode_bytes[0] = mode;
-       req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
-       req.bRequest = UR_SET_REPORT;
-       USETW2(req.wValue, (uint8_t)0x03 /* type */, (uint8_t)0x00 /* id */);
-       USETW(req.wIndex, 0);
-       USETW(req.wLength, MODE_LENGTH);
-       err = usbd_do_request(sc->sc_usb_device, NULL, &req, sc->sc_mode_bytes);
-       if (err != USB_ERR_NORMAL_COMPLETION)
-               return (ENXIO);
-
-       return (0);
-}
-
-void
-atp_reset_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       usb_device_request_t   req;
-       struct usb_page_cache *pc;
-       struct atp_softc      *sc = usbd_xfer_softc(xfer);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_SETUP:
-               sc->sc_mode_bytes[0] = RAW_SENSOR_MODE;
-               req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
-               req.bRequest = UR_SET_REPORT;
-               USETW2(req.wValue,
-                   (uint8_t)0x03 /* type */, (uint8_t)0x00 /* id */);
-               USETW(req.wIndex, 0);
-               USETW(req.wLength, MODE_LENGTH);
-
-               pc = usbd_xfer_get_frame(xfer, 0);
-               usbd_copy_in(pc, 0, &req, sizeof(req));
-               pc = usbd_xfer_get_frame(xfer, 1);
-               usbd_copy_in(pc, 0, sc->sc_mode_bytes, MODE_LENGTH);
-
-               usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
-               usbd_xfer_set_frame_len(xfer, 1, MODE_LENGTH);
-               usbd_xfer_set_frames(xfer, 2);
-               usbd_transfer_submit(xfer);
-               break;
-
-       case USB_ST_TRANSFERRED:
-       default:
-               break;
-       }
-}
-
-static int
-atp_enable(struct atp_softc *sc)
-{
-       /* Allocate the dynamic buffers */
-       if (atp_softc_populate(sc) != 0) {
-               atp_softc_unpopulate(sc);
-               return (ENOMEM);
-       }
-
-       /* reset status */
-       memset(sc->sc_strokes, 0, sizeof(sc->sc_strokes));
-       sc->sc_n_strokes = 0;
-       memset(&sc->sc_status, 0, sizeof(sc->sc_status));
-       sc->sc_idlecount = 0;
-       sc->sc_state |= ATP_ENABLED;
-
-       DPRINTFN(ATP_LLEVEL_INFO, "enabled atp\n");
-       return (0);
-}
-
-static void
-atp_disable(struct atp_softc *sc)
-{
-       atp_softc_unpopulate(sc);
-
-       sc->sc_state &= ~(ATP_ENABLED | ATP_VALID);
-       DPRINTFN(ATP_LLEVEL_INFO, "disabled atp\n");
-}
-
-/* Allocate dynamic memory for some fields in softc. */
-static int
-atp_softc_populate(struct atp_softc *sc)
-{
-       const struct atp_dev_params *params = sc->sc_params;
-
-       if (params == NULL) {
-               DPRINTF("params uninitialized!\n");
-               return (ENXIO);
-       }
-       if (params->data_len) {
-               sc->sensor_data = malloc(params->data_len * sizeof(int8_t),
-                   M_USB, M_WAITOK);
-               if (sc->sensor_data == NULL) {
-                       DPRINTF("mem for sensor_data\n");
-                       return (ENXIO);
-               }
-       }
-
-       if (params->n_xsensors != 0) {
-               sc->base_x = malloc(params->n_xsensors * sizeof(*(sc->base_x)),
-                   M_USB, M_WAITOK);
-               if (sc->base_x == NULL) {
-                       DPRINTF("mem for sc->base_x\n");
-                       return (ENXIO);
-               }
-
-               sc->cur_x = malloc(params->n_xsensors * sizeof(*(sc->cur_x)),
-                   M_USB, M_WAITOK);
-               if (sc->cur_x == NULL) {
-                       DPRINTF("mem for sc->cur_x\n");
-                       return (ENXIO);
-               }
-
-               sc->pressure_x =
-                       malloc(params->n_xsensors * sizeof(*(sc->pressure_x)),
-                           M_USB, M_WAITOK);
-               if (sc->pressure_x == NULL) {
-                       DPRINTF("mem. for pressure_x\n");
-                       return (ENXIO);
-               }
-       }
-
-       if (params->n_ysensors != 0) {
-               sc->base_y = malloc(params->n_ysensors * sizeof(*(sc->base_y)),
-                   M_USB, M_WAITOK);
-               if (sc->base_y == NULL) {
-                       DPRINTF("mem for base_y\n");
-                       return (ENXIO);
-               }
-
-               sc->cur_y = malloc(params->n_ysensors * sizeof(*(sc->cur_y)),
-                   M_USB, M_WAITOK);
-               if (sc->cur_y == NULL) {
-                       DPRINTF("mem for cur_y\n");
-                       return (ENXIO);
-               }
-
-               sc->pressure_y =
-                       malloc(params->n_ysensors * sizeof(*(sc->pressure_y)),
-                           M_USB, M_WAITOK);
-               if (sc->pressure_y == NULL) {
-                       DPRINTF("mem. for pressure_y\n");
-                       return (ENXIO);
-               }
-       }
-
-       return (0);
-}
-
-/* Free dynamic memory allocated for some fields in softc. */
-static void
-atp_softc_unpopulate(struct atp_softc *sc)
-{
-       const struct atp_dev_params *params = sc->sc_params;
-
-       if (params == NULL) {
-               return;
-       }
-       if (params->n_xsensors != 0) {
-               if (sc->base_x != NULL) {
-                       free(sc->base_x, M_USB);
-                       sc->base_x = NULL;
-               }
-
-               if (sc->cur_x != NULL) {
-                       free(sc->cur_x, M_USB);
-                       sc->cur_x = NULL;
-               }
-
-               if (sc->pressure_x != NULL) {
-                       free(sc->pressure_x, M_USB);
-                       sc->pressure_x = NULL;
-               }
-       }
-       if (params->n_ysensors != 0) {
-               if (sc->base_y != NULL) {
-                       free(sc->base_y, M_USB);
-                       sc->base_y = NULL;
-               }
-
-               if (sc->cur_y != NULL) {
-                       free(sc->cur_y, M_USB);
-                       sc->cur_y = NULL;
-               }
-
-               if (sc->pressure_y != NULL) {
-                       free(sc->pressure_y, M_USB);
-                       sc->pressure_y = NULL;
-               }
-       }
-       if (sc->sensor_data != NULL) {
-               free(sc->sensor_data, M_USB);
-               sc->sensor_data = NULL;
-       }
-}
-
-/*
- * Interpret the data from the X and Y pressure sensors. This function
- * is called separately for the X and Y sensor arrays. The data in the
- * USB packet is laid out in the following manner:
- *
- * sensor_data:
- *            --,--,Y1,Y2,--,Y3,Y4,--,Y5,...,Y10, ... X1,X2,--,X3,X4
- *  indices:   0  1  2  3  4  5  6  7  8 ...  15  ... 20 21 22 23 24
- *
- * '--' (in the above) indicates that the value is unimportant.
- *
- * Information about the above layout was obtained from the
- * implementation of the AppleTouch driver in Linux.
- *
- * parameters:
- *   sensor_data
- *       raw sensor data from the USB packet.
- *   num
- *       The number of elements in the array 'arr'.
- *   axis
- *       Axis of data to fetch
- *   arr
- *       The array to be initialized with the readings.
- *   prot
- *       The protocol to use to interpret the data
- */
-static __inline void
-atp_interpret_sensor_data(const int8_t *sensor_data, u_int num, atp_axis axis,
-    int        *arr, atp_protocol prot)
-{
-       u_int i;
-       u_int di;   /* index into sensor data */
-
-       switch (prot) {
-       case ATP_PROT_GEYSER1:
-               /*
-                * For Geyser 1, the sensors are laid out in pairs
-                * every 5 bytes.
-                */
-               for (i = 0, di = (axis == Y) ? 1 : 2; i < 8; di += 5, i++) {
-                       arr[i] = sensor_data[di];
-                       arr[i+8] = sensor_data[di+2];
-                       if (axis == X && num > 16)
-                               arr[i+16] = sensor_data[di+40];
-               }
-
-               break;
-       case ATP_PROT_GEYSER2:
-       case ATP_PROT_GEYSER3:
-               for (i = 0, di = (axis == Y) ? 2 : 20; i < num; /* empty */ ) {
-                       arr[i++] = sensor_data[di++];
-                       arr[i++] = sensor_data[di++];
-                       di++;
-               }
-               break;
-       }
-}
-
-static __inline void
-atp_get_pressures(int *p, const int *cur, const int *base, int n)
-{
-       int i;
-
-       for (i = 0; i < n; i++) {
-               p[i] = cur[i] - base[i];
-               if (p[i] > 127)
-                       p[i] -= 256;
-               if (p[i] < -127)
-                       p[i] += 256;
-               if (p[i] < 0)
-                       p[i] = 0;
-
-               /*
-                * Shave off pressures below the noise-pressure
-                * threshold; this will reduce the contribution from
-                * lower pressure readings.
-                */
-               if (p[i] <= atp_sensor_noise_threshold)
-                       p[i] = 0; /* filter away noise */
-               else
-                       p[i] -= atp_sensor_noise_threshold;
-       }
-}
-
-static void
-atp_detect_pspans(int *p, u_int num_sensors,
-    u_int       max_spans, /* max # of pspans permitted */
-    atp_pspan  *spans,     /* finger spans */
-    u_int      *nspans_p)  /* num spans detected */
-{
-       u_int i;
-       int   maxp;             /* max pressure seen within a span */
-       u_int num_spans = 0;
-
-       enum atp_pspan_state {
-               ATP_PSPAN_INACTIVE,
-               ATP_PSPAN_INCREASING,
-               ATP_PSPAN_DECREASING,
-       } state; /* state of the pressure span */
-
-       /*
-        * The following is a simple state machine to track
-        * the phase of the pressure span.
-        */
-       memset(spans, 0, max_spans * sizeof(atp_pspan));
-       maxp = 0;
-       state = ATP_PSPAN_INACTIVE;
-       for (i = 0; i < num_sensors; i++) {
-               if (num_spans >= max_spans)
-                       break;
-
-               if (p[i] == 0) {
-                       if (state == ATP_PSPAN_INACTIVE) {
-                               /*
-                                * There is no pressure information for this
-                                * sensor, and we aren't tracking a finger.
-                                */
-                               continue;
-                       } else {
-                               state = ATP_PSPAN_INACTIVE;
-                               maxp = 0;
-                               num_spans++;
-                       }
-               } else {
-                       switch (state) {
-                       case ATP_PSPAN_INACTIVE:
-                               state = ATP_PSPAN_INCREASING;
-                               maxp  = p[i];
-                               break;
-
-                       case ATP_PSPAN_INCREASING:
-                               if (p[i] > maxp)
-                                       maxp = p[i];
-                               else if (p[i] <= (maxp >> 1))
-                                       state = ATP_PSPAN_DECREASING;
-                               break;
-
-                       case ATP_PSPAN_DECREASING:
-                               if (p[i] > p[i - 1]) {
-                                       /*
-                                        * This is the beginning of
-                                        * another span; change state
-                                        * to give the appearance that
-                                        * we're starting from an
-                                        * inactive span, and then
-                                        * re-process this reading in
-                                        * the next iteration.
-                                        */
-                                       num_spans++;
-                                       state = ATP_PSPAN_INACTIVE;
-                                       maxp  = 0;
-                                       i--;
-                                       continue;
-                               }
-                               break;
-                       }
-
-                       /* Update the finger span with this reading. */
-                       spans[num_spans].width++;
-                       spans[num_spans].cum += p[i];
-                       spans[num_spans].cog += p[i] * (i + 1);
-               }
-       }
-       if (state != ATP_PSPAN_INACTIVE)
-               num_spans++;    /* close the last finger span */
-
-       /* post-process the spans */
-       for (i = 0; i < num_spans; i++) {
-               /* filter away unwanted pressure spans */
-               if ((spans[i].cum < atp_pspan_min_cum_pressure) ||
-                   (spans[i].width > atp_pspan_max_width)) {
-                       if ((i + 1) < num_spans) {
-                               memcpy(&spans[i], &spans[i + 1],
-                                   (num_spans - i - 1) * sizeof(atp_pspan));
-                               i--;
-                       }
-                       num_spans--;
-                       continue;
-               }
-
-               /* compute this span's representative location */
-               spans[i].loc = spans[i].cog * atp_mickeys_scale_factor /
-                       spans[i].cum;
-
-               spans[i].matched = FALSE; /* not yet matched against a stroke */
-       }
-
-       *nspans_p = num_spans;
-}
-
-/*
- * Match a pressure-span against a stroke-component. If there is a
- * match, update the component's state and return TRUE.
- */
-static boolean_t
-atp_match_stroke_component(atp_stroke_component *component,
-    const atp_pspan *pspan, atp_stroke_type stroke_type)
-{
-       int   delta_mickeys;
-       u_int min_pressure;
-
-       delta_mickeys = pspan->loc - component->loc;
-
-       if (abs(delta_mickeys) > atp_max_delta_mickeys)
-               return (FALSE); /* the finger span is too far out; no match */
-
-       component->loc = pspan->loc;
-
-       /*
-        * A sudden and significant increase in a pspan's cumulative
-        * pressure indicates the incidence of a new finger
-        * contact. This usually revises the pspan's
-        * centre-of-gravity, and hence the location of any/all
-        * matching stroke component(s). But such a change should
-        * *not* be interpreted as a movement.
-        */
-       if (pspan->cum > ((3 * component->cum_pressure) >> 1))
-               delta_mickeys = 0;
-
-       component->cum_pressure = pspan->cum;
-       if (pspan->cum > component->max_cum_pressure)
-               component->max_cum_pressure = pspan->cum;
-
-       /*
-        * Disregard the component's movement if its cumulative
-        * pressure drops below a fraction of the maximum; this
-        * fraction is determined based on the stroke's type.
-        */
-       if (stroke_type == ATP_STROKE_TOUCH)
-               min_pressure = (3 * component->max_cum_pressure) >> 2;
-       else
-               min_pressure = component->max_cum_pressure >> 2;
-       if (component->cum_pressure < min_pressure)
-               delta_mickeys = 0;
-
-       component->delta_mickeys = delta_mickeys;
-       return (TRUE);
-}
-
-static void
-atp_match_strokes_against_pspans(struct atp_softc *sc, atp_axis axis,
-    atp_pspan *pspans, u_int n_pspans, u_int repeat_count)
-{
-       u_int i, j;
-       u_int repeat_index = 0;
-
-       /* Determine the index of the multi-span. */
-       if (repeat_count) {
-               u_int cum = 0;
-               for (i = 0; i < n_pspans; i++) {
-                       if (pspans[i].cum > cum) {
-                               repeat_index = i;
-                               cum = pspans[i].cum;
-                       }
-               }
-       }
-
-       for (i = 0; i < sc->sc_n_strokes; i++) {
-               atp_stroke *stroke  = &sc->sc_strokes[i];
-               if (stroke->components[axis].matched)
-                       continue; /* skip matched components */
-
-               for (j = 0; j < n_pspans; j++) {
-                       if (pspans[j].matched)
-                               continue; /* skip matched pspans */
-
-                       if (atp_match_stroke_component(
-                                   &stroke->components[axis], &pspans[j],
-                                   stroke->type)) {
-                               /* There is a match. */
-                               stroke->components[axis].matched = TRUE;
-
-                               /* Take care to repeat at the multi-span. */
-                               if ((repeat_count > 0) && (j == repeat_index))
-                                       repeat_count--;
-                               else
-                                       pspans[j].matched = TRUE;
-
-                               break; /* skip to the next stroke */
-                       }
-               } /* loop over pspans */
-       } /* loop over strokes */
-}
-
-/*
- * Update strokes by matching against current pressure-spans.
- * Return TRUE if any movement is detected.
- */
-static boolean_t
-atp_update_strokes(struct atp_softc *sc, atp_pspan *pspans_x,
-    u_int n_xpspans, atp_pspan *pspans_y, u_int n_ypspans)
-{
-       u_int       i, j;
-       atp_stroke *stroke;
-       boolean_t   movement = FALSE;
-       u_int       repeat_count = 0;
-
-       /* Reset X and Y components of all strokes as unmatched. */
-       for (i = 0; i < sc->sc_n_strokes; i++) {
-               stroke = &sc->sc_strokes[i];
-               stroke->components[X].matched = FALSE;
-               stroke->components[Y].matched = FALSE;
-       }
-
-       /*
-        * Usually, the X and Y pspans come in pairs (the common case
-        * being a single pair). It is possible, however, that
-        * multiple contacts resolve to a single pspan along an
-        * axis, as illustrated in the following:
-        *
-        *   F = finger-contact
-        *
-        *                pspan  pspan
-        *        +-----------------------+
-        *        |         .      .      |
-        *        |         .      .      |
-        *        |         .      .      |
-        *        |         .      .      |
-        *  pspan |.........F......F      |
-        *        |                       |
-        *        |                       |
-        *        |                       |
-        *        +-----------------------+
-        *
-        *
-        * The above case can be detected by a difference in the
-        * number of X and Y pspans. When this happens, X and Y pspans
-        * aren't easy to pair or match against strokes.
-        *
-        * When X and Y pspans differ in number, the axis with the
-        * smaller number of pspans is regarded as having a repeating
-        * pspan (or a multi-pspan)--in the above illustration, the
-        * Y-axis has a repeating pspan. Our approach is to try to
-        * match the multi-pspan repeatedly against strokes. The
-        * difference between the number of X and Y pspans gives us a
-        * crude repeat_count for matching multi-pspans--i.e. the
-        * multi-pspan along the Y axis (above) has a repeat_count of 1.
-        */
-       repeat_count = abs(n_xpspans - n_ypspans);
-
-       atp_match_strokes_against_pspans(sc, X, pspans_x, n_xpspans,
-           (((repeat_count != 0) && ((n_xpspans < n_ypspans))) ?
-               repeat_count : 0));
-       atp_match_strokes_against_pspans(sc, Y, pspans_y, n_ypspans,
-           (((repeat_count != 0) && (n_ypspans < n_xpspans)) ?
-               repeat_count : 0));
-
-       /* Update the state of strokes based on the above pspan matches. */
-       for (i = 0; i < sc->sc_n_strokes; i++) {
-               stroke = &sc->sc_strokes[i];
-               if (stroke->components[X].matched &&
-                   stroke->components[Y].matched) {
-                       atp_advance_stroke_state(sc, stroke, &movement);
-               } else {
-                       /*
-                        * At least one component of this stroke
-                        * didn't match against current pspans;
-                        * terminate it.
-                        */
-                       atp_terminate_stroke(sc, i);
-               }
-       }
-
-       /* Add new strokes for pairs of unmatched pspans */
-       for (i = 0; i < n_xpspans; i++) {
-               if (pspans_x[i].matched == FALSE) break;
-       }
-       for (j = 0; j < n_ypspans; j++) {
-               if (pspans_y[j].matched == FALSE) break;
-       }
-       if ((i < n_xpspans) && (j < n_ypspans)) {
-#ifdef USB_DEBUG
-               if (atp_debug >= ATP_LLEVEL_INFO) {
-                       printf("unmatched pspans:");
-                       for (; i < n_xpspans; i++) {
-                               if (pspans_x[i].matched)
-                                       continue;
-                               printf(" X:[loc:%u,cum:%u]",
-                                   pspans_x[i].loc, pspans_x[i].cum);
-                       }
-                       for (; j < n_ypspans; j++) {
-                               if (pspans_y[j].matched)
-                                       continue;
-                               printf(" Y:[loc:%u,cum:%u]",
-                                   pspans_y[j].loc, pspans_y[j].cum);
-                       }
-                       printf("\n");
-               }
-#endif /* USB_DEBUG */
-               if ((n_xpspans == 1) && (n_ypspans == 1))
-                       /* The common case of a single pair of new pspans. */
-                       atp_add_stroke(sc, &pspans_x[0], &pspans_y[0]);
-               else
-                       atp_add_new_strokes(sc,
-                           pspans_x, n_xpspans,
-                           pspans_y, n_ypspans);
-       }
-
-#ifdef USB_DEBUG
-       if (atp_debug >= ATP_LLEVEL_INFO) {
-               for (i = 0; i < sc->sc_n_strokes; i++) {
-                       atp_stroke *stroke = &sc->sc_strokes[i];
-
-                       printf(" %s%clc:%u,dm:%d,pnd:%d,cum:%d,max:%d,mv:%d%c"
-                           ",%clc:%u,dm:%d,pnd:%d,cum:%d,max:%d,mv:%d%c",
-                           (stroke->flags & ATSF_ZOMBIE) ? "zomb:" : "",
-                           (stroke->type == ATP_STROKE_TOUCH) ? '[' : '<',
-                           stroke->components[X].loc,
-                           stroke->components[X].delta_mickeys,
-                           stroke->components[X].pending,
-                           stroke->components[X].cum_pressure,
-                           stroke->components[X].max_cum_pressure,
-                           stroke->components[X].movement,
-                           (stroke->type == ATP_STROKE_TOUCH) ? ']' : '>',
-                           (stroke->type == ATP_STROKE_TOUCH) ? '[' : '<',
-                           stroke->components[Y].loc,
-                           stroke->components[Y].delta_mickeys,
-                           stroke->components[Y].pending,
-                           stroke->components[Y].cum_pressure,
-                           stroke->components[Y].max_cum_pressure,
-                           stroke->components[Y].movement,
-                           (stroke->type == ATP_STROKE_TOUCH) ? ']' : '>');
-               }
-               if (sc->sc_n_strokes)
-                       printf("\n");
-       }
-#endif /* USB_DEBUG */
-
-       return (movement);
-}
-
-/* Initialize a stroke using a pressure-span. */
-static __inline void
-atp_add_stroke(struct atp_softc *sc, const atp_pspan *pspan_x,
-    const atp_pspan *pspan_y)
-{
-       atp_stroke *stroke;
-
-       if (sc->sc_n_strokes >= ATP_MAX_STROKES)
-               return;
-       stroke = &sc->sc_strokes[sc->sc_n_strokes];
-
-       memset(stroke, 0, sizeof(atp_stroke));
-
-       /*
-        * Strokes begin as potential touches. If a stroke survives
-        * longer than a threshold, or if it records significant
-        * cumulative movement, then it is considered a 'slide'.
-        */
-       stroke->type = ATP_STROKE_TOUCH;
-       microtime(&stroke->ctime);
-       stroke->age  = 1;       /* Unit: interrupts */
-
-       stroke->components[X].loc              = pspan_x->loc;
-       stroke->components[X].cum_pressure     = pspan_x->cum;
-       stroke->components[X].max_cum_pressure = pspan_x->cum;
-       stroke->components[X].matched          = TRUE;
-
-       stroke->components[Y].loc              = pspan_y->loc;
-       stroke->components[Y].cum_pressure     = pspan_y->cum;
-       stroke->components[Y].max_cum_pressure = pspan_y->cum;
-       stroke->components[Y].matched          = TRUE;
-
-       sc->sc_n_strokes++;
-       if (sc->sc_n_strokes > 1) {
-               /* Reset double-tap-n-drag if we have more than one strokes. */
-               sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG;
-       }
-
-       DPRINTFN(ATP_LLEVEL_INFO, "[%u,%u], time: %u,%ld\n",
-           stroke->components[X].loc,
-           stroke->components[Y].loc,
-           (unsigned int)stroke->ctime.tv_sec,
-           (unsigned long int)stroke->ctime.tv_usec);
-}
-
-static void
-atp_add_new_strokes(struct atp_softc *sc, atp_pspan *pspans_x,
-    u_int n_xpspans, atp_pspan *pspans_y, u_int n_ypspans)
-{
-       int       i, j;
-       atp_pspan spans[2][ATP_MAX_PSPANS_PER_AXIS];
-       u_int     nspans[2];
-
-       /* Copy unmatched pspans into the local arrays. */
-       for (i = 0, nspans[X] = 0; i < n_xpspans; i++) {
-               if (pspans_x[i].matched == FALSE) {
-                       spans[X][nspans[X]] = pspans_x[i];
-                       nspans[X]++;
-               }
-       }
-       for (j = 0, nspans[Y] = 0; j < n_ypspans; j++) {
-               if (pspans_y[j].matched == FALSE) {
-                       spans[Y][nspans[Y]] = pspans_y[j];
-                       nspans[Y]++;
-               }
-       }
-
-       if (nspans[X] == nspans[Y]) {
-               /* Create new strokes from pairs of unmatched pspans */
-               for (i = 0, j = 0; (i < nspans[X]) && (j < nspans[Y]); i++, j++)
-                       atp_add_stroke(sc, &spans[X][i], &spans[Y][j]);
-       } else {
-               u_int    cum = 0;
-               atp_axis repeat_axis;      /* axis with multi-pspans */
-               u_int    repeat_count;     /* repeat count for the multi-pspan*/
-               u_int    repeat_index = 0; /* index of the multi-span */
-
-               repeat_axis  = (nspans[X] > nspans[Y]) ? Y : X;
-               repeat_count = abs(nspans[X] - nspans[Y]);
-               for (i = 0; i < nspans[repeat_axis]; i++) {
-                       if (spans[repeat_axis][i].cum > cum) {
-                               repeat_index = i;
-                               cum = spans[repeat_axis][i].cum;
-                       }
-               }
-
-               /* Create new strokes from pairs of unmatched pspans */
-               i = 0, j = 0;
-               for (; (i < nspans[X]) && (j < nspans[Y]); i++, j++) {
-                       atp_add_stroke(sc, &spans[X][i], &spans[Y][j]);
-
-                       /* Take care to repeat at the multi-pspan. */
-                       if (repeat_count > 0) {
-                               if ((repeat_axis == X) &&
-                                   (repeat_index == i)) {
-                                       i--; /* counter loop increment */
-                                       repeat_count--;
-                               } else if ((repeat_axis == Y) &&
-                                   (repeat_index == j)) {
-                                       j--; /* counter loop increment */
-                                       repeat_count--;
-                               }
-                       }
-               }
-       }
-}
-
-/*
- * Advance the state of this stroke--and update the out-parameter
- * 'movement' as a side-effect.
- */
-void
-atp_advance_stroke_state(struct atp_softc *sc, atp_stroke *stroke,
-    boolean_t *movement)
-{
-       stroke->age++;
-       if (stroke->age <= atp_stroke_maturity_threshold) {
-               /* Avoid noise from immature strokes. */
-               stroke->components[X].delta_mickeys = 0;
-               stroke->components[Y].delta_mickeys = 0;
-       }
-
-       /* Revitalize stroke if it had previously been marked as a zombie. */
-       if (stroke->flags & ATSF_ZOMBIE)
-               stroke->flags &= ~ATSF_ZOMBIE;
-
-       if (atp_compute_stroke_movement(stroke))
-               *movement = TRUE;
-
-       if (stroke->type != ATP_STROKE_TOUCH)
-               return;
-
-       /* Convert touch strokes to slides upon detecting movement or age. */
-       if (stroke->cum_movement >= atp_slide_min_movement) {
-               atp_convert_to_slide(sc, stroke);
-       } else {
-               /* If a touch stroke is found to be older than the
-                * touch-timeout threshold, it should be converted to
-                * a slide; except if there is a co-incident sibling
-                * with a later creation time.
-                *
-                * When multiple fingers make contact with the
-                * touchpad, they are likely to be separated in their
-                * times of incidence.  During a multi-finger tap,
-                * therefore, the last finger to make
-                * contact--i.e. the one with the latest
-                * 'ctime'--should be used to determine how the
-                * touch-siblings get treated; otherwise older
-                * siblings may lapse the touch-timeout and get
-                * converted into slides prematurely.  The following
-                * loop determines if there exists another touch
-                * stroke with a larger 'ctime' than the current
-                * stroke (NOTE: zombies with a larger 'ctime' are
-                * also considered) .
-                */
-
-               u_int i;
-               for (i = 0; i < sc->sc_n_strokes; i++) {
-                       if ((&sc->sc_strokes[i] == stroke) ||
-                           (sc->sc_strokes[i].type != ATP_STROKE_TOUCH))
-                               continue;
-
-                       if (timevalcmp(&sc->sc_strokes[i].ctime,
-                               &stroke->ctime, >))
-                               break;
-               }
-               if (i == sc->sc_n_strokes) {
-                       /* Found no other touch stroke with a larger 'ctime'. */
-                       struct timeval tdiff;
-
-                       /* Compute the stroke's age. */
-                       getmicrotime(&tdiff);
-                       if (timevalcmp(&tdiff, &stroke->ctime, >))
-                               timevalsub(&tdiff, &stroke->ctime);
-                       else {
-                               /*
-                                * If we are here, it is because getmicrotime
-                                * reported the current time as being behind
-                                * the stroke's start time; getmicrotime can
-                                * be imprecise.
-                                */
-                               tdiff.tv_sec  = 0;
-                               tdiff.tv_usec = 0;
-                       }
-
-                       if ((tdiff.tv_sec > (atp_touch_timeout / 1000000)) ||
-                           ((tdiff.tv_sec == (atp_touch_timeout / 1000000)) &&
-                               (tdiff.tv_usec >=
-                                   (atp_touch_timeout % 1000000))))
-                               atp_convert_to_slide(sc, stroke);
-               }
-       }
-}
-
-/* Switch a given touch stroke to being a slide. */
-void
-atp_convert_to_slide(struct atp_softc *sc, atp_stroke *stroke)
-{
-       stroke->type = ATP_STROKE_SLIDE;
-
-       /* Are we at the beginning of a double-click-n-drag? */
-       if ((sc->sc_n_strokes == 1) &&
-           ((sc->sc_state & ATP_ZOMBIES_EXIST) == 0) &&
-           timevalcmp(&stroke->ctime, &sc->sc_reap_time, >)) {
-               struct timeval delta;
-               struct timeval window = {
-                       atp_double_tap_threshold / 1000000,
-                       atp_double_tap_threshold % 1000000
-               };
-
-               delta = stroke->ctime;
-               timevalsub(&delta, &sc->sc_reap_time);
-               if (timevalcmp(&delta, &window, <=))
-                       sc->sc_state |= ATP_DOUBLE_TAP_DRAG;
-       }
-}
-
-/*
- * Terminate a stroke. While SLIDE strokes are dropped, TOUCH strokes
- * are retained as zombies so as to reap all their siblings together;
- * this helps establish the number of fingers involved in the tap.
- */
-static void
-atp_terminate_stroke(struct atp_softc *sc,
-    u_int index) /* index of the stroke to be terminated */
-{
-       atp_stroke *s = &sc->sc_strokes[index];
-
-       if (s->flags & ATSF_ZOMBIE) {
-               return;
-       }
-
-       if ((s->type == ATP_STROKE_TOUCH) &&
-           (s->age > atp_stroke_maturity_threshold)) {
-               s->flags |= ATSF_ZOMBIE;
-
-               /* If no zombies exist, then prepare to reap zombies later. */
-               if ((sc->sc_state & ATP_ZOMBIES_EXIST) == 0) {
-                       atp_setup_reap_time(sc, &s->ctime);
-                       sc->sc_state |= ATP_ZOMBIES_EXIST;
-               }
-       } else {
-               /* Drop this stroke. */
-               memcpy(&sc->sc_strokes[index], &sc->sc_strokes[index + 1],
-                   (sc->sc_n_strokes - index - 1) * sizeof(atp_stroke));
-               sc->sc_n_strokes--;
-
-               /*
-                * Reset the double-click-n-drag at the termination of
-                * any slide stroke.
-                */
-               sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG;
-       }
-}
-
-static __inline boolean_t
-atp_stroke_has_small_movement(const atp_stroke *stroke)
-{
-       return ((abs(stroke->components[X].delta_mickeys) <=
-               atp_small_movement_threshold) &&
-           (abs(stroke->components[Y].delta_mickeys) <=
-               atp_small_movement_threshold));
-}
-
-/*
- * Accumulate delta_mickeys into the component's 'pending' bucket; if
- * the aggregate exceeds the small_movement_threshold, then retain
- * delta_mickeys for later.
- */
-static __inline void
-atp_update_pending_mickeys(atp_stroke_component *component)
-{
-       component->pending += component->delta_mickeys;
-       if (abs(component->pending) <= atp_small_movement_threshold)
-               component->delta_mickeys = 0;
-       else {
-               /*
-                * Penalise pending mickeys for having accumulated
-                * over short deltas. This operation has the effect of
-                * scaling down the cumulative contribution of short
-                * movements.
-                */
-               component->pending -= (component->delta_mickeys << 1);
-       }
-}
-
-
-static void
-atp_compute_smoothening_scale_ratio(atp_stroke *stroke, int *numerator,
-    int *denominator)
-{
-       int   dxdt;
-       int   dydt;
-       u_int vel_squared; /* Square of the velocity vector's magnitude. */
-       u_int vel_squared_smooth;
-
-       /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
-       static uint8_t sqrt_table[256] = {
-               10, 14, 17, 20, 22, 24, 26, 28,
-               30, 31, 33, 34, 36, 37, 38, 40,
-               41, 42, 43, 44, 45, 46, 47, 48,
-               50, 50, 51, 52, 53, 54, 55, 56,
-               57, 58, 59, 60, 60, 61, 62, 63,
-               64, 64, 65, 66, 67, 67, 68, 69,
-               70, 70, 71, 72, 72, 73, 74, 74,
-               75, 76, 76, 77, 78, 78, 79, 80,
-               80, 81, 81, 82, 83, 83, 84, 84,
-               85, 86, 86, 87, 87, 88, 88, 89,
-               90, 90, 91, 91, 92, 92, 93, 93,
-               94, 94, 95, 95, 96, 96, 97, 97,
-               98, 98, 99, 100, 100, 100, 101, 101,
-               102, 102, 103, 103, 104, 104, 105, 105,
-               106, 106, 107, 107, 108, 108, 109, 109,
-               110, 110, 110, 111, 111, 112, 112, 113,
-               113, 114, 114, 114, 115, 115, 116, 116,
-               117, 117, 117, 118, 118, 119, 119, 120,
-               120, 120, 121, 121, 122, 122, 122, 123,
-               123, 124, 124, 124, 125, 125, 126, 126,
-               126, 127, 127, 128, 128, 128, 129, 129,
-               130, 130, 130, 131, 131, 131, 132, 132,
-               133, 133, 133, 134, 134, 134, 135, 135,
-               136, 136, 136, 137, 137, 137, 138, 138,
-               138, 139, 139, 140, 140, 140, 141, 141,
-               141, 142, 142, 142, 143, 143, 143, 144,
-               144, 144, 145, 145, 145, 146, 146, 146,
-               147, 147, 147, 148, 148, 148, 149, 149,
-               150, 150, 150, 150, 151, 151, 151, 152,
-               152, 152, 153, 153, 153, 154, 154, 154,
-               155, 155, 155, 156, 156, 156, 157, 157,
-               157, 158, 158, 158, 159, 159, 159, 160
-       };
-       const u_int N = NELEM(sqrt_table);
-
-       dxdt = stroke->components[X].delta_mickeys;
-       dydt = stroke->components[Y].delta_mickeys;
-
-       *numerator = 0, *denominator = 0; /* default values. */
-
-       /* Compute a smoothened magnitude_squared of the stroke's velocity. */
-       vel_squared = dxdt * dxdt + dydt * dydt;
-       vel_squared_smooth = (3 * stroke->velocity_squared + vel_squared) >> 2;
-       stroke->velocity_squared = vel_squared_smooth; /* retained as history */
-       if ((vel_squared == 0) || (vel_squared_smooth == 0))
-               return; /* returning (numerator == 0) will imply zero movement*/
-
-       /*
-        * In order to determine the overall movement scale factor,
-        * we're actually interested in the effect of smoothening upon
-        * the *magnitude* of velocity; i.e. we need to compute the
-        * square-root of (vel_squared_smooth / vel_squared) in the
-        * form of a numerator and denominator.
-        */
-
-       /* Keep within the bounds of the square-root table. */
-       while ((vel_squared > N) || (vel_squared_smooth > N)) {
-               /* Dividing uniformly by 2 won't disturb the final ratio. */
-               vel_squared        >>= 1;
-               vel_squared_smooth >>= 1;
-       }
-
-       *numerator   = sqrt_table[vel_squared_smooth - 1];
-       *denominator = sqrt_table[vel_squared - 1];
-}
-
-/*
- * Compute a smoothened value for the stroke's movement from
- * delta_mickeys in the X and Y components.
- */
-static boolean_t
-atp_compute_stroke_movement(atp_stroke *stroke)
-{
-       int   num;              /* numerator of scale ratio */
-       int   denom;            /* denominator of scale ratio */
-
-       /*
-        * Short movements are added first to the 'pending' bucket,
-        * and then acted upon only when their aggregate exceeds a
-        * threshold. This has the effect of filtering away movement
-        * noise.
-        */
-       if (atp_stroke_has_small_movement(stroke)) {
-               atp_update_pending_mickeys(&stroke->components[X]);
-               atp_update_pending_mickeys(&stroke->components[Y]);
-       } else {                /* large movement */
-               /* clear away any pending mickeys if there are large movements*/
-               stroke->components[X].pending = 0;
-               stroke->components[Y].pending = 0;
-       }
-
-       /* Get the scale ratio and smoothen movement. */
-       atp_compute_smoothening_scale_ratio(stroke, &num, &denom);
-       if ((num == 0) || (denom == 0)) {
-               stroke->components[X].movement = 0;
-               stroke->components[Y].movement = 0;
-               stroke->velocity_squared >>= 1; /* Erode velocity_squared. */
-       } else {
-               stroke->components[X].movement =
-                       (stroke->components[X].delta_mickeys * num) / denom;
-               stroke->components[Y].movement =
-                       (stroke->components[Y].delta_mickeys * num) / denom;
-
-               stroke->cum_movement +=
-                       abs(stroke->components[X].movement) +
-                       abs(stroke->components[Y].movement);
-       }
-
-       return ((stroke->components[X].movement != 0) ||
-           (stroke->components[Y].movement != 0));
-}
-
-static __inline void
-atp_setup_reap_time(struct atp_softc *sc, struct timeval *tvp)
-{
-       struct timeval reap_window = {
-               ATP_ZOMBIE_STROKE_REAP_WINDOW / 1000000,
-               ATP_ZOMBIE_STROKE_REAP_WINDOW % 1000000
-       };
-
-       microtime(&sc->sc_reap_time);
-       timevaladd(&sc->sc_reap_time, &reap_window);
-
-       sc->sc_reap_ctime = *tvp; /* ctime to reap */
-}
-
-static void
-atp_reap_zombies(struct atp_softc *sc, u_int *n_reaped, u_int *reaped_xlocs)
-{
-       u_int       i;
-       atp_stroke *stroke;
-
-       *n_reaped = 0;
-       for (i = 0; i < sc->sc_n_strokes; i++) {
-               struct timeval  tdiff;
-
-               stroke = &sc->sc_strokes[i];
-
-               if ((stroke->flags & ATSF_ZOMBIE) == 0)
-                       continue;
-
-               /* Compare this stroke's ctime with the ctime being reaped. */
-               if (timevalcmp(&stroke->ctime, &sc->sc_reap_ctime, >=)) {
-                       tdiff = stroke->ctime;
-                       timevalsub(&tdiff, &sc->sc_reap_ctime);
-               } else {
-                       tdiff = sc->sc_reap_ctime;
-                       timevalsub(&tdiff, &stroke->ctime);
-               }
-
-               if ((tdiff.tv_sec > (ATP_COINCIDENCE_THRESHOLD / 1000000)) ||
-                   ((tdiff.tv_sec == (ATP_COINCIDENCE_THRESHOLD / 1000000)) &&
-                    (tdiff.tv_usec > (ATP_COINCIDENCE_THRESHOLD % 1000000)))) {
-                       continue; /* Skip non-siblings. */
-               }
-
-               /*
-                * Reap this sibling zombie stroke.
-                */
-
-               if (reaped_xlocs != NULL)
-                       reaped_xlocs[*n_reaped] = stroke->components[X].loc;
-
-               /* Erase the stroke from the sc. */
-               memcpy(&stroke[i], &stroke[i + 1],
-                   (sc->sc_n_strokes - i - 1) * sizeof(atp_stroke));
-               sc->sc_n_strokes--;
-
-               *n_reaped += 1;
-               --i; /* Decr. i to keep it unchanged for the next iteration */
-       }
-
-       DPRINTFN(ATP_LLEVEL_INFO, "reaped %u zombies\n", *n_reaped);
-
-       /* There could still be zombies remaining in the system. */
-       for (i = 0; i < sc->sc_n_strokes; i++) {
-               stroke = &sc->sc_strokes[i];
-               if (stroke->flags & ATSF_ZOMBIE) {
-                       DPRINTFN(ATP_LLEVEL_INFO, "zombies remain!\n");
-                       atp_setup_reap_time(sc, &stroke->ctime);
-                       return;
-               }
-       }
-
-       /* If we reach here, then no more zombies remain. */
-       sc->sc_state &= ~ATP_ZOMBIES_EXIST;
-}
-
-
-/* Device methods. */
-static device_probe_t  atp_probe;
-static device_attach_t atp_attach;
-static device_detach_t atp_detach;
-static usb_callback_t  atp_intr;
-
-static const struct usb_config atp_config[ATP_N_TRANSFER] = {
-       [ATP_INTR_DT] = {
-               .type      = UE_INTERRUPT,
-               .endpoint  = UE_ADDR_ANY,
-               .direction = UE_DIR_IN,
-               .flags = {
-                       .pipe_bof = 1,
-                       .short_xfer_ok = 1,
-               },
-               .bufsize   = 0, /* use wMaxPacketSize */
-               .callback  = &atp_intr,
-       },
-       [ATP_RESET] = {
-               .type      = UE_CONTROL,
-               .endpoint  = 0, /* Control pipe */
-               .direction = UE_DIR_ANY,
-               .bufsize = sizeof(struct usb_device_request) + MODE_LENGTH,
-               .callback  = &atp_reset_callback,
-               .interval = 0,  /* no pre-delay */
-       },
-};
-
-static int
-atp_probe(device_t self)
-{
-       struct usb_attach_arg *uaa = device_get_ivars(self);
-
-       if (uaa->usb_mode != USB_MODE_HOST)
-               return (ENXIO);
-
-       if ((uaa->info.bInterfaceClass != UICLASS_HID) ||
-           (uaa->info.bInterfaceProtocol != UIPROTO_MOUSE))
-               return (ENXIO);
-
-       return (usbd_lookup_id_by_uaa(atp_devs, sizeof(atp_devs), uaa));
-}
-
-static int
-atp_attach(device_t dev)
-{
-       struct atp_softc      *sc = device_get_softc(dev);
-       struct usb_attach_arg *uaa = device_get_ivars(dev);
-       usb_error_t            err;
-
-       DPRINTFN(ATP_LLEVEL_INFO, "sc=%p\n", sc);
-
-       sc->sc_dev        = dev;
-       sc->sc_usb_device = uaa->device;
-
-       /*
-        * By default the touchpad behaves like an HID device, sending
-        * packets with reportID = 2. Such reports contain only
-        * limited information--they encode movement deltas and button
-        * events,--but do not include data from the pressure
-        * sensors. The device input mode can be switched from HID
-        * reports to raw sensor data using vendor-specific USB
-        * control commands; but first the mode must be read.
-        */
-       err = atp_req_get_report(sc->sc_usb_device, sc->sc_mode_bytes);
-       if (err != USB_ERR_NORMAL_COMPLETION) {
-               DPRINTF("failed to read device mode (%d)\n", err);
-               return (ENXIO);
-       }
-
-       if (atp_set_device_mode(dev, RAW_SENSOR_MODE) != 0) {
-               DPRINTF("failed to set mode to 'RAW_SENSOR' (%d)\n", err);
-               return (ENXIO);
-       }
-
-       mtx_init(&sc->sc_mutex, "atpmtx", NULL, MTX_DEF | MTX_RECURSE);
-
-       err = usbd_transfer_setup(uaa->device,
-           &uaa->info.bIfaceIndex, sc->sc_xfer, atp_config,
-           ATP_N_TRANSFER, sc, &sc->sc_mutex);
-
-       if (err) {
-               DPRINTF("error=%s\n", usbd_errstr(err));
-               goto detach;
-       }
-
-       if (usb_fifo_attach(sc->sc_usb_device, sc, &sc->sc_mutex,
-               &atp_fifo_methods, &sc->sc_fifo,
-               device_get_unit(dev), 0 - 1, uaa->info.bIfaceIndex,
-               UID_ROOT, GID_OPERATOR, 0644)) {
-               goto detach;
-       }
-
-       device_set_usb_desc(dev);
-
-       sc->sc_params           = &atp_dev_params[uaa->driver_info];
-
-       sc->sc_hw.buttons       = 3;
-       sc->sc_hw.iftype        = MOUSE_IF_USB;
-       sc->sc_hw.type          = MOUSE_PAD;
-       sc->sc_hw.model         = MOUSE_MODEL_GENERIC;
-       sc->sc_hw.hwid          = 0;
-       sc->sc_mode.protocol    = MOUSE_PROTO_MSC;
-       sc->sc_mode.rate        = -1;
-       sc->sc_mode.resolution  = MOUSE_RES_UNKNOWN;
-       sc->sc_mode.accelfactor = 0;
-       sc->sc_mode.level       = 0;
-       sc->sc_mode.packetsize  = MOUSE_MSC_PACKETSIZE;
-       sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
-       sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC;
-
-       sc->sc_state            = 0;
-
-       sc->sc_left_margin  = atp_mickeys_scale_factor;
-       sc->sc_right_margin = (sc->sc_params->n_xsensors - 1) *
-               atp_mickeys_scale_factor;
-
-       return (0);
-
-detach:
-       atp_detach(dev);
-       return (ENOMEM);
-}
-
-static int
-atp_detach(device_t dev)
-{
-       struct atp_softc *sc;
-
-       sc = device_get_softc(dev);
-       if (sc->sc_state & ATP_ENABLED) {
-               mtx_lock(&sc->sc_mutex);
-               atp_disable(sc);
-               mtx_unlock(&sc->sc_mutex);
-       }
-
-       usb_fifo_detach(&sc->sc_fifo);
-
-       usbd_transfer_unsetup(sc->sc_xfer, ATP_N_TRANSFER);
-
-       mtx_destroy(&sc->sc_mutex);
-
-       return (0);
-}
-
-static void
-atp_intr(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct atp_softc      *sc = usbd_xfer_softc(xfer);
-       int                    len;
-       struct usb_page_cache *pc;
-       uint8_t                status_bits;
-       atp_pspan  pspans_x[ATP_MAX_PSPANS_PER_AXIS];
-       atp_pspan  pspans_y[ATP_MAX_PSPANS_PER_AXIS];
-       u_int      n_xpspans = 0, n_ypspans = 0;
-       u_int      reaped_xlocs[ATP_MAX_STROKES];
-       u_int      tap_fingers = 0;
-
-       usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               if (len > sc->sc_params->data_len) {
-                       DPRINTFN(ATP_LLEVEL_ERROR,
-                           "truncating large packet from %u to %u bytes\n",
-                           len, sc->sc_params->data_len);
-                       len = sc->sc_params->data_len;
-               }
-               if (len < sc->sc_params->data_len)
-                       goto tr_setup;
-
-               pc = usbd_xfer_get_frame(xfer, 0);
-               usbd_copy_out(pc, 0, sc->sensor_data, sc->sc_params->data_len);
-
-               /* Interpret sensor data */
-               atp_interpret_sensor_data(sc->sensor_data,
-                   sc->sc_params->n_xsensors, X, sc->cur_x,
-                   sc->sc_params->prot);
-               atp_interpret_sensor_data(sc->sensor_data,
-                   sc->sc_params->n_ysensors, Y,  sc->cur_y,
-                   sc->sc_params->prot);
-
-               /*
-                * If this is the initial update (from an untouched
-                * pad), we should set the base values for the sensor
-                * data; deltas with respect to these base values can
-                * be used as pressure readings subsequently.
-                */
-               status_bits = sc->sensor_data[sc->sc_params->data_len - 1];
-               if ((sc->sc_params->prot == ATP_PROT_GEYSER3 &&
-                   (status_bits & ATP_STATUS_BASE_UPDATE)) ||
-                   !(sc->sc_state & ATP_VALID)) {
-                       memcpy(sc->base_x, sc->cur_x,
-                           sc->sc_params->n_xsensors * sizeof(*(sc->base_x)));
-                       memcpy(sc->base_y, sc->cur_y,
-                           sc->sc_params->n_ysensors * sizeof(*(sc->base_y)));
-                       sc->sc_state |= ATP_VALID;
-                       goto tr_setup;
-               }
-
-               /* Get pressure readings and detect p-spans for both axes. */
-               atp_get_pressures(sc->pressure_x, sc->cur_x, sc->base_x,
-                   sc->sc_params->n_xsensors);
-               atp_detect_pspans(sc->pressure_x, sc->sc_params->n_xsensors,
-                   ATP_MAX_PSPANS_PER_AXIS,
-                   pspans_x, &n_xpspans);
-               atp_get_pressures(sc->pressure_y, sc->cur_y, sc->base_y,
-                   sc->sc_params->n_ysensors);
-               atp_detect_pspans(sc->pressure_y, sc->sc_params->n_ysensors,
-                   ATP_MAX_PSPANS_PER_AXIS,
-                   pspans_y, &n_ypspans);
-
-               /* Update strokes with new pspans to detect movements. */
-               sc->sc_status.flags &= ~MOUSE_POSCHANGED;
-               if (atp_update_strokes(sc,
-                       pspans_x, n_xpspans,
-                       pspans_y, n_ypspans))
-                       sc->sc_status.flags |= MOUSE_POSCHANGED;
-
-               /* Reap zombies if it is time. */
-               if (sc->sc_state & ATP_ZOMBIES_EXIST) {
-                       struct timeval now;
-
-                       getmicrotime(&now);
-                       if (timevalcmp(&now, &sc->sc_reap_time, >=))
-                               atp_reap_zombies(sc, &tap_fingers,
-                                   reaped_xlocs);
-               }
-
-               sc->sc_status.flags &= ~MOUSE_STDBUTTONSCHANGED;
-               sc->sc_status.obutton = sc->sc_status.button;
-
-               /* Get the state of the physical buttton. */
-               sc->sc_status.button = (status_bits & ATP_STATUS_BUTTON) ?
-                       MOUSE_BUTTON1DOWN : 0;
-               if (sc->sc_status.button != 0) {
-                       /* Reset DOUBLE_TAP_N_DRAG if the button is pressed. */
-                       sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG;
-               } else if (sc->sc_state & ATP_DOUBLE_TAP_DRAG) {
-                       /* Assume a button-press with DOUBLE_TAP_N_DRAG. */
-                       sc->sc_status.button = MOUSE_BUTTON1DOWN;
-               }
-
-               sc->sc_status.flags |=
-                       sc->sc_status.button ^ sc->sc_status.obutton;
-               if (sc->sc_status.flags & MOUSE_STDBUTTONSCHANGED) {
-                       DPRINTFN(ATP_LLEVEL_INFO, "button %s\n",
-                           ((sc->sc_status.button & MOUSE_BUTTON1DOWN) ?
-                               "pressed" : "released"));
-               } else if ((sc->sc_status.obutton == 0) &&
-                   (sc->sc_status.button == 0) &&
-                   (tap_fingers != 0)) {
-                       /* Ignore single-finger taps at the edges. */
-                       if ((tap_fingers == 1) &&
-                           ((reaped_xlocs[0] <= sc->sc_left_margin) ||
-                               (reaped_xlocs[0] > sc->sc_right_margin))) {
-                               tap_fingers = 0;
-                       }
-                       DPRINTFN(ATP_LLEVEL_INFO,
-                           "tap_fingers: %u\n", tap_fingers);
-               }
-
-               if (sc->sc_status.flags &
-                   (MOUSE_POSCHANGED | MOUSE_STDBUTTONSCHANGED)) {
-                       int   dx, dy;
-                       u_int n_movements;
-
-                       dx = 0, dy = 0, n_movements = 0;
-                       for (u_int i = 0; i < sc->sc_n_strokes; i++) {
-                               atp_stroke *stroke = &sc->sc_strokes[i];
-
-                               if ((stroke->components[X].movement) ||
-                                   (stroke->components[Y].movement)) {
-                                       dx += stroke->components[X].movement;
-                                       dy += stroke->components[Y].movement;
-                                       n_movements++;
-                               }
-                       }
-                       /*
-                        * Disregard movement if multiple
-                        * strokes record motion.
-                        */
-                       if (n_movements != 1)
-                               dx = 0, dy = 0;
-
-                       sc->sc_status.dx += dx;
-                       sc->sc_status.dy += dy;
-                       atp_add_to_queue(sc, dx, -dy, sc->sc_status.button);
-               }
-
-               if (tap_fingers != 0) {
-                       /* Add a pair of events (button-down and button-up). */
-                       switch (tap_fingers) {
-                       case 1: atp_add_to_queue(sc, 0, 0, MOUSE_BUTTON1DOWN);
-                               break;
-                       case 2: atp_add_to_queue(sc, 0, 0, MOUSE_BUTTON2DOWN);
-                               break;
-                       case 3: atp_add_to_queue(sc, 0, 0, MOUSE_BUTTON3DOWN);
-                               break;
-                       default: break;/* handle taps of only up to 3 fingers */
-                       }
-                       atp_add_to_queue(sc, 0, 0, 0); /* button release */
-               }
-
-               /*
-                * The device continues to trigger interrupts at a
-                * fast rate even after touchpad activity has
-                * stopped. Upon detecting that the device has
-                * remained idle beyond a threshold, we reinitialize
-                * it to silence the interrupts.
-                */
-               if ((sc->sc_status.flags  == 0) &&
-                   (sc->sc_n_strokes     == 0) &&
-                   (sc->sc_status.button == 0)) {
-                       sc->sc_idlecount++;
-                       if (sc->sc_idlecount >= ATP_IDLENESS_THRESHOLD) {
-                               DPRINTFN(ATP_LLEVEL_INFO, "idle\n");
-
-                               /*
-                                * Use the last frame before we go idle for
-                                * calibration on pads which do not send
-                                * calibration frames.
-                                */
-                               if (sc->sc_params->prot < ATP_PROT_GEYSER3) {
-                                       memcpy(sc->base_x, sc->cur_x,
-                                           sc->sc_params->n_xsensors *
-                                           sizeof(*(sc->base_x)));
-                                       memcpy(sc->base_y, sc->cur_y,
-                                           sc->sc_params->n_ysensors *
-                                           sizeof(*(sc->base_y)));
-                               }
-
-                               sc->sc_idlecount = 0;
-                               usbd_transfer_start(sc->sc_xfer[ATP_RESET]);
-                       }
-               } else {
-                       sc->sc_idlecount = 0;
-               }
-
-       case USB_ST_SETUP:
-       tr_setup:
-               /* check if we can put more data into the FIFO */
-               if (usb_fifo_put_bytes_max(
-                           sc->sc_fifo.fp[USB_FIFO_RX]) != 0) {
-                       usbd_xfer_set_frame_len(xfer, 0,
-                           sc->sc_params->data_len);
-                       usbd_transfer_submit(xfer);
-               }
-               break;
-
-       default:                        /* Error */
-               if (error != USB_ERR_CANCELLED) {
-                       /* try clear stall first */
-                       usbd_xfer_set_stall(xfer);
-                       goto tr_setup;
-               }
-               break;
-       }
-
-       return;
-}
-
-static void
-atp_add_to_queue(struct atp_softc *sc, int dx, int dy, uint32_t buttons_in)
-{
-       uint32_t buttons_out;
-       uint8_t  buf[8];
-
-       dx = imin(dx,  254); dx = imax(dx, -256);
-       dy = imin(dy,  254); dy = imax(dy, -256);
-
-       buttons_out = MOUSE_MSC_BUTTONS;
-       if (buttons_in & MOUSE_BUTTON1DOWN)
-               buttons_out &= ~MOUSE_MSC_BUTTON1UP;
-       else if (buttons_in & MOUSE_BUTTON2DOWN)
-               buttons_out &= ~MOUSE_MSC_BUTTON2UP;
-       else if (buttons_in & MOUSE_BUTTON3DOWN)
-               buttons_out &= ~MOUSE_MSC_BUTTON3UP;
-
-       DPRINTFN(ATP_LLEVEL_INFO, "dx=%d, dy=%d, buttons=%x\n",
-           dx, dy, buttons_out);
-
-       /* Encode the mouse data in standard format; refer to mouse(4) */
-       buf[0] = sc->sc_mode.syncmask[1];
-       buf[0] |= buttons_out;
-       buf[1] = dx >> 1;
-       buf[2] = dy >> 1;
-       buf[3] = dx - (dx >> 1);
-       buf[4] = dy - (dy >> 1);
-       /* Encode extra bytes for level 1 */
-       if (sc->sc_mode.level == 1) {
-               buf[5] = 0;                    /* dz */
-               buf[6] = 0;                    /* dz - (dz / 2) */
-               buf[7] = MOUSE_SYS_EXTBUTTONS; /* Extra buttons all up. */
-       }
-
-       usb_fifo_put_data_linear(sc->sc_fifo.fp[USB_FIFO_RX], buf,
-           sc->sc_mode.packetsize, 1);
-}
-
-static void
-atp_reset_buf(struct atp_softc *sc)
-{
-       /* reset read queue */
-       usb_fifo_reset(sc->sc_fifo.fp[USB_FIFO_RX]);
-}
-
-static void
-atp_start_read(struct usb_fifo *fifo)
-{
-       struct atp_softc *sc = usb_fifo_softc(fifo);
-       int rate;
-
-       /* Check if we should override the default polling interval */
-       rate = sc->sc_pollrate;
-       /* Range check rate */
-       if (rate > 1000)
-               rate = 1000;
-       /* Check for set rate */
-       if ((rate > 0) && (sc->sc_xfer[ATP_INTR_DT] != NULL)) {
-               /* Stop current transfer, if any */
-               usbd_transfer_stop(sc->sc_xfer[ATP_INTR_DT]);
-               /* Set new interval */
-               usbd_xfer_set_interval(sc->sc_xfer[ATP_INTR_DT], 1000 / rate);
-               /* Only set pollrate once */
-               sc->sc_pollrate = 0;
-       }
-
-       usbd_transfer_start(sc->sc_xfer[ATP_INTR_DT]);
-}
-
-static void
-atp_stop_read(struct usb_fifo *fifo)
-{
-       struct atp_softc *sc = usb_fifo_softc(fifo);
-
-       usbd_transfer_stop(sc->sc_xfer[ATP_INTR_DT]);
-}
-
-static int
-atp_open(struct usb_fifo *fifo, int fflags)
-{
-       DPRINTFN(ATP_LLEVEL_INFO, "\n");
-
-       if (fflags & FREAD) {
-               struct atp_softc *sc = usb_fifo_softc(fifo);
-               int rc;
-
-               if (sc->sc_state & ATP_ENABLED)
-                       return (EBUSY);
-
-               if (usb_fifo_alloc_buffer(fifo,
-                       ATP_FIFO_BUF_SIZE, ATP_FIFO_QUEUE_MAXLEN)) {
-                       return (ENOMEM);
-               }
-
-               rc = atp_enable(sc);
-               if (rc != 0) {
-                       usb_fifo_free_buffer(fifo);
-                       return (rc);
-               }
-       }
-
-       return (0);
-}
-
-static void
-atp_close(struct usb_fifo *fifo, int fflags)
-{
-       if (fflags & FREAD) {
-               struct atp_softc *sc = usb_fifo_softc(fifo);
-
-               atp_disable(sc);
-               usb_fifo_free_buffer(fifo);
-       }
-}
-
-int
-atp_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, int fflags)
-{
-       struct atp_softc *sc = usb_fifo_softc(fifo);
-       mousemode_t mode;
-       int error = 0;
-
-       mtx_lock(&sc->sc_mutex);
-
-       switch(cmd) {
-       case MOUSE_GETHWINFO:
-               *(mousehw_t *)addr = sc->sc_hw;
-               break;
-       case MOUSE_GETMODE:
-               *(mousemode_t *)addr = sc->sc_mode;
-               break;
-       case MOUSE_SETMODE:
-               mode = *(mousemode_t *)addr;
-
-               if (mode.level == -1)
-                       /* Don't change the current setting */
-                       ;
-               else if ((mode.level < 0) || (mode.level > 1)) {
-                       error = EINVAL;
-                       goto done;
-               }
-               sc->sc_mode.level = mode.level;
-               sc->sc_pollrate   = mode.rate;
-               sc->sc_hw.buttons = 3;
-
-               if (sc->sc_mode.level == 0) {
-                       sc->sc_mode.protocol = MOUSE_PROTO_MSC;
-                       sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE;
-                       sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
-                       sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC;
-               } else if (sc->sc_mode.level == 1) {
-                       sc->sc_mode.protocol = MOUSE_PROTO_SYSMOUSE;
-                       sc->sc_mode.packetsize = MOUSE_SYS_PACKETSIZE;
-                       sc->sc_mode.syncmask[0] = MOUSE_SYS_SYNCMASK;
-                       sc->sc_mode.syncmask[1] = MOUSE_SYS_SYNC;
-               }
-               atp_reset_buf(sc);
-               break;
-       case MOUSE_GETLEVEL:
-               *(int *)addr = sc->sc_mode.level;
-               break;
-       case MOUSE_SETLEVEL:
-               if (*(int *)addr < 0 || *(int *)addr > 1) {
-                       error = EINVAL;
-                       goto done;
-               }
-               sc->sc_mode.level = *(int *)addr;
-               sc->sc_hw.buttons = 3;
-
-               if (sc->sc_mode.level == 0) {
-                       sc->sc_mode.protocol = MOUSE_PROTO_MSC;
-                       sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE;
-                       sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
-                       sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC;
-               } else if (sc->sc_mode.level == 1) {
-                       sc->sc_mode.protocol = MOUSE_PROTO_SYSMOUSE;
-                       sc->sc_mode.packetsize = MOUSE_SYS_PACKETSIZE;
-                       sc->sc_mode.syncmask[0] = MOUSE_SYS_SYNCMASK;
-                       sc->sc_mode.syncmask[1] = MOUSE_SYS_SYNC;
-               }
-               atp_reset_buf(sc);
-               break;
-       case MOUSE_GETSTATUS: {
-               mousestatus_t *status = (mousestatus_t *)addr;
-
-               *status = sc->sc_status;
-               sc->sc_status.obutton = sc->sc_status.button;
-               sc->sc_status.button  = 0;
-               sc->sc_status.dx = 0;
-               sc->sc_status.dy = 0;
-               sc->sc_status.dz = 0;
-
-               if (status->dx || status->dy || status->dz)
-                       status->flags |= MOUSE_POSCHANGED;
-               if (status->button != status->obutton)
-                       status->flags |= MOUSE_BUTTONSCHANGED;
-               break;
-       }
-       default:
-               error = ENOTTY;
-       }
-
-done:
-       mtx_unlock(&sc->sc_mutex);
-       return (error);
-}
-
-static int
-atp_sysctl_scale_factor_handler(SYSCTL_HANDLER_ARGS)
-{
-       int error;
-       u_int tmp;
-       u_int prev_mickeys_scale_factor;
-
-       prev_mickeys_scale_factor = atp_mickeys_scale_factor;
-
-       tmp = atp_mickeys_scale_factor;
-       error = sysctl_handle_int(oidp, &tmp, 0, req);
-       if (error != 0 || req->newptr == NULL)
-               return (error);
-
-       if (tmp == prev_mickeys_scale_factor)
-               return (0);     /* no change */
-
-       atp_mickeys_scale_factor = tmp;
-       DPRINTFN(ATP_LLEVEL_INFO, "%s: resetting mickeys_scale_factor to %u\n",
-           ATP_DRIVER_NAME, tmp);
-
-       /* Update dependent thresholds. */
-       if (atp_small_movement_threshold == (prev_mickeys_scale_factor >> 3))
-               atp_small_movement_threshold = atp_mickeys_scale_factor >> 3;
-       if (atp_max_delta_mickeys == ((3 * prev_mickeys_scale_factor) >> 1))
-               atp_max_delta_mickeys = ((3 * atp_mickeys_scale_factor) >>1);
-       if (atp_slide_min_movement == (prev_mickeys_scale_factor >> 3))
-               atp_slide_min_movement = atp_mickeys_scale_factor >> 3;
-
-       return (0);
-}
-
-static device_method_t atp_methods[] = {
-       /* Device interface */
-       DEVMETHOD(device_probe,  atp_probe),
-       DEVMETHOD(device_attach, atp_attach),
-       DEVMETHOD(device_detach, atp_detach),
-       DEVMETHOD_END
-};
-
-static driver_t atp_driver = {
-       ATP_DRIVER_NAME,
-       atp_methods,
-       sizeof(struct atp_softc)
-};
-
-static devclass_t atp_devclass;
-
-DRIVER_MODULE(atp, uhub, atp_driver, atp_devclass, NULL, NULL);
-MODULE_DEPEND(atp, usb, 1, 1, 1);
-MODULE_VERSION(atp, 1);
diff --git a/sys/bus/u4b/misc/udbp.c b/sys/bus/u4b/misc/udbp.c
deleted file mode 100644 (file)
index b0c1734..0000000
+++ /dev/null
@@ -1,857 +0,0 @@
-/*-
- * Copyright (c) 1996-2000 Whistle Communications, Inc.
- * All rights reserved.
- *
- * 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.
- * 3. Neither the name of author nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY NICK HIBMA 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 AUTHOR 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.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/* Driver for arbitrary double bulk pipe devices.
- * The driver assumes that there will be the same driver on the other side.
- *
- * XXX Some more information on what the framing of the IP packets looks like.
- *
- * To take full advantage of bulk transmission, packets should be chosen
- * between 1k and 5k in size (1k to make sure the sending side starts
- * streaming, and <5k to avoid overflowing the system with small TDs).
- */
-
-
-/* probe/attach/detach:
- *  Connect the driver to the hardware and netgraph
- *
- *  The reason we submit a bulk in transfer is that USB does not know about
- *  interrupts. The bulk transfer continuously polls the device for data.
- *  While the device has no data available, the device NAKs the TDs. As soon
- *  as there is data, the transfer happens and the data comes flowing in.
- *
- *  In case you were wondering, interrupt transfers happen exactly that way.
- *  It therefore doesn't make sense to use the interrupt pipe to signal
- *  'data ready' and then schedule a bulk transfer to fetch it. That would
- *  incur a 2ms delay at least, without reducing bandwidth requirements.
- *
- */
-
-#include <sys/stdint.h>
-#include <sys/stddef.h>
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/bus.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/condvar.h>
-#include <sys/sysctl.h>
-#include <sys/sx.h>
-#include <sys/unistd.h>
-#include <sys/callout.h>
-#include <sys/malloc.h>
-#include <sys/priv.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#define        USB_DEBUG_VAR udbp_debug
-#include <dev/usb/usb_debug.h>
-
-#include <sys/mbuf.h>
-
-#include <netgraph/ng_message.h>
-#include <netgraph/netgraph.h>
-#include <netgraph/ng_parse.h>
-#include <netgraph/bluetooth/include/ng_bluetooth.h>
-
-#include <dev/usb/misc/udbp.h>
-
-#ifdef USB_DEBUG
-static int udbp_debug = 0;
-
-static SYSCTL_NODE(_hw_usb, OID_AUTO, udbp, CTLFLAG_RW, 0, "USB udbp");
-SYSCTL_INT(_hw_usb_udbp, OID_AUTO, debug, CTLFLAG_RWTUN,
-    &udbp_debug, 0, "udbp debug level");
-#endif
-
-#define        UDBP_TIMEOUT    2000            /* timeout on outbound transfers, in
-                                        * msecs */
-#define        UDBP_BUFFERSIZE MCLBYTES        /* maximum number of bytes in one
-                                        * transfer */
-#define        UDBP_T_WR       0
-#define        UDBP_T_RD       1
-#define        UDBP_T_WR_CS    2
-#define        UDBP_T_RD_CS    3
-#define        UDBP_T_MAX      4
-#define        UDBP_Q_MAXLEN   50
-
-struct udbp_softc {
-
-       struct mtx sc_mtx;
-       struct ng_bt_mbufq sc_xmitq_hipri;      /* hi-priority transmit queue */
-       struct ng_bt_mbufq sc_xmitq;    /* low-priority transmit queue */
-
-       struct usb_xfer *sc_xfer[UDBP_T_MAX];
-       node_p  sc_node;                /* back pointer to node */
-       hook_p  sc_hook;                /* pointer to the hook */
-       struct mbuf *sc_bulk_in_buffer;
-
-       uint32_t sc_packets_in;         /* packets in from downstream */
-       uint32_t sc_packets_out;        /* packets out towards downstream */
-
-       uint8_t sc_flags;
-#define        UDBP_FLAG_READ_STALL    0x01    /* read transfer stalled */
-#define        UDBP_FLAG_WRITE_STALL   0x02    /* write transfer stalled */
-
-       uint8_t sc_name[16];
-};
-
-/* prototypes */
-
-static int udbp_modload(module_t mod, int event, void *data);
-
-static device_probe_t udbp_probe;
-static device_attach_t udbp_attach;
-static device_detach_t udbp_detach;
-
-static usb_callback_t udbp_bulk_read_callback;
-static usb_callback_t udbp_bulk_read_clear_stall_callback;
-static usb_callback_t udbp_bulk_write_callback;
-static usb_callback_t udbp_bulk_write_clear_stall_callback;
-
-static void    udbp_bulk_read_complete(node_p, hook_p, void *, int);
-
-static ng_constructor_t        ng_udbp_constructor;
-static ng_rcvmsg_t     ng_udbp_rcvmsg;
-static ng_shutdown_t   ng_udbp_rmnode;
-static ng_newhook_t    ng_udbp_newhook;
-static ng_connect_t    ng_udbp_connect;
-static ng_rcvdata_t    ng_udbp_rcvdata;
-static ng_disconnect_t ng_udbp_disconnect;
-
-/* Parse type for struct ngudbpstat */
-static const struct ng_parse_struct_field
-       ng_udbp_stat_type_fields[] = NG_UDBP_STATS_TYPE_INFO;
-
-static const struct ng_parse_type ng_udbp_stat_type = {
-       &ng_parse_struct_type,
-       &ng_udbp_stat_type_fields
-};
-
-/* List of commands and how to convert arguments to/from ASCII */
-static const struct ng_cmdlist ng_udbp_cmdlist[] = {
-       {
-               NGM_UDBP_COOKIE,
-               NGM_UDBP_GET_STATUS,
-               "getstatus",
-               NULL,
-               &ng_udbp_stat_type,
-       },
-       {
-               NGM_UDBP_COOKIE,
-               NGM_UDBP_SET_FLAG,
-               "setflag",
-               &ng_parse_int32_type,
-               NULL
-       },
-       {0}
-};
-
-/* Netgraph node type descriptor */
-static struct ng_type ng_udbp_typestruct = {
-       .version = NG_ABI_VERSION,
-       .name = NG_UDBP_NODE_TYPE,
-       .constructor = ng_udbp_constructor,
-       .rcvmsg = ng_udbp_rcvmsg,
-       .shutdown = ng_udbp_rmnode,
-       .newhook = ng_udbp_newhook,
-       .connect = ng_udbp_connect,
-       .rcvdata = ng_udbp_rcvdata,
-       .disconnect = ng_udbp_disconnect,
-       .cmdlist = ng_udbp_cmdlist,
-};
-
-/* USB config */
-static const struct usb_config udbp_config[UDBP_T_MAX] = {
-
-       [UDBP_T_WR] = {
-               .type = UE_BULK,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_OUT,
-               .bufsize = UDBP_BUFFERSIZE,
-               .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
-               .callback = &udbp_bulk_write_callback,
-               .timeout = UDBP_TIMEOUT,
-       },
-
-       [UDBP_T_RD] = {
-               .type = UE_BULK,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_IN,
-               .bufsize = UDBP_BUFFERSIZE,
-               .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
-               .callback = &udbp_bulk_read_callback,
-       },
-
-       [UDBP_T_WR_CS] = {
-               .type = UE_CONTROL,
-               .endpoint = 0x00,       /* Control pipe */
-               .direction = UE_DIR_ANY,
-               .bufsize = sizeof(struct usb_device_request),
-               .callback = &udbp_bulk_write_clear_stall_callback,
-               .timeout = 1000,        /* 1 second */
-               .interval = 50, /* 50ms */
-       },
-
-       [UDBP_T_RD_CS] = {
-               .type = UE_CONTROL,
-               .endpoint = 0x00,       /* Control pipe */
-               .direction = UE_DIR_ANY,
-               .bufsize = sizeof(struct usb_device_request),
-               .callback = &udbp_bulk_read_clear_stall_callback,
-               .timeout = 1000,        /* 1 second */
-               .interval = 50, /* 50ms */
-       },
-};
-
-static devclass_t udbp_devclass;
-
-static device_method_t udbp_methods[] = {
-       /* Device interface */
-       DEVMETHOD(device_probe, udbp_probe),
-       DEVMETHOD(device_attach, udbp_attach),
-       DEVMETHOD(device_detach, udbp_detach),
-       DEVMETHOD_END
-};
-
-static driver_t udbp_driver = {
-       .name = "udbp",
-       .methods = udbp_methods,
-       .size = sizeof(struct udbp_softc),
-};
-
-DRIVER_MODULE(udbp, uhub, udbp_driver, udbp_devclass, udbp_modload, NULL);
-MODULE_DEPEND(udbp, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
-MODULE_DEPEND(udbp, usb, 1, 1, 1);
-MODULE_VERSION(udbp, 1);
-
-static int
-udbp_modload(module_t mod, int event, void *data)
-{
-       int error;
-
-       switch (event) {
-       case MOD_LOAD:
-               error = ng_newtype(&ng_udbp_typestruct);
-               if (error != 0) {
-                       printf("%s: Could not register "
-                           "Netgraph node type, error=%d\n",
-                           NG_UDBP_NODE_TYPE, error);
-               }
-               break;
-
-       case MOD_UNLOAD:
-               error = ng_rmtype(&ng_udbp_typestruct);
-               break;
-
-       default:
-               error = EOPNOTSUPP;
-               break;
-       }
-       return (error);
-}
-
-static const STRUCT_USB_HOST_ID udbp_devs[] = {
-       {USB_VPI(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_TURBOCONNECT, 0)},
-       {USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301, 0)},
-       {USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302, 0)},
-       {USB_VPI(USB_VENDOR_ANCHOR, USB_PRODUCT_ANCHOR_EZLINK, 0)},
-       {USB_VPI(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL620USB, 0)},
-};
-
-static int
-udbp_probe(device_t dev)
-{
-       struct usb_attach_arg *uaa = device_get_ivars(dev);
-
-       if (uaa->usb_mode != USB_MODE_HOST)
-               return (ENXIO);
-       if (uaa->info.bConfigIndex != 0)
-               return (ENXIO);
-       if (uaa->info.bIfaceIndex != 0)
-               return (ENXIO);
-
-       return (usbd_lookup_id_by_uaa(udbp_devs, sizeof(udbp_devs), uaa));
-}
-
-static int
-udbp_attach(device_t dev)
-{
-       struct usb_attach_arg *uaa = device_get_ivars(dev);
-       struct udbp_softc *sc = device_get_softc(dev);
-       int error;
-
-       device_set_usb_desc(dev);
-
-       snprintf(sc->sc_name, sizeof(sc->sc_name),
-           "%s", device_get_nameunit(dev));
-
-       mtx_init(&sc->sc_mtx, "udbp lock", NULL, MTX_DEF | MTX_RECURSE);
-
-       error = usbd_transfer_setup(uaa->device, &uaa->info.bIfaceIndex,
-           sc->sc_xfer, udbp_config, UDBP_T_MAX, sc, &sc->sc_mtx);
-       if (error) {
-               DPRINTF("error=%s\n", usbd_errstr(error));
-               goto detach;
-       }
-       NG_BT_MBUFQ_INIT(&sc->sc_xmitq, UDBP_Q_MAXLEN);
-
-       NG_BT_MBUFQ_INIT(&sc->sc_xmitq_hipri, UDBP_Q_MAXLEN);
-
-       /* create Netgraph node */
-
-       if (ng_make_node_common(&ng_udbp_typestruct, &sc->sc_node) != 0) {
-               printf("%s: Could not create Netgraph node\n",
-                   sc->sc_name);
-               sc->sc_node = NULL;
-               goto detach;
-       }
-       /* name node */
-
-       if (ng_name_node(sc->sc_node, sc->sc_name) != 0) {
-               printf("%s: Could not name node\n",
-                   sc->sc_name);
-               NG_NODE_UNREF(sc->sc_node);
-               sc->sc_node = NULL;
-               goto detach;
-       }
-       NG_NODE_SET_PRIVATE(sc->sc_node, sc);
-
-       /* the device is now operational */
-
-       return (0);                     /* success */
-
-detach:
-       udbp_detach(dev);
-       return (ENOMEM);                /* failure */
-}
-
-static int
-udbp_detach(device_t dev)
-{
-       struct udbp_softc *sc = device_get_softc(dev);
-
-       /* destroy Netgraph node */
-
-       if (sc->sc_node != NULL) {
-               NG_NODE_SET_PRIVATE(sc->sc_node, NULL);
-               ng_rmnode_self(sc->sc_node);
-               sc->sc_node = NULL;
-       }
-       /* free USB transfers, if any */
-
-       usbd_transfer_unsetup(sc->sc_xfer, UDBP_T_MAX);
-
-       mtx_destroy(&sc->sc_mtx);
-
-       /* destroy queues */
-
-       NG_BT_MBUFQ_DESTROY(&sc->sc_xmitq);
-       NG_BT_MBUFQ_DESTROY(&sc->sc_xmitq_hipri);
-
-       /* extra check */
-
-       if (sc->sc_bulk_in_buffer) {
-               m_freem(sc->sc_bulk_in_buffer);
-               sc->sc_bulk_in_buffer = NULL;
-       }
-       return (0);                     /* success */
-}
-
-static void
-udbp_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct udbp_softc *sc = usbd_xfer_softc(xfer);
-       struct usb_page_cache *pc;
-       struct mbuf *m;
-       int actlen;
-
-       usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-
-               /* allocate new mbuf */
-
-               MGETHDR(m, M_DONTWAIT, MT_DATA);
-
-               if (m == NULL) {
-                       goto tr_setup;
-               }
-               MCLGET(m, M_DONTWAIT);
-
-               if (!(m->m_flags & M_EXT)) {
-                       m_freem(m);
-                       goto tr_setup;
-               }
-               m->m_pkthdr.len = m->m_len = actlen;
-
-               pc = usbd_xfer_get_frame(xfer, 0);
-               usbd_copy_out(pc, 0, m->m_data, actlen);
-
-               sc->sc_bulk_in_buffer = m;
-
-               DPRINTF("received package %d bytes\n", actlen);
-
-       case USB_ST_SETUP:
-tr_setup:
-               if (sc->sc_bulk_in_buffer) {
-                       ng_send_fn(sc->sc_node, NULL, &udbp_bulk_read_complete, NULL, 0);
-                       return;
-               }
-               if (sc->sc_flags & UDBP_FLAG_READ_STALL) {
-                       usbd_transfer_start(sc->sc_xfer[UDBP_T_RD_CS]);
-                       return;
-               }
-               usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
-               usbd_transfer_submit(xfer);
-               return;
-
-       default:                        /* Error */
-               if (error != USB_ERR_CANCELLED) {
-                       /* try to clear stall first */
-                       sc->sc_flags |= UDBP_FLAG_READ_STALL;
-                       usbd_transfer_start(sc->sc_xfer[UDBP_T_RD_CS]);
-               }
-               return;
-
-       }
-}
-
-static void
-udbp_bulk_read_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct udbp_softc *sc = usbd_xfer_softc(xfer);
-       struct usb_xfer *xfer_other = sc->sc_xfer[UDBP_T_RD];
-
-       if (usbd_clear_stall_callback(xfer, xfer_other)) {
-               DPRINTF("stall cleared\n");
-               sc->sc_flags &= ~UDBP_FLAG_READ_STALL;
-               usbd_transfer_start(xfer_other);
-       }
-}
-
-static void
-udbp_bulk_read_complete(node_p node, hook_p hook, void *arg1, int arg2)
-{
-       struct udbp_softc *sc = NG_NODE_PRIVATE(node);
-       struct mbuf *m;
-       int error;
-
-       if (sc == NULL) {
-               return;
-       }
-       mtx_lock(&sc->sc_mtx);
-
-       m = sc->sc_bulk_in_buffer;
-
-       if (m) {
-
-               sc->sc_bulk_in_buffer = NULL;
-
-               if ((sc->sc_hook == NULL) ||
-                   NG_HOOK_NOT_VALID(sc->sc_hook)) {
-                       DPRINTF("No upstream hook\n");
-                       goto done;
-               }
-               sc->sc_packets_in++;
-
-               NG_SEND_DATA_ONLY(error, sc->sc_hook, m);
-
-               m = NULL;
-       }
-done:
-       if (m) {
-               m_freem(m);
-       }
-       /* start USB bulk-in transfer, if not already started */
-
-       usbd_transfer_start(sc->sc_xfer[UDBP_T_RD]);
-
-       mtx_unlock(&sc->sc_mtx);
-}
-
-static void
-udbp_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct udbp_softc *sc = usbd_xfer_softc(xfer);
-       struct usb_page_cache *pc;
-       struct mbuf *m;
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-
-               sc->sc_packets_out++;
-
-       case USB_ST_SETUP:
-               if (sc->sc_flags & UDBP_FLAG_WRITE_STALL) {
-                       usbd_transfer_start(sc->sc_xfer[UDBP_T_WR_CS]);
-                       return;
-               }
-               /* get next mbuf, if any */
-
-               NG_BT_MBUFQ_DEQUEUE(&sc->sc_xmitq_hipri, m);
-               if (m == NULL) {
-                       NG_BT_MBUFQ_DEQUEUE(&sc->sc_xmitq, m);
-                       if (m == NULL) {
-                               DPRINTF("Data queue is empty\n");
-                               return;
-                       }
-               }
-               if (m->m_pkthdr.len > MCLBYTES) {
-                       DPRINTF("truncating large packet "
-                           "from %d to %d bytes\n", m->m_pkthdr.len,
-                           MCLBYTES);
-                       m->m_pkthdr.len = MCLBYTES;
-               }
-               pc = usbd_xfer_get_frame(xfer, 0);
-               usbd_m_copy_in(pc, 0, m, 0, m->m_pkthdr.len);
-
-               usbd_xfer_set_frame_len(xfer, 0, m->m_pkthdr.len);
-
-               DPRINTF("packet out: %d bytes\n", m->m_pkthdr.len);
-
-               m_freem(m);
-
-               usbd_transfer_submit(xfer);
-               return;
-
-       default:                        /* Error */
-               if (error != USB_ERR_CANCELLED) {
-                       /* try to clear stall first */
-                       sc->sc_flags |= UDBP_FLAG_WRITE_STALL;
-                       usbd_transfer_start(sc->sc_xfer[UDBP_T_WR_CS]);
-               }
-               return;
-
-       }
-}
-
-static void
-udbp_bulk_write_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct udbp_softc *sc = usbd_xfer_softc(xfer);
-       struct usb_xfer *xfer_other = sc->sc_xfer[UDBP_T_WR];
-
-       if (usbd_clear_stall_callback(xfer, xfer_other)) {
-               DPRINTF("stall cleared\n");
-               sc->sc_flags &= ~UDBP_FLAG_WRITE_STALL;
-               usbd_transfer_start(xfer_other);
-       }
-}
-
-/***********************************************************************
- * Start of Netgraph methods
- **********************************************************************/
-
-/*
- * If this is a device node so this work is done in the attach()
- * routine and the constructor will return EINVAL as you should not be able
- * to create nodes that depend on hardware (unless you can add the hardware :)
- */
-static int
-ng_udbp_constructor(node_p node)
-{
-       return (EINVAL);
-}
-
-/*
- * Give our ok for a hook to be added...
- * If we are not running this might kick a device into life.
- * Possibly decode information out of the hook name.
- * Add the hook's private info to the hook structure.
- * (if we had some). In this example, we assume that there is a
- * an array of structs, called 'channel' in the private info,
- * one for each active channel. The private
- * pointer of each hook points to the appropriate UDBP_hookinfo struct
- * so that the source of an input packet is easily identified.
- */
-static int
-ng_udbp_newhook(node_p node, hook_p hook, const char *name)
-{
-       struct udbp_softc *sc = NG_NODE_PRIVATE(node);
-       int32_t error = 0;
-
-       if (strcmp(name, NG_UDBP_HOOK_NAME)) {
-               return (EINVAL);
-       }
-       mtx_lock(&sc->sc_mtx);
-
-       if (sc->sc_hook != NULL) {
-               error = EISCONN;
-       } else {
-               sc->sc_hook = hook;
-               NG_HOOK_SET_PRIVATE(hook, NULL);
-       }
-
-       mtx_unlock(&sc->sc_mtx);
-
-       return (error);
-}
-
-/*
- * Get a netgraph control message.
- * Check it is one we understand. If needed, send a response.
- * We could save the address for an async action later, but don't here.
- * Always free the message.
- * The response should be in a malloc'd region that the caller can 'free'.
- * A response is not required.
- * Theoretically you could respond defferently to old message types if
- * the cookie in the header didn't match what we consider to be current
- * (so that old userland programs could continue to work).
- */
-static int
-ng_udbp_rcvmsg(node_p node, item_p item, hook_p lasthook)
-{
-       struct udbp_softc *sc = NG_NODE_PRIVATE(node);
-       struct ng_mesg *resp = NULL;
-       int error = 0;
-       struct ng_mesg *msg;
-
-       NGI_GET_MSG(item, msg);
-       /* Deal with message according to cookie and command */
-       switch (msg->header.typecookie) {
-       case NGM_UDBP_COOKIE:
-               switch (msg->header.cmd) {
-               case NGM_UDBP_GET_STATUS:
-                       {
-                               struct ngudbpstat *stats;
-
-                               NG_MKRESPONSE(resp, msg, sizeof(*stats), M_WAITOK);
-                               if (!resp) {
-                                       error = ENOMEM;
-                                       break;
-                               }
-                               stats = (struct ngudbpstat *)resp->data;
-                               mtx_lock(&sc->sc_mtx);
-                               stats->packets_in = sc->sc_packets_in;
-                               stats->packets_out = sc->sc_packets_out;
-                               mtx_unlock(&sc->sc_mtx);
-                               break;
-                       }
-               case NGM_UDBP_SET_FLAG:
-                       if (msg->header.arglen != sizeof(uint32_t)) {
-                               error = EINVAL;
-                               break;
-                       }
-                       DPRINTF("flags = 0x%08x\n",
-                           *((uint32_t *)msg->data));
-                       break;
-               default:
-                       error = EINVAL; /* unknown command */
-                       break;
-               }
-               break;
-       default:
-               error = EINVAL;         /* unknown cookie type */
-               break;
-       }
-
-       /* Take care of synchronous response, if any */
-       NG_RESPOND_MSG(error, node, item, resp);
-       NG_FREE_MSG(msg);
-       return (error);
-}
-
-/*
- * Accept data from the hook and queue it for output.
- */
-static int
-ng_udbp_rcvdata(hook_p hook, item_p item)
-{
-       struct udbp_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
-       struct ng_bt_mbufq *queue_ptr;
-       struct mbuf *m;
-       struct ng_tag_prio *ptag;
-       int error;
-
-       if (sc == NULL) {
-               NG_FREE_ITEM(item);
-               return (EHOSTDOWN);
-       }
-       NGI_GET_M(item, m);
-       NG_FREE_ITEM(item);
-
-       /*
-        * Now queue the data for when it can be sent
-        */
-       ptag = (void *)m_tag_locate(m, NGM_GENERIC_COOKIE,
-           NG_TAG_PRIO, NULL);
-
-       if (ptag && (ptag->priority > NG_PRIO_CUTOFF))
-               queue_ptr = &sc->sc_xmitq_hipri;
-       else
-               queue_ptr = &sc->sc_xmitq;
-
-       mtx_lock(&sc->sc_mtx);
-
-       if (NG_BT_MBUFQ_FULL(queue_ptr)) {
-               NG_BT_MBUFQ_DROP(queue_ptr);
-               NG_FREE_M(m);
-               error = ENOBUFS;
-       } else {
-               NG_BT_MBUFQ_ENQUEUE(queue_ptr, m);
-               /*
-                * start bulk-out transfer, if not already started:
-                */
-               usbd_transfer_start(sc->sc_xfer[UDBP_T_WR]);
-               error = 0;
-       }
-
-       mtx_unlock(&sc->sc_mtx);
-
-       return (error);
-}
-
-/*
- * Do local shutdown processing..
- * We are a persistant device, we refuse to go away, and
- * only remove our links and reset ourself.
- */
-static int
-ng_udbp_rmnode(node_p node)
-{
-       struct udbp_softc *sc = NG_NODE_PRIVATE(node);
-
-       /* Let old node go */
-       NG_NODE_SET_PRIVATE(node, NULL);
-       NG_NODE_UNREF(node);            /* forget it ever existed */
-
-       if (sc == NULL) {
-               goto done;
-       }
-       /* Create Netgraph node */
-       if (ng_make_node_common(&ng_udbp_typestruct, &sc->sc_node) != 0) {
-               printf("%s: Could not create Netgraph node\n",
-                   sc->sc_name);
-               sc->sc_node = NULL;
-               goto done;
-       }
-       /* Name node */
-       if (ng_name_node(sc->sc_node, sc->sc_name) != 0) {
-               printf("%s: Could not name Netgraph node\n",
-                   sc->sc_name);
-               NG_NODE_UNREF(sc->sc_node);
-               sc->sc_node = NULL;
-               goto done;
-       }
-       NG_NODE_SET_PRIVATE(sc->sc_node, sc);
-
-done:
-       if (sc) {
-               mtx_unlock(&sc->sc_mtx);
-       }
-       return (0);
-}
-
-/*
- * This is called once we've already connected a new hook to the other node.
- * It gives us a chance to balk at the last minute.
- */
-static int
-ng_udbp_connect(hook_p hook)
-{
-       struct udbp_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
-
-       /* probably not at splnet, force outward queueing */
-       NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
-
-       mtx_lock(&sc->sc_mtx);
-
-       sc->sc_flags |= (UDBP_FLAG_READ_STALL |
-           UDBP_FLAG_WRITE_STALL);
-
-       /* start bulk-in transfer */
-       usbd_transfer_start(sc->sc_xfer[UDBP_T_RD]);
-
-       /* start bulk-out transfer */
-       usbd_transfer_start(sc->sc_xfer[UDBP_T_WR]);
-
-       mtx_unlock(&sc->sc_mtx);
-
-       return (0);
-}
-
-/*
- * Dook disconnection
- *
- * For this type, removal of the last link destroys the node
- */
-static int
-ng_udbp_disconnect(hook_p hook)
-{
-       struct udbp_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
-       int error = 0;
-
-       if (sc != NULL) {
-
-               mtx_lock(&sc->sc_mtx);
-
-               if (hook != sc->sc_hook) {
-                       error = EINVAL;
-               } else {
-
-                       /* stop bulk-in transfer */
-                       usbd_transfer_stop(sc->sc_xfer[UDBP_T_RD_CS]);
-                       usbd_transfer_stop(sc->sc_xfer[UDBP_T_RD]);
-
-                       /* stop bulk-out transfer */
-                       usbd_transfer_stop(sc->sc_xfer[UDBP_T_WR_CS]);
-                       usbd_transfer_stop(sc->sc_xfer[UDBP_T_WR]);
-
-                       /* cleanup queues */
-                       NG_BT_MBUFQ_DRAIN(&sc->sc_xmitq);
-                       NG_BT_MBUFQ_DRAIN(&sc->sc_xmitq_hipri);
-
-                       if (sc->sc_bulk_in_buffer) {
-                               m_freem(sc->sc_bulk_in_buffer);
-                               sc->sc_bulk_in_buffer = NULL;
-                       }
-                       sc->sc_hook = NULL;
-               }
-
-               mtx_unlock(&sc->sc_mtx);
-       }
-       if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
-           && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))))
-               ng_rmnode_self(NG_HOOK_NODE(hook));
-
-       return (error);
-}
diff --git a/sys/bus/u4b/misc/udbp.h b/sys/bus/u4b/misc/udbp.h
deleted file mode 100644 (file)
index e6fd853..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*-
- * Copyright (c) 1996-2000 Whistle Communications, Inc.
- * All rights reserved.
- *
- * Subject to the following obligations and disclaimer of warranty, use and
- * redistribution of this software, in source or object code forms, with or
- * without modifications are expressly permitted by Whistle Communications;
- * provided, however, that:
- * 1. Any and all reproductions of the source or object code must include the
- *    copyright notice above and the following disclaimer of warranties; and
- * 2. No rights are granted, in any manner or form, to use Whistle
- *    Communications, Inc. trademarks, including the mark "WHISTLE
- *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
- *    such appears in the above copyright notice or in the software.
- *
- * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
- * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
- * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
- * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
- * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
- * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
- * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
- * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
- * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
- * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file was derived from src/sys/netgraph/ng_sample.h, revision 1.1
- * written by Julian Elischer, Whistle Communications.
- *
- * $FreeBSD$
- */
-
-#ifndef        _NETGRAPH_UDBP_H_
-#define        _NETGRAPH_UDBP_H_
-
-/* Node type name. This should be unique among all netgraph node types */
-#define        NG_UDBP_NODE_TYPE       "udbp"
-
-/* Node type cookie. Should also be unique. This value MUST change whenever
-   an incompatible change is made to this header file, to insure consistency.
-   The de facto method for generating cookies is to take the output of the
-   date command: date -u +'%s' */
-#define        NGM_UDBP_COOKIE         944609300
-
-
-#define        NG_UDBP_HOOK_NAME       "data"
-
-/* Netgraph commands understood by this node type */
-enum {
-       NGM_UDBP_SET_FLAG = 1,
-       NGM_UDBP_GET_STATUS,
-};
-
-/* This structure is returned by the NGM_UDBP_GET_STATUS command */
-struct ngudbpstat {
-       uint32_t packets_in;            /* packets in from downstream */
-       uint32_t packets_out;           /* packets out towards downstream */
-};
-
-/*
- * This is used to define the 'parse type' for a struct ngudbpstat, which
- * is bascially a description of how to convert a binary struct ngudbpstat
- * to an ASCII string and back.  See ng_parse.h for more info.
- *
- * This needs to be kept in sync with the above structure definition
- */
-#define        NG_UDBP_STATS_TYPE_INFO {                                       \
-         { "packets_in",       &ng_parse_int32_type    },              \
-         { "packets_out",      &ng_parse_int32_type    },              \
-         { NULL },                                                     \
-}
-
-#endif                                 /* _NETGRAPH_UDBP_H_ */
index d7c6a9d..8c1d263 100644 (file)
@@ -1,5 +1,5 @@
 #
-# XXX MISSING: rue smsc uhso usie
+# XXX MISSING: smsc
 
 SUBDIR=        aue axe axge cdce cue ipheth kue mos udav uether urndis
 
diff --git a/sys/bus/u4b/net/if_rue.c b/sys/bus/u4b/net/if_rue.c
deleted file mode 100644 (file)
index ebbe087..0000000
+++ /dev/null
@@ -1,915 +0,0 @@
-/*-
- * Copyright (c) 2001-2003, Shunsuke Akiyama <akiyama@FreeBSD.org>.
- * Copyright (c) 1997, 1998, 1999, 2000 Bill Paul <wpaul@ee.columbia.edu>.
- * All rights reserved.
- *
- * 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 AUTHOR 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 AUTHOR 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) 1997, 1998, 1999, 2000
- *     Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.
- *
- * 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.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * RealTek RTL8150 USB to fast ethernet controller driver.
- * Datasheet is available from
- * ftp://ftp.realtek.com.tw/lancard/data_sheet/8150/.
- */
-
-#include <sys/stdint.h>
-#include <sys/stddef.h>
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/bus.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/condvar.h>
-#include <sys/sysctl.h>
-#include <sys/sx.h>
-#include <sys/unistd.h>
-#include <sys/callout.h>
-#include <sys/malloc.h>
-#include <sys/priv.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#define        USB_DEBUG_VAR rue_debug
-#include <dev/usb/usb_debug.h>
-#include <dev/usb/usb_process.h>
-
-#include <dev/usb/net/usb_ethernet.h>
-#include <dev/usb/net/if_ruereg.h>
-
-#ifdef USB_DEBUG
-static int rue_debug = 0;
-
-static SYSCTL_NODE(_hw_usb, OID_AUTO, rue, CTLFLAG_RW, 0, "USB rue");
-SYSCTL_INT(_hw_usb_rue, OID_AUTO, debug, CTLFLAG_RWTUN,
-    &rue_debug, 0, "Debug level");
-#endif
-
-/*
- * Various supported device vendors/products.
- */
-
-static const STRUCT_USB_HOST_ID rue_devs[] = {
-       {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX, 0)},
-       {USB_VPI(USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_USBKR100, 0)},
-       {USB_VPI(USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01, 0)},
-};
-
-/* prototypes */
-
-static device_probe_t rue_probe;
-static device_attach_t rue_attach;
-static device_detach_t rue_detach;
-
-static miibus_readreg_t rue_miibus_readreg;
-static miibus_writereg_t rue_miibus_writereg;
-static miibus_statchg_t rue_miibus_statchg;
-
-static usb_callback_t rue_intr_callback;
-static usb_callback_t rue_bulk_read_callback;
-static usb_callback_t rue_bulk_write_callback;
-
-static uether_fn_t rue_attach_post;
-static uether_fn_t rue_init;
-static uether_fn_t rue_stop;
-static uether_fn_t rue_start;
-static uether_fn_t rue_tick;
-static uether_fn_t rue_setmulti;
-static uether_fn_t rue_setpromisc;
-
-static int     rue_read_mem(struct rue_softc *, uint16_t, void *, int);
-static int     rue_write_mem(struct rue_softc *, uint16_t, void *, int);
-static uint8_t rue_csr_read_1(struct rue_softc *, uint16_t);
-static uint16_t        rue_csr_read_2(struct rue_softc *, uint16_t);
-static int     rue_csr_write_1(struct rue_softc *, uint16_t, uint8_t);
-static int     rue_csr_write_2(struct rue_softc *, uint16_t, uint16_t);
-static int     rue_csr_write_4(struct rue_softc *, int, uint32_t);
-
-static void    rue_reset(struct rue_softc *);
-static int     rue_ifmedia_upd(struct ifnet *);
-static void    rue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-
-static const struct usb_config rue_config[RUE_N_TRANSFER] = {
-
-       [RUE_BULK_DT_WR] = {
-               .type = UE_BULK,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_OUT,
-               .bufsize = MCLBYTES,
-               .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
-               .callback = rue_bulk_write_callback,
-               .timeout = 10000,       /* 10 seconds */
-       },
-
-       [RUE_BULK_DT_RD] = {
-               .type = UE_BULK,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_IN,
-               .bufsize = (MCLBYTES + 4),
-               .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
-               .callback = rue_bulk_read_callback,
-               .timeout = 0,   /* no timeout */
-       },
-
-       [RUE_INTR_DT_RD] = {
-               .type = UE_INTERRUPT,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_IN,
-               .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
-               .bufsize = 0,   /* use wMaxPacketSize */
-               .callback = rue_intr_callback,
-       },
-};
-
-static device_method_t rue_methods[] = {
-       /* Device interface */
-       DEVMETHOD(device_probe, rue_probe),
-       DEVMETHOD(device_attach, rue_attach),
-       DEVMETHOD(device_detach, rue_detach),
-
-       /* MII interface */
-       DEVMETHOD(miibus_readreg, rue_miibus_readreg),
-       DEVMETHOD(miibus_writereg, rue_miibus_writereg),
-       DEVMETHOD(miibus_statchg, rue_miibus_statchg),
-
-       DEVMETHOD_END
-};
-
-static driver_t rue_driver = {
-       .name = "rue",
-       .methods = rue_methods,
-       .size = sizeof(struct rue_softc),
-};
-
-static devclass_t rue_devclass;
-
-DRIVER_MODULE(rue, uhub, rue_driver, rue_devclass, NULL, NULL);
-DRIVER_MODULE(miibus, rue, miibus_driver, miibus_devclass, NULL, NULL);
-MODULE_DEPEND(rue, uether, 1, 1, 1);
-MODULE_DEPEND(rue, usb, 1, 1, 1);
-MODULE_DEPEND(rue, ether, 1, 1, 1);
-MODULE_DEPEND(rue, miibus, 1, 1, 1);
-MODULE_VERSION(rue, 1);
-
-static const struct usb_ether_methods rue_ue_methods = {
-       .ue_attach_post = rue_attach_post,
-       .ue_start = rue_start,
-       .ue_init = rue_init,
-       .ue_stop = rue_stop,
-       .ue_tick = rue_tick,
-       .ue_setmulti = rue_setmulti,
-       .ue_setpromisc = rue_setpromisc,
-       .ue_mii_upd = rue_ifmedia_upd,
-       .ue_mii_sts = rue_ifmedia_sts,
-};
-
-#define        RUE_SETBIT(sc, reg, x) \
-       rue_csr_write_1(sc, reg, rue_csr_read_1(sc, reg) | (x))
-
-#define        RUE_CLRBIT(sc, reg, x) \
-       rue_csr_write_1(sc, reg, rue_csr_read_1(sc, reg) & ~(x))
-
-static int
-rue_read_mem(struct rue_softc *sc, uint16_t addr, void *buf, int len)
-{
-       struct usb_device_request req;
-
-       req.bmRequestType = UT_READ_VENDOR_DEVICE;
-       req.bRequest = UR_SET_ADDRESS;
-       USETW(req.wValue, addr);
-       USETW(req.wIndex, 0);
-       USETW(req.wLength, len);
-
-       return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
-}
-
-static int
-rue_write_mem(struct rue_softc *sc, uint16_t addr, void *buf, int len)
-{
-       struct usb_device_request req;
-
-       req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
-       req.bRequest = UR_SET_ADDRESS;
-       USETW(req.wValue, addr);
-       USETW(req.wIndex, 0);
-       USETW(req.wLength, len);
-
-       return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
-}
-
-static uint8_t
-rue_csr_read_1(struct rue_softc *sc, uint16_t reg)
-{
-       uint8_t val;
-
-       rue_read_mem(sc, reg, &val, 1);
-       return (val);
-}
-
-static uint16_t
-rue_csr_read_2(struct rue_softc *sc, uint16_t reg)
-{
-       uint8_t val[2];
-
-       rue_read_mem(sc, reg, &val, 2);
-       return (UGETW(val));
-}
-
-static int
-rue_csr_write_1(struct rue_softc *sc, uint16_t reg, uint8_t val)
-{
-       return (rue_write_mem(sc, reg, &val, 1));
-}
-
-static int
-rue_csr_write_2(struct rue_softc *sc, uint16_t reg, uint16_t val)
-{
-       uint8_t temp[2];
-
-       USETW(temp, val);
-       return (rue_write_mem(sc, reg, &temp, 2));
-}
-
-static int
-rue_csr_write_4(struct rue_softc *sc, int reg, uint32_t val)
-{
-       uint8_t temp[4];
-
-       USETDW(temp, val);
-       return (rue_write_mem(sc, reg, &temp, 4));
-}
-
-static int
-rue_miibus_readreg(device_t dev, int phy, int reg)
-{
-       struct rue_softc *sc = device_get_softc(dev);
-       uint16_t rval;
-       uint16_t ruereg;
-       int locked;
-
-       if (phy != 0)           /* RTL8150 supports PHY == 0, only */
-               return (0);
-
-       locked = mtx_owned(&sc->sc_mtx);
-       if (!locked)
-               RUE_LOCK(sc);
-
-       switch (reg) {
-       case MII_BMCR:
-               ruereg = RUE_BMCR;
-               break;
-       case MII_BMSR:
-               ruereg = RUE_BMSR;
-               break;
-       case MII_ANAR:
-               ruereg = RUE_ANAR;
-               break;
-       case MII_ANER:
-               ruereg = RUE_AER;
-               break;
-       case MII_ANLPAR:
-               ruereg = RUE_ANLP;
-               break;
-       case MII_PHYIDR1:
-       case MII_PHYIDR2:
-               rval = 0;
-               goto done;
-       default:
-               if (RUE_REG_MIN <= reg && reg <= RUE_REG_MAX) {
-                       rval = rue_csr_read_1(sc, reg);
-                       goto done;
-               }
-               device_printf(sc->sc_ue.ue_dev, "bad phy register\n");
-               rval = 0;
-               goto done;
-       }
-
-       rval = rue_csr_read_2(sc, ruereg);
-done:
-       if (!locked)
-               RUE_UNLOCK(sc);
-       return (rval);
-}
-
-static int
-rue_miibus_writereg(device_t dev, int phy, int reg, int data)
-{
-       struct rue_softc *sc = device_get_softc(dev);
-       uint16_t ruereg;
-       int locked;
-
-       if (phy != 0)           /* RTL8150 supports PHY == 0, only */
-               return (0);
-
-       locked = mtx_owned(&sc->sc_mtx);
-       if (!locked)
-               RUE_LOCK(sc);
-
-       switch (reg) {
-       case MII_BMCR:
-               ruereg = RUE_BMCR;
-               break;
-       case MII_BMSR:
-               ruereg = RUE_BMSR;
-               break;
-       case MII_ANAR:
-               ruereg = RUE_ANAR;
-               break;
-       case MII_ANER:
-               ruereg = RUE_AER;
-               break;
-       case MII_ANLPAR:
-               ruereg = RUE_ANLP;
-               break;
-       case MII_PHYIDR1:
-       case MII_PHYIDR2:
-               goto done;
-       default:
-               if (RUE_REG_MIN <= reg && reg <= RUE_REG_MAX) {
-                       rue_csr_write_1(sc, reg, data);
-                       goto done;
-               }
-               device_printf(sc->sc_ue.ue_dev, " bad phy register\n");
-               goto done;
-       }
-       rue_csr_write_2(sc, ruereg, data);
-done:
-       if (!locked)
-               RUE_UNLOCK(sc);
-       return (0);
-}
-
-static void
-rue_miibus_statchg(device_t dev)
-{
-       /*
-        * When the code below is enabled the card starts doing weird
-        * things after link going from UP to DOWN and back UP.
-        *
-        * Looks like some of register writes below messes up PHY
-        * interface.
-        *
-        * No visible regressions were found after commenting this code
-        * out, so that disable it for good.
-        */
-#if 0
-       struct rue_softc *sc = device_get_softc(dev);
-       struct mii_data *mii = GET_MII(sc);
-       uint16_t bmcr;
-       int locked;
-
-       locked = mtx_owned(&sc->sc_mtx);
-       if (!locked)
-               RUE_LOCK(sc);
-
-       RUE_CLRBIT(sc, RUE_CR, (RUE_CR_RE | RUE_CR_TE));
-
-       bmcr = rue_csr_read_2(sc, RUE_BMCR);
-
-       if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX)
-               bmcr |= RUE_BMCR_SPD_SET;
-       else
-               bmcr &= ~RUE_BMCR_SPD_SET;
-
-       if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
-               bmcr |= RUE_BMCR_DUPLEX;
-       else
-               bmcr &= ~RUE_BMCR_DUPLEX;
-
-       rue_csr_write_2(sc, RUE_BMCR, bmcr);
-
-       RUE_SETBIT(sc, RUE_CR, (RUE_CR_RE | RUE_CR_TE));
-
-       if (!locked)
-               RUE_UNLOCK(sc);
-#endif
-}
-
-static void
-rue_setpromisc(struct usb_ether *ue)
-{
-       struct rue_softc *sc = uether_getsc(ue);
-       struct ifnet *ifp = uether_getifp(ue);
-
-       RUE_LOCK_ASSERT(sc, MA_OWNED);
-
-       /* If we want promiscuous mode, set the allframes bit. */
-       if (ifp->if_flags & IFF_PROMISC)
-               RUE_SETBIT(sc, RUE_RCR, RUE_RCR_AAP);
-       else
-               RUE_CLRBIT(sc, RUE_RCR, RUE_RCR_AAP);
-}
-
-/*
- * Program the 64-bit multicast hash filter.
- */
-static void
-rue_setmulti(struct usb_ether *ue)
-{
-       struct rue_softc *sc = uether_getsc(ue);
-       struct ifnet *ifp = uether_getifp(ue);
-       uint16_t rxcfg;
-       int h = 0;
-       uint32_t hashes[2] = { 0, 0 };
-       struct ifmultiaddr *ifma;
-       int mcnt = 0;
-
-       RUE_LOCK_ASSERT(sc, MA_OWNED);
-
-       rxcfg = rue_csr_read_2(sc, RUE_RCR);
-
-       if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
-               rxcfg |= (RUE_RCR_AAM | RUE_RCR_AAP);
-               rxcfg &= ~RUE_RCR_AM;
-               rue_csr_write_2(sc, RUE_RCR, rxcfg);
-               rue_csr_write_4(sc, RUE_MAR0, 0xFFFFFFFF);
-               rue_csr_write_4(sc, RUE_MAR4, 0xFFFFFFFF);
-               return;
-       }
-
-       /* first, zot all the existing hash bits */
-       rue_csr_write_4(sc, RUE_MAR0, 0);
-       rue_csr_write_4(sc, RUE_MAR4, 0);
-
-       /* now program new ones */
-       if_maddr_rlock(ifp);
-       TAILQ_FOREACH (ifma, &ifp->if_multiaddrs, ifma_link)
-       {
-               if (ifma->ifma_addr->sa_family != AF_LINK)
-                       continue;
-               h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
-                   ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
-               if (h < 32)
-                       hashes[0] |= (1 << h);
-               else
-                       hashes[1] |= (1 << (h - 32));
-               mcnt++;
-       }
-       if_maddr_runlock(ifp);
-
-       if (mcnt)
-               rxcfg |= RUE_RCR_AM;
-       else
-               rxcfg &= ~RUE_RCR_AM;
-
-       rxcfg &= ~(RUE_RCR_AAM | RUE_RCR_AAP);
-
-       rue_csr_write_2(sc, RUE_RCR, rxcfg);
-       rue_csr_write_4(sc, RUE_MAR0, hashes[0]);
-       rue_csr_write_4(sc, RUE_MAR4, hashes[1]);
-}
-
-static void
-rue_reset(struct rue_softc *sc)
-{
-       int i;
-
-       rue_csr_write_1(sc, RUE_CR, RUE_CR_SOFT_RST);
-
-       for (i = 0; i != RUE_TIMEOUT; i++) {
-               if (uether_pause(&sc->sc_ue, hz / 1000))
-                       break;
-               if (!(rue_csr_read_1(sc, RUE_CR) & RUE_CR_SOFT_RST))
-                       break;
-       }
-       if (i == RUE_TIMEOUT)
-               device_printf(sc->sc_ue.ue_dev, "reset never completed\n");
-
-       uether_pause(&sc->sc_ue, hz / 100);
-}
-
-static void
-rue_attach_post(struct usb_ether *ue)
-{
-       struct rue_softc *sc = uether_getsc(ue);
-
-       /* reset the adapter */
-       rue_reset(sc);
-
-       /* get station address from the EEPROM */
-       rue_read_mem(sc, RUE_EEPROM_IDR0, ue->ue_eaddr, ETHER_ADDR_LEN);
-}
-
-/*
- * Probe for a RTL8150 chip.
- */
-static int
-rue_probe(device_t dev)
-{
-       struct usb_attach_arg *uaa = device_get_ivars(dev);
-
-       if (uaa->usb_mode != USB_MODE_HOST)
-               return (ENXIO);
-       if (uaa->info.bConfigIndex != RUE_CONFIG_IDX)
-               return (ENXIO);
-       if (uaa->info.bIfaceIndex != RUE_IFACE_IDX)
-               return (ENXIO);
-
-       return (usbd_lookup_id_by_uaa(rue_devs, sizeof(rue_devs), uaa));
-}
-
-/*
- * Attach the interface. Allocate softc structures, do ifmedia
- * setup and ethernet/BPF attach.
- */
-static int
-rue_attach(device_t dev)
-{
-       struct usb_attach_arg *uaa = device_get_ivars(dev);
-       struct rue_softc *sc = device_get_softc(dev);
-       struct usb_ether *ue = &sc->sc_ue;
-       uint8_t iface_index;
-       int error;
-
-       device_set_usb_desc(dev);
-       mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
-
-       iface_index = RUE_IFACE_IDX;
-       error = usbd_transfer_setup(uaa->device, &iface_index,
-           sc->sc_xfer, rue_config, RUE_N_TRANSFER,
-           sc, &sc->sc_mtx);
-       if (error) {
-               device_printf(dev, "allocating USB transfers failed\n");
-               goto detach;
-       }
-
-       ue->ue_sc = sc;
-       ue->ue_dev = dev;
-       ue->ue_udev = uaa->device;
-       ue->ue_mtx = &sc->sc_mtx;
-       ue->ue_methods = &rue_ue_methods;
-
-       error = uether_ifattach(ue);
-       if (error) {
-               device_printf(dev, "could not attach interface\n");
-               goto detach;
-       }
-       return (0);                     /* success */
-
-detach:
-       rue_detach(dev);
-       return (ENXIO);                 /* failure */
-}
-
-static int
-rue_detach(device_t dev)
-{
-       struct rue_softc *sc = device_get_softc(dev);
-       struct usb_ether *ue = &sc->sc_ue;
-
-       usbd_transfer_unsetup(sc->sc_xfer, RUE_N_TRANSFER);
-       uether_ifdetach(ue);
-       mtx_destroy(&sc->sc_mtx);
-
-       return (0);
-}
-
-static void
-rue_intr_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct rue_softc *sc = usbd_xfer_softc(xfer);
-       struct ifnet *ifp = uether_getifp(&sc->sc_ue);
-       struct rue_intrpkt pkt;
-       struct usb_page_cache *pc;
-       int actlen;
-
-       usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-
-               if (ifp && (ifp->if_drv_flags & IFF_DRV_RUNNING) &&
-                   actlen >= sizeof(pkt)) {
-
-                       pc = usbd_xfer_get_frame(xfer, 0);
-                       usbd_copy_out(pc, 0, &pkt, sizeof(pkt));
-
-                       ifp->if_ierrors += pkt.rue_rxlost_cnt;
-                       ifp->if_ierrors += pkt.rue_crcerr_cnt;
-                       ifp->if_collisions += pkt.rue_col_cnt;
-               }
-               /* FALLTHROUGH */
-       case USB_ST_SETUP:
-tr_setup:
-               usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
-               usbd_transfer_submit(xfer);
-               return;
-
-       default:                        /* Error */
-               if (error != USB_ERR_CANCELLED) {
-                       /* try to clear stall first */
-                       usbd_xfer_set_stall(xfer);
-                       goto tr_setup;
-               }
-               return;
-       }
-}
-
-static void
-rue_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct rue_softc *sc = usbd_xfer_softc(xfer);
-       struct usb_ether *ue = &sc->sc_ue;
-       struct ifnet *ifp = uether_getifp(ue);
-       struct usb_page_cache *pc;
-       uint16_t status;
-       int actlen;
-
-       usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-
-               if (actlen < 4) {
-                       ifp->if_ierrors++;
-                       goto tr_setup;
-               }
-               pc = usbd_xfer_get_frame(xfer, 0);
-               usbd_copy_out(pc, actlen - 4, &status, sizeof(status));
-               actlen -= 4;
-
-               /* check recieve packet was valid or not */
-               status = le16toh(status);
-               if ((status & RUE_RXSTAT_VALID) == 0) {
-                       ifp->if_ierrors++;
-                       goto tr_setup;
-               }
-               uether_rxbuf(ue, pc, 0, actlen);
-               /* FALLTHROUGH */
-       case USB_ST_SETUP:
-tr_setup:
-               usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
-               usbd_transfer_submit(xfer);
-               uether_rxflush(ue);
-               return;
-
-       default:                        /* Error */
-               DPRINTF("bulk read error, %s\n",
-                   usbd_errstr(error));
-
-               if (error != USB_ERR_CANCELLED) {
-                       /* try to clear stall first */
-                       usbd_xfer_set_stall(xfer);
-                       goto tr_setup;
-               }
-               return;
-       }
-}
-
-static void
-rue_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct rue_softc *sc = usbd_xfer_softc(xfer);
-       struct ifnet *ifp = uether_getifp(&sc->sc_ue);
-       struct usb_page_cache *pc;
-       struct mbuf *m;
-       int temp_len;
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               DPRINTFN(11, "transfer complete\n");
-               ifp->if_opackets++;
-
-               /* FALLTHROUGH */
-       case USB_ST_SETUP:
-tr_setup:
-               if ((sc->sc_flags & RUE_FLAG_LINK) == 0) {
-                       /*
-                        * don't send anything if there is no link !
-                        */
-                       return;
-               }
-               IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
-
-               if (m == NULL)
-                       return;
-               if (m->m_pkthdr.len > MCLBYTES)
-                       m->m_pkthdr.len = MCLBYTES;
-               temp_len = m->m_pkthdr.len;
-
-               pc = usbd_xfer_get_frame(xfer, 0);
-               usbd_m_copy_in(pc, 0, m, 0, m->m_pkthdr.len);
-
-               /*
-                * This is an undocumented behavior.
-                * RTL8150 chip doesn't send frame length smaller than
-                * RUE_MIN_FRAMELEN (60) byte packet.
-                */
-               if (temp_len < RUE_MIN_FRAMELEN) {
-                       usbd_frame_zero(pc, temp_len,
-                           RUE_MIN_FRAMELEN - temp_len);
-                       temp_len = RUE_MIN_FRAMELEN;
-               }
-               usbd_xfer_set_frame_len(xfer, 0, temp_len);
-
-               /*
-                * if there's a BPF listener, bounce a copy
-                * of this frame to him:
-                */
-               BPF_MTAP(ifp, m);
-
-               m_freem(m);
-
-               usbd_transfer_submit(xfer);
-
-               return;
-
-       default:                        /* Error */
-               DPRINTFN(11, "transfer error, %s\n",
-                   usbd_errstr(error));
-
-               ifp->if_oerrors++;
-
-               if (error != USB_ERR_CANCELLED) {
-                       /* try to clear stall first */
-                       usbd_xfer_set_stall(xfer);
-                       goto tr_setup;
-               }
-               return;
-       }
-}
-
-static void
-rue_tick(struct usb_ether *ue)
-{
-       struct rue_softc *sc = uether_getsc(ue);
-       struct mii_data *mii = GET_MII(sc);
-
-       RUE_LOCK_ASSERT(sc, MA_OWNED);
-
-       mii_tick(mii);
-       if ((sc->sc_flags & RUE_FLAG_LINK) == 0
-           && mii->mii_media_status & IFM_ACTIVE &&
-           IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
-               sc->sc_flags |= RUE_FLAG_LINK;
-               rue_start(ue);
-       }
-}
-
-static void
-rue_start(struct usb_ether *ue)
-{
-       struct rue_softc *sc = uether_getsc(ue);
-
-       /*
-        * start the USB transfers, if not already started:
-        */
-       usbd_transfer_start(sc->sc_xfer[RUE_INTR_DT_RD]);
-       usbd_transfer_start(sc->sc_xfer[RUE_BULK_DT_RD]);
-       usbd_transfer_start(sc->sc_xfer[RUE_BULK_DT_WR]);
-}
-
-static void
-rue_init(struct usb_ether *ue)
-{
-       struct rue_softc *sc = uether_getsc(ue);
-       struct ifnet *ifp = uether_getifp(ue);
-
-       RUE_LOCK_ASSERT(sc, MA_OWNED);
-
-       /*
-        * Cancel pending I/O
-        */
-       rue_reset(sc);
-
-       /* Set MAC address */
-       rue_write_mem(sc, RUE_IDR0, IF_LLADDR(ifp), ETHER_ADDR_LEN);
-
-       rue_stop(ue);
-
-       /*
-        * Set the initial TX and RX configuration.
-        */
-       rue_csr_write_1(sc, RUE_TCR, RUE_TCR_CONFIG);
-       rue_csr_write_2(sc, RUE_RCR, RUE_RCR_CONFIG|RUE_RCR_AB);
-
-       /* Load the multicast filter */
-       rue_setpromisc(ue);
-       /* Load the multicast filter. */
-       rue_setmulti(ue);
-
-       /* Enable RX and TX */
-       rue_csr_write_1(sc, RUE_CR, (RUE_CR_TE | RUE_CR_RE | RUE_CR_EP3CLREN));
-
-       usbd_xfer_set_stall(sc->sc_xfer[RUE_BULK_DT_WR]);
-
-       ifp->if_drv_flags |= IFF_DRV_RUNNING;
-       rue_start(ue);
-}
-
-/*
- * Set media options.
- */
-static int
-rue_ifmedia_upd(struct ifnet *ifp)
-{
-       struct rue_softc *sc = ifp->if_softc;
-       struct mii_data *mii = GET_MII(sc);
-       struct mii_softc *miisc;
-
-       RUE_LOCK_ASSERT(sc, MA_OWNED);
-
-        sc->sc_flags &= ~RUE_FLAG_LINK;
-       LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
-               PHY_RESET(miisc);
-       mii_mediachg(mii);
-       return (0);
-}
-
-/*
- * Report current media status.
- */
-static void
-rue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct rue_softc *sc = ifp->if_softc;
-       struct mii_data *mii = GET_MII(sc);
-
-       RUE_LOCK(sc);
-       mii_pollstat(mii);
-       ifmr->ifm_active = mii->mii_media_active;
-       ifmr->ifm_status = mii->mii_media_status;
-       RUE_UNLOCK(sc);
-}
-
-static void
-rue_stop(struct usb_ether *ue)
-{
-       struct rue_softc *sc = uether_getsc(ue);
-       struct ifnet *ifp = uether_getifp(ue);
-
-       RUE_LOCK_ASSERT(sc, MA_OWNED);
-
-       ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-       sc->sc_flags &= ~RUE_FLAG_LINK;
-
-       /*
-        * stop all the transfers, if not already stopped:
-        */
-       usbd_transfer_stop(sc->sc_xfer[RUE_BULK_DT_WR]);
-       usbd_transfer_stop(sc->sc_xfer[RUE_BULK_DT_RD]);
-       usbd_transfer_stop(sc->sc_xfer[RUE_INTR_DT_RD]);
-
-       rue_csr_write_1(sc, RUE_CR, 0x00);
-
-       rue_reset(sc);
-}
diff --git a/sys/bus/u4b/net/if_ruereg.h b/sys/bus/u4b/net/if_ruereg.h
deleted file mode 100644 (file)
index c90a969..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/*-
- * Copyright (c) 2001-2003, Shunsuke Akiyama <akiyama@FreeBSD.org>.
- * All rights reserved.
- *
- * 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 AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#define        RUE_CONFIG_IDX          0       /* config number 1 */
-#define        RUE_IFACE_IDX           0
-
-#define        RUE_INTR_PKTLEN         0x8
-
-#define        RUE_TIMEOUT             50
-#define        RUE_MIN_FRAMELEN        60
-
-/* Registers. */
-#define        RUE_IDR0                0x0120
-#define        RUE_IDR1                0x0121
-#define        RUE_IDR2                0x0122
-#define        RUE_IDR3                0x0123
-#define        RUE_IDR4                0x0124
-#define        RUE_IDR5                0x0125
-
-#define        RUE_MAR0                0x0126
-#define        RUE_MAR1                0x0127
-#define        RUE_MAR2                0x0128
-#define        RUE_MAR3                0x0129
-#define        RUE_MAR4                0x012A
-#define        RUE_MAR5                0x012B
-#define        RUE_MAR6                0x012C
-#define        RUE_MAR7                0x012D
-
-#define        RUE_CR                  0x012E  /* B, R/W */
-#define        RUE_CR_SOFT_RST         0x10
-#define        RUE_CR_RE               0x08
-#define        RUE_CR_TE               0x04
-#define        RUE_CR_EP3CLREN         0x02
-
-#define        RUE_TCR                 0x012F  /* B, R/W */
-#define        RUE_TCR_TXRR1           0x80
-#define        RUE_TCR_TXRR0           0x40
-#define        RUE_TCR_IFG1            0x10
-#define        RUE_TCR_IFG0            0x08
-#define        RUE_TCR_NOCRC           0x01
-#define        RUE_TCR_CONFIG          (RUE_TCR_TXRR1 | RUE_TCR_TXRR0 |        \
-                                   RUE_TCR_IFG1 | RUE_TCR_IFG0)
-
-#define        RUE_RCR                 0x0130  /* W, R/W */
-#define        RUE_RCR_TAIL            0x80
-#define        RUE_RCR_AER             0x40
-#define        RUE_RCR_AR              0x20
-#define        RUE_RCR_AM              0x10
-#define        RUE_RCR_AB              0x08
-#define        RUE_RCR_AD              0x04
-#define        RUE_RCR_AAM             0x02
-#define        RUE_RCR_AAP             0x01
-#define        RUE_RCR_CONFIG          (RUE_RCR_TAIL | RUE_RCR_AD)
-
-#define        RUE_TSR                 0x0132
-#define        RUE_RSR                 0x0133
-#define        RUE_CON0                0x0135
-#define        RUE_CON1                0x0136
-#define        RUE_MSR                 0x0137
-#define        RUE_PHYADD              0x0138
-#define        RUE_PHYDAT              0x0139
-
-#define        RUE_PHYCNT              0x013B  /* B, R/W */
-#define        RUE_PHYCNT_PHYOWN       0x40
-#define        RUE_PHYCNT_RWCR         0x20
-
-#define        RUE_GPPC                0x013D
-#define        RUE_WAKECNT             0x013E
-
-#define        RUE_BMCR                0x0140
-#define        RUE_BMCR_SPD_SET        0x2000
-#define        RUE_BMCR_DUPLEX         0x0100
-
-#define        RUE_BMSR                0x0142
-
-#define        RUE_ANAR                0x0144  /* W, R/W */
-#define        RUE_ANAR_PAUSE          0x0400
-
-#define        RUE_ANLP                0x0146  /* W, R/O */
-#define        RUE_ANLP_PAUSE          0x0400
-
-#define        RUE_AER                 0x0148
-
-#define        RUE_NWAYT               0x014A
-#define        RUE_CSCR                0x014C
-
-#define        RUE_CRC0                0x014E
-#define        RUE_CRC1                0x0150
-#define        RUE_CRC2                0x0152
-#define        RUE_CRC3                0x0154
-#define        RUE_CRC4                0x0156
-
-#define        RUE_BYTEMASK0           0x0158
-#define        RUE_BYTEMASK1           0x0160
-#define        RUE_BYTEMASK2           0x0168
-#define        RUE_BYTEMASK3           0x0170
-#define        RUE_BYTEMASK4           0x0178
-
-#define        RUE_PHY1                0x0180
-#define        RUE_PHY2                0x0184
-
-#define        RUE_TW1                 0x0186
-
-#define        RUE_REG_MIN             0x0120
-#define        RUE_REG_MAX             0x0189
-
-/* EEPROM address declarations. */
-#define        RUE_EEPROM_BASE         0x1200
-#define        RUE_EEPROM_IDR0         (RUE_EEPROM_BASE + 0x02)
-#define        RUE_EEPROM_IDR1         (RUE_EEPROM_BASE + 0x03)
-#define        RUE_EEPROM_IDR2         (RUE_EEPROM_BASE + 0x03)
-#define        RUE_EEPROM_IDR3         (RUE_EEPROM_BASE + 0x03)
-#define        RUE_EEPROM_IDR4         (RUE_EEPROM_BASE + 0x03)
-#define        RUE_EEPROM_IDR5         (RUE_EEPROM_BASE + 0x03)
-#define        RUE_EEPROM_INTERVAL     (RUE_EEPROM_BASE + 0x17)
-
-#define        RUE_RXSTAT_VALID        (0x01 << 12)
-#define        RUE_RXSTAT_RUNT         (0x02 << 12)
-#define        RUE_RXSTAT_PMATCH       (0x04 << 12)
-#define        RUE_RXSTAT_MCAST        (0x08 << 12)
-
-#define        GET_MII(sc)             uether_getmii(&(sc)->sc_ue)
-
-struct rue_intrpkt {
-       uint8_t rue_tsr;
-       uint8_t rue_rsr;
-       uint8_t rue_gep_msr;
-       uint8_t rue_waksr;
-       uint8_t rue_txok_cnt;
-       uint8_t rue_rxlost_cnt;
-       uint8_t rue_crcerr_cnt;
-       uint8_t rue_col_cnt;
-} __packed;
-
-enum {
-       RUE_BULK_DT_WR,
-       RUE_BULK_DT_RD,
-       RUE_INTR_DT_RD,
-       RUE_N_TRANSFER,
-};
-
-struct rue_softc {
-       struct usb_ether        sc_ue;
-       struct mtx              sc_mtx;
-       struct usb_xfer *sc_xfer[RUE_N_TRANSFER];
-
-       int                     sc_flags;
-#define        RUE_FLAG_LINK           0x0001
-};
-
-#define        RUE_LOCK(_sc)           mtx_lock(&(_sc)->sc_mtx)
-#define        RUE_UNLOCK(_sc)         mtx_unlock(&(_sc)->sc_mtx)
-#define        RUE_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->sc_mtx, t)
diff --git a/sys/bus/u4b/net/if_usie.c b/sys/bus/u4b/net/if_usie.c
deleted file mode 100644 (file)
index e476dae..0000000
+++ /dev/null
@@ -1,1588 +0,0 @@
-/*-
- * Copyright (c) 2011 Anybots Inc
- * written by Akinori Furukoshi <moonlightakkiy@yahoo.ca>
- *  - ucom part is based on u3g.c
- *
- * 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 AUTHOR 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 AUTHOR 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/queue.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/bus.h>
-#include <sys/module.h>
-#include <sys/sockio.h>
-#include <sys/socket.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/condvar.h>
-#include <sys/sysctl.h>
-#include <sys/malloc.h>
-#include <sys/taskqueue.h>
-
-#include <machine/bus.h>
-
-#include <net/if.h>
-#include <net/if_types.h>
-#include <net/netisr.h>
-#include <net/bpf.h>
-#include <net/ethernet.h>
-
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-#include <netinet/udp.h>
-
-#include <net80211/ieee80211_ioctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usb_cdc.h>
-#include "usbdevs.h"
-
-#define        USB_DEBUG_VAR usie_debug
-#include <dev/usb/usb_debug.h>
-#include <dev/usb/usb_process.h>
-#include <dev/usb/usb_msctest.h>
-
-#include <dev/usb/serial/usb_serial.h>
-
-#include <dev/usb/net/if_usievar.h>
-
-#ifdef USB_DEBUG
-static int usie_debug = 0;
-
-static SYSCTL_NODE(_hw_usb, OID_AUTO, usie, CTLFLAG_RW, 0, "sierra USB modem");
-SYSCTL_INT(_hw_usb_usie, OID_AUTO, debug, CTLFLAG_RWTUN, &usie_debug, 0,
-    "usie debug level");
-#endif
-
-/* Sierra Wireless Direct IP modems */
-static const STRUCT_USB_HOST_ID usie_devs[] = {
-#define        USIE_DEV(v, d) {                                \
-    USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##d) }
-       USIE_DEV(SIERRA, MC8700),
-       USIE_DEV(SIERRA, TRUINSTALL),
-       USIE_DEV(AIRPRIME, USB308),
-#undef USIE_DEV
-};
-
-static device_probe_t usie_probe;
-static device_attach_t usie_attach;
-static device_detach_t usie_detach;
-
-static void usie_uc_update_line_state(struct ucom_softc *, uint8_t);
-static void usie_uc_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *);
-static void usie_uc_cfg_set_dtr(struct ucom_softc *, uint8_t);
-static void usie_uc_cfg_set_rts(struct ucom_softc *, uint8_t);
-static void usie_uc_cfg_open(struct ucom_softc *);
-static void usie_uc_cfg_close(struct ucom_softc *);
-static void usie_uc_start_read(struct ucom_softc *);
-static void usie_uc_stop_read(struct ucom_softc *);
-static void usie_uc_start_write(struct ucom_softc *);
-static void usie_uc_stop_write(struct ucom_softc *);
-
-static usb_callback_t usie_uc_tx_callback;
-static usb_callback_t usie_uc_rx_callback;
-static usb_callback_t usie_uc_status_callback;
-static usb_callback_t usie_if_tx_callback;
-static usb_callback_t usie_if_rx_callback;
-static usb_callback_t usie_if_status_callback;
-
-static void usie_if_sync_to(void *);
-static void usie_if_sync_cb(void *, int);
-static void usie_if_status_cb(void *, int);
-
-static void usie_if_start(struct ifnet *, struct ifaltq_subque *);
-static int usie_if_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct route *);
-static void usie_if_init(void *);
-static void usie_if_stop(struct usie_softc *);
-static int usie_if_ioctl(struct ifnet *, u_long, caddr_t);
-
-static int usie_do_request(struct usie_softc *, struct usb_device_request *, void *);
-static int usie_if_cmd(struct usie_softc *, uint8_t);
-static void usie_cns_req(struct usie_softc *, uint32_t, uint16_t);
-static void usie_cns_rsp(struct usie_softc *, struct usie_cns *);
-static void usie_hip_rsp(struct usie_softc *, uint8_t *, uint32_t);
-static int usie_driver_loaded(struct module *, int, void *);
-
-static const struct usb_config usie_uc_config[USIE_UC_N_XFER] = {
-       [USIE_UC_STATUS] = {
-               .type = UE_INTERRUPT,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_IN,
-               .bufsize = 0,           /* use wMaxPacketSize */
-               .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
-               .callback = &usie_uc_status_callback,
-       },
-       [USIE_UC_RX] = {
-               .type = UE_BULK,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_IN,
-               .bufsize = USIE_BUFSIZE,
-               .flags = {.pipe_bof = 1,.short_xfer_ok = 1,.proxy_buffer = 1,},
-               .callback = &usie_uc_rx_callback,
-       },
-       [USIE_UC_TX] = {
-               .type = UE_BULK,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_OUT,
-               .bufsize = USIE_BUFSIZE,
-               .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
-               .callback = &usie_uc_tx_callback,
-       }
-};
-
-static const struct usb_config usie_if_config[USIE_IF_N_XFER] = {
-       [USIE_IF_STATUS] = {
-               .type = UE_INTERRUPT,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_IN,
-               .bufsize = 0,           /* use wMaxPacketSize */
-               .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
-               .callback = &usie_if_status_callback,
-       },
-       [USIE_IF_RX] = {
-               .type = UE_BULK,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_IN,
-               .bufsize = USIE_BUFSIZE,
-               .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
-               .callback = &usie_if_rx_callback,
-       },
-       [USIE_IF_TX] = {
-               .type = UE_BULK,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_OUT,
-               .bufsize = MAX(USIE_BUFSIZE, MCLBYTES),
-               .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
-               .callback = &usie_if_tx_callback,
-       }
-};
-
-static device_method_t usie_methods[] = {
-       DEVMETHOD(device_probe, usie_probe),
-       DEVMETHOD(device_attach, usie_attach),
-       DEVMETHOD(device_detach, usie_detach),
-       DEVMETHOD_END
-};
-
-static driver_t usie_driver = {
-       .name = "usie",
-       .methods = usie_methods,
-       .size = sizeof(struct usie_softc),
-};
-
-static devclass_t usie_devclass;
-static eventhandler_tag usie_etag;
-
-DRIVER_MODULE(usie, uhub, usie_driver, usie_devclass, usie_driver_loaded, NULL);
-MODULE_DEPEND(usie, ucom, 1, 1, 1);
-MODULE_DEPEND(usie, usb, 1, 1, 1);
-MODULE_VERSION(usie, 1);
-
-static const struct ucom_callback usie_uc_callback = {
-       .ucom_cfg_get_status = &usie_uc_cfg_get_status,
-       .ucom_cfg_set_dtr = &usie_uc_cfg_set_dtr,
-       .ucom_cfg_set_rts = &usie_uc_cfg_set_rts,
-       .ucom_cfg_open = &usie_uc_cfg_open,
-       .ucom_cfg_close = &usie_uc_cfg_close,
-       .ucom_start_read = &usie_uc_start_read,
-       .ucom_stop_read = &usie_uc_stop_read,
-       .ucom_start_write = &usie_uc_start_write,
-       .ucom_stop_write = &usie_uc_stop_write,
-};
-
-static void
-usie_autoinst(void *arg, struct usb_device *udev,
-    struct usb_attach_arg *uaa)
-{
-       struct usb_interface *iface;
-       struct usb_interface_descriptor *id;
-       struct usb_device_request req;
-       int err;
-
-       if (uaa->dev_state != UAA_DEV_READY)
-               return;
-
-       iface = usbd_get_iface(udev, 0);
-       if (iface == NULL)
-               return;
-
-       id = iface->idesc;
-       if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
-               return;
-
-       if (usbd_lookup_id_by_uaa(usie_devs, sizeof(usie_devs), uaa) != 0)
-               return;                 /* no device match */
-
-       if (bootverbose) {
-               DPRINTF("Ejecting %s %s\n",
-                   usb_get_manufacturer(udev),
-                   usb_get_product(udev));
-       }
-       req.bmRequestType = UT_VENDOR;
-       req.bRequest = UR_SET_INTERFACE;
-       USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
-       USETW(req.wIndex, UHF_PORT_CONNECTION);
-       USETW(req.wLength, 0);
-
-       /* at this moment there is no mutex */
-       err = usbd_do_request_flags(udev, NULL, &req,
-           NULL, 0, NULL, 250 /* ms */ );
-
-       /* success, mark the udev as disappearing */
-       if (err == 0)
-               uaa->dev_state = UAA_DEV_EJECTING;
-}
-
-static int
-usie_probe(device_t self)
-{
-       struct usb_attach_arg *uaa = device_get_ivars(self);
-
-       if (uaa->usb_mode != USB_MODE_HOST)
-               return (ENXIO);
-       if (uaa->info.bConfigIndex != USIE_CNFG_INDEX)
-               return (ENXIO);
-       if (uaa->info.bIfaceIndex != USIE_IFACE_INDEX)
-               return (ENXIO);
-       if (uaa->info.bInterfaceClass != UICLASS_VENDOR)
-               return (ENXIO);
-
-       return (usbd_lookup_id_by_uaa(usie_devs, sizeof(usie_devs), uaa));
-}
-
-static int
-usie_attach(device_t self)
-{
-       struct usie_softc *sc = device_get_softc(self);
-       struct usb_attach_arg *uaa = device_get_ivars(self);
-       struct ifnet *ifp;
-       struct usb_interface *iface;
-       struct usb_interface_descriptor *id;
-       struct usb_device_request req;
-       int err;
-       uint16_t fwattr;
-       uint8_t iface_index;
-       uint8_t ifidx;
-       uint8_t start;
-
-       device_set_usb_desc(self);
-       sc->sc_udev = uaa->device;
-       sc->sc_dev = self;
-
-       mtx_init(&sc->sc_mtx, "usie", MTX_NETWORK_LOCK, MTX_DEF);
-
-       TASK_INIT(&sc->sc_if_status_task, 0, usie_if_status_cb, sc);
-       TASK_INIT(&sc->sc_if_sync_task, 0, usie_if_sync_cb, sc);
-
-       usb_callout_init_mtx(&sc->sc_if_sync_ch, &sc->sc_mtx, 0);
-
-       mtx_lock(&sc->sc_mtx);
-
-       /* set power mode to D0 */
-       req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
-       req.bRequest = USIE_POWER;
-       USETW(req.wValue, 0);
-       USETW(req.wIndex, 0);
-       USETW(req.wLength, 0);
-       if (usie_do_request(sc, &req, NULL)) {
-               mtx_unlock(&sc->sc_mtx);
-               goto detach;
-       }
-       /* read fw attr */
-       fwattr = 0;
-       req.bmRequestType = UT_READ_VENDOR_DEVICE;
-       req.bRequest = USIE_FW_ATTR;
-       USETW(req.wValue, 0);
-       USETW(req.wIndex, 0);
-       USETW(req.wLength, sizeof(fwattr));
-       if (usie_do_request(sc, &req, &fwattr)) {
-               mtx_unlock(&sc->sc_mtx);
-               goto detach;
-       }
-       mtx_unlock(&sc->sc_mtx);
-
-       /* check DHCP supports */
-       DPRINTF("fwattr=%x\n", fwattr);
-       if (!(fwattr & USIE_FW_DHCP)) {
-               device_printf(self, "DHCP is not supported. A firmware upgrade might be needed.\n");
-       }
-
-       /* find available interfaces */
-       sc->sc_nucom = 0;
-       for (ifidx = 0; ifidx < USIE_IFACE_MAX; ifidx++) {
-               iface = usbd_get_iface(uaa->device, ifidx);
-               if (iface == NULL)
-                       break;
-
-               id = usbd_get_interface_descriptor(iface);
-               if ((id == NULL) || (id->bInterfaceClass != UICLASS_VENDOR))
-                       continue;
-
-               /* setup Direct IP transfer */
-               if (id->bInterfaceNumber >= 7 && id->bNumEndpoints == 3) {
-                       sc->sc_if_ifnum = id->bInterfaceNumber;
-                       iface_index = ifidx;
-
-                       DPRINTF("ifnum=%d, ifidx=%d\n",
-                           sc->sc_if_ifnum, ifidx);
-
-                       err = usbd_transfer_setup(uaa->device,
-                           &iface_index, sc->sc_if_xfer, usie_if_config,
-                           USIE_IF_N_XFER, sc, &sc->sc_mtx);
-
-                       if (err == 0)
-                               continue;
-
-                       device_printf(self,
-                           "could not allocate USB transfers on "
-                           "iface_index=%d, err=%s\n",
-                           iface_index, usbd_errstr(err));
-                       goto detach;
-               }
-
-               /* setup ucom */
-               if (sc->sc_nucom >= USIE_UCOM_MAX)
-                       continue;
-
-               usbd_set_parent_iface(uaa->device, ifidx,
-                   uaa->info.bIfaceIndex);
-
-               DPRINTF("NumEndpoints=%d bInterfaceNumber=%d\n",
-                   id->bNumEndpoints, id->bInterfaceNumber);
-
-               if (id->bNumEndpoints == 2) {
-                       sc->sc_uc_xfer[sc->sc_nucom][0] = NULL;
-                       start = 1;
-               } else
-                       start = 0;
-
-               err = usbd_transfer_setup(uaa->device, &ifidx,
-                   sc->sc_uc_xfer[sc->sc_nucom] + start,
-                   usie_uc_config + start, USIE_UC_N_XFER - start,
-                   &sc->sc_ucom[sc->sc_nucom], &sc->sc_mtx);
-
-               if (err != 0) {
-                       DPRINTF("usbd_transfer_setup error=%s\n", usbd_errstr(err));
-                       continue;
-               }
-
-               mtx_lock(&sc->sc_mtx);
-               for (; start < USIE_UC_N_XFER; start++)
-                       usbd_xfer_set_stall(sc->sc_uc_xfer[sc->sc_nucom][start]);
-               mtx_unlock(&sc->sc_mtx);
-
-               sc->sc_uc_ifnum[sc->sc_nucom] = id->bInterfaceNumber;
-
-               sc->sc_nucom++;         /* found a port */
-       }
-
-       if (sc->sc_nucom == 0) {
-               device_printf(self, "no comports found\n");
-               goto detach;
-       }
-
-       err = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom,
-           sc->sc_nucom, sc, &usie_uc_callback, &sc->sc_mtx);
-
-       if (err != 0) {
-               DPRINTF("ucom_attach failed\n");
-               goto detach;
-       }
-       DPRINTF("Found %d interfaces.\n", sc->sc_nucom);
-
-       /* setup ifnet (Direct IP) */
-       sc->sc_ifp = ifp = if_alloc(IFT_OTHER);
-
-       if (ifp == NULL) {
-               device_printf(self, "Could not allocate a network interface\n");
-               goto detach;
-       }
-       if_initname(ifp, "usie", device_get_unit(self));
-
-       ifp->if_softc = sc;
-       ifp->if_mtu = USIE_MTU_MAX;
-       ifp->if_flags |= IFF_NOARP;
-       ifp->if_init = usie_if_init;
-       ifp->if_ioctl = usie_if_ioctl;
-       ifp->if_start = usie_if_start;
-       ifp->if_output = usie_if_output;
-       IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
-       ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
-       IFQ_SET_READY(&ifp->if_snd);
-
-       if_attach(ifp);
-       bpfattach(ifp, DLT_RAW, 0);
-
-       if (fwattr & USIE_PM_AUTO) {
-               usbd_set_power_mode(uaa->device, USB_POWER_MODE_SAVE);
-               DPRINTF("enabling automatic suspend and resume\n");
-       } else {
-               usbd_set_power_mode(uaa->device, USB_POWER_MODE_ON);
-               DPRINTF("USB power is always ON\n");
-       }
-
-       DPRINTF("device attached\n");
-       return (0);
-
-detach:
-       usie_detach(self);
-       return (ENOMEM);
-}
-
-static int
-usie_detach(device_t self)
-{
-       struct usie_softc *sc = device_get_softc(self);
-       uint8_t x;
-
-       /* detach ifnet */
-       if (sc->sc_ifp != NULL) {
-               usie_if_stop(sc);
-               usbd_transfer_unsetup(sc->sc_if_xfer, USIE_IF_N_XFER);
-               bpfdetach(sc->sc_ifp);
-               if_detach(sc->sc_ifp);
-               if_free(sc->sc_ifp);
-               sc->sc_ifp = NULL;
-       }
-       /* detach ucom */
-       if (sc->sc_nucom > 0)
-               ucom_detach(&sc->sc_super_ucom, sc->sc_ucom);
-
-       /* stop all USB transfers */
-       usbd_transfer_unsetup(sc->sc_if_xfer, USIE_IF_N_XFER);
-
-       for (x = 0; x != USIE_UCOM_MAX; x++)
-               usbd_transfer_unsetup(sc->sc_uc_xfer[x], USIE_UC_N_XFER);
-
-       mtx_destroy(&sc->sc_mtx);
-
-       return (0);
-}
-
-static void
-usie_uc_update_line_state(struct ucom_softc *ucom, uint8_t ls)
-{
-       struct usie_softc *sc = ucom->sc_parent;
-       struct usb_device_request req;
-
-       if (sc->sc_uc_xfer[ucom->sc_subunit][USIE_UC_STATUS] == NULL)
-               return;
-
-       req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
-       req.bRequest = USIE_LINK_STATE;
-       USETW(req.wValue, ls);
-       USETW(req.wIndex, sc->sc_uc_ifnum[ucom->sc_subunit]);
-       USETW(req.wLength, 0);
-
-       DPRINTF("sc_uc_ifnum=%d\n", sc->sc_uc_ifnum[ucom->sc_subunit]);
-
-       usie_do_request(sc, &req, NULL);
-}
-
-static void
-usie_uc_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr)
-{
-       struct usie_softc *sc = ucom->sc_parent;
-
-       *msr = sc->sc_msr;
-       *lsr = sc->sc_lsr;
-}
-
-static void
-usie_uc_cfg_set_dtr(struct ucom_softc *ucom, uint8_t flag)
-{
-       uint8_t dtr;
-
-       dtr = flag ? USIE_LS_DTR : 0;
-       usie_uc_update_line_state(ucom, dtr);
-}
-
-static void
-usie_uc_cfg_set_rts(struct ucom_softc *ucom, uint8_t flag)
-{
-       uint8_t rts;
-
-       rts = flag ? USIE_LS_RTS : 0;
-       usie_uc_update_line_state(ucom, rts);
-}
-
-static void
-usie_uc_cfg_open(struct ucom_softc *ucom)
-{
-       struct usie_softc *sc = ucom->sc_parent;
-
-       /* usbd_transfer_start() is NULL safe */
-
-       usbd_transfer_start(sc->sc_uc_xfer[ucom->sc_subunit][USIE_UC_STATUS]);
-}
-
-static void
-usie_uc_cfg_close(struct ucom_softc *ucom)
-{
-       struct usie_softc *sc = ucom->sc_parent;
-
-       usbd_transfer_stop(sc->sc_uc_xfer[ucom->sc_subunit][USIE_UC_STATUS]);
-}
-
-static void
-usie_uc_start_read(struct ucom_softc *ucom)
-{
-       struct usie_softc *sc = ucom->sc_parent;
-
-       usbd_transfer_start(sc->sc_uc_xfer[ucom->sc_subunit][USIE_UC_RX]);
-}
-
-static void
-usie_uc_stop_read(struct ucom_softc *ucom)
-{
-       struct usie_softc *sc = ucom->sc_parent;
-
-       usbd_transfer_stop(sc->sc_uc_xfer[ucom->sc_subunit][USIE_UC_RX]);
-}
-
-static void
-usie_uc_start_write(struct ucom_softc *ucom)
-{
-       struct usie_softc *sc = ucom->sc_parent;
-
-       usbd_transfer_start(sc->sc_uc_xfer[ucom->sc_subunit][USIE_UC_TX]);
-}
-
-static void
-usie_uc_stop_write(struct ucom_softc *ucom)
-{
-       struct usie_softc *sc = ucom->sc_parent;
-
-       usbd_transfer_stop(sc->sc_uc_xfer[ucom->sc_subunit][USIE_UC_TX]);
-}
-
-static void
-usie_uc_rx_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct ucom_softc *ucom = usbd_xfer_softc(xfer);
-       struct usie_softc *sc = ucom->sc_parent;
-       struct usb_page_cache *pc;
-       uint32_t actlen;
-
-       usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               pc = usbd_xfer_get_frame(xfer, 0);
-
-               /* handle CnS response */
-               if (ucom == sc->sc_ucom && actlen >= USIE_HIPCNS_MIN) {
-
-                       DPRINTF("transferred=%u\n", actlen);
-
-                       /* check if it is really CnS reply */
-                       usbd_copy_out(pc, 0, sc->sc_resp_temp, 1);
-
-                       if (sc->sc_resp_temp[0] == USIE_HIP_FRM_CHR) {
-
-                               /* verify actlen */
-                               if (actlen > USIE_BUFSIZE)
-                                       actlen = USIE_BUFSIZE;
-
-                               /* get complete message */
-                               usbd_copy_out(pc, 0, sc->sc_resp_temp, actlen);
-                               usie_hip_rsp(sc, sc->sc_resp_temp, actlen);
-
-                               /* need to fall though */
-                               goto tr_setup;
-                       }
-                       /* else call ucom_put_data() */
-               }
-               /* standard ucom transfer */
-               ucom_put_data(ucom, pc, 0, actlen);
-
-               /* fall though */
-       case USB_ST_SETUP:
-tr_setup:
-               usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
-               usbd_transfer_submit(xfer);
-               break;
-
-       default:                        /* Error */
-               if (error != USB_ERR_CANCELLED) {
-                       usbd_xfer_set_stall(xfer);
-                       goto tr_setup;
-               }
-               break;
-       }
-}
-
-static void
-usie_uc_tx_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct ucom_softc *ucom = usbd_xfer_softc(xfer);
-       struct usb_page_cache *pc;
-       uint32_t actlen;
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-       case USB_ST_SETUP:
-tr_setup:
-               pc = usbd_xfer_get_frame(xfer, 0);
-
-               /* handle CnS request */
-               struct mbuf *m = usbd_xfer_get_priv(xfer);
-
-               if (m != NULL) {
-                       usbd_m_copy_in(pc, 0, m, 0, m->m_pkthdr.len);
-                       usbd_xfer_set_frame_len(xfer, 0, m->m_pkthdr.len);
-                       usbd_xfer_set_priv(xfer, NULL);
-                       usbd_transfer_submit(xfer);
-                       m_freem(m);
-                       break;
-               }
-               /* standard ucom transfer */
-               if (ucom_get_data(ucom, pc, 0, USIE_BUFSIZE, &actlen)) {
-                       usbd_xfer_set_frame_len(xfer, 0, actlen);
-                       usbd_transfer_submit(xfer);
-               }
-               break;
-
-       default:                        /* Error */
-               if (error != USB_ERR_CANCELLED) {
-                       usbd_xfer_set_stall(xfer);
-                       goto tr_setup;
-               }
-               break;
-       }
-}
-
-static void
-usie_uc_status_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct usb_page_cache *pc;
-       struct {
-               struct usb_device_request req;
-               uint16_t param;
-       }      st;
-       uint32_t actlen;
-       uint16_t param;
-
-       usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               DPRINTFN(4, "info received, actlen=%u\n", actlen);
-
-               if (actlen < sizeof(st)) {
-                       DPRINTF("data too short actlen=%u\n", actlen);
-                       goto tr_setup;
-               }
-               pc = usbd_xfer_get_frame(xfer, 0);
-               usbd_copy_out(pc, 0, &st, sizeof(st));
-
-               if (st.req.bmRequestType == 0xa1 && st.req.bRequest == 0x20) {
-                       struct ucom_softc *ucom = usbd_xfer_softc(xfer);
-                       struct usie_softc *sc = ucom->sc_parent;
-
-                       param = le16toh(st.param);
-                       DPRINTF("param=%x\n", param);
-                       sc->sc_msr = sc->sc_lsr = 0;
-                       sc->sc_msr |= (param & USIE_DCD) ? SER_DCD : 0;
-                       sc->sc_msr |= (param & USIE_DSR) ? SER_DSR : 0;
-                       sc->sc_msr |= (param & USIE_RI) ? SER_RI : 0;
-                       sc->sc_msr |= (param & USIE_CTS) ? 0 : SER_CTS;
-                       sc->sc_msr |= (param & USIE_RTS) ? SER_RTS : 0;
-                       sc->sc_msr |= (param & USIE_DTR) ? SER_DTR : 0;
-               }
-               /* fall though */
-       case USB_ST_SETUP:
-tr_setup:
-               usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
-               usbd_transfer_submit(xfer);
-               break;
-
-       default:                        /* Error */
-               DPRINTF("USB transfer error, %s\n",
-                   usbd_errstr(error));
-
-               if (error != USB_ERR_CANCELLED) {
-                       usbd_xfer_set_stall(xfer);
-                       goto tr_setup;
-               }
-               break;
-       }
-}
-
-static void
-usie_if_rx_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct usie_softc *sc = usbd_xfer_softc(xfer);
-       struct ifnet *ifp = sc->sc_ifp;
-       struct mbuf *m0;
-       struct mbuf *m = NULL;
-       struct usie_desc *rxd;
-       uint32_t actlen;
-       uint16_t err;
-       uint16_t pkt;
-       uint16_t ipl;
-       uint16_t len;
-       uint16_t diff;
-       uint8_t pad;
-       uint8_t ipv;
-
-       usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               DPRINTFN(15, "rx done, actlen=%u\n", actlen);
-
-               if (actlen < sizeof(struct usie_hip)) {
-                       DPRINTF("data too short %u\n", actlen);
-                       goto tr_setup;
-               }
-               m = sc->sc_rxm;
-               sc->sc_rxm = NULL;
-
-               /* fall though */
-       case USB_ST_SETUP:
-tr_setup:
-
-               if (sc->sc_rxm == NULL) {
-                       sc->sc_rxm = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR,
-                           MJUMPAGESIZE /* could be bigger than MCLBYTES */ );
-               }
-               if (sc->sc_rxm == NULL) {
-                       DPRINTF("could not allocate Rx mbuf\n");
-                       ifp->if_ierrors++;
-                       usbd_xfer_set_stall(xfer);
-                       usbd_xfer_set_frames(xfer, 0);
-               } else {
-                       /*
-                        * Directly loading a mbuf cluster into DMA to
-                        * save some data copying. This works because
-                        * there is only one cluster.
-                        */
-                       usbd_xfer_set_frame_data(xfer, 0,
-                           mtod(sc->sc_rxm, caddr_t), MIN(MJUMPAGESIZE, USIE_RXSZ_MAX));
-                       usbd_xfer_set_frames(xfer, 1);
-               }
-               usbd_transfer_submit(xfer);
-               break;
-
-       default:                        /* Error */
-               DPRINTF("USB transfer error, %s\n", usbd_errstr(error));
-
-               if (error != USB_ERR_CANCELLED) {
-                       /* try to clear stall first */
-                       usbd_xfer_set_stall(xfer);
-                       ifp->if_ierrors++;
-                       goto tr_setup;
-               }
-               if (sc->sc_rxm != NULL) {
-                       m_freem(sc->sc_rxm);
-                       sc->sc_rxm = NULL;
-               }
-               break;
-       }
-
-       if (m == NULL)
-               return;
-
-       mtx_unlock(&sc->sc_mtx);
-
-       m->m_pkthdr.len = m->m_len = actlen;
-
-       err = pkt = 0;
-
-       /* HW can aggregate multiple frames in a single USB xfer */
-       for (;;) {
-               rxd = mtod(m, struct usie_desc *);
-
-               len = be16toh(rxd->hip.len) & USIE_HIP_IP_LEN_MASK;
-               pad = (rxd->hip.id & USIE_HIP_PAD) ? 1 : 0;
-               ipl = (len - pad - ETHER_HDR_LEN);
-               if (ipl >= len) {
-                       DPRINTF("Corrupt frame\n");
-                       m_freem(m);
-                       break;
-               }
-               diff = sizeof(struct usie_desc) + ipl + pad;
-
-               if (((rxd->hip.id & USIE_HIP_MASK) != USIE_HIP_IP) ||
-                   (be16toh(rxd->desc_type) & USIE_TYPE_MASK) != USIE_IP_RX) {
-                       DPRINTF("received wrong type of packet\n");
-                       m->m_data += diff;
-                       m->m_pkthdr.len = (m->m_len -= diff);
-                       err++;
-                       if (m->m_pkthdr.len > 0)
-                               continue;
-                       m_freem(m);
-                       break;
-               }
-               switch (be16toh(rxd->ethhdr.ether_type)) {
-               case ETHERTYPE_IP:
-                       ipv = NETISR_IP;
-                       break;
-#ifdef INET6
-               case ETHERTYPE_IPV6:
-                       ipv = NETISR_IPV6;
-                       break;
-#endif
-               default:
-                       DPRINTF("unsupported ether type\n");
-                       err++;
-                       break;
-               }
-
-               /* the last packet */
-               if (m->m_pkthdr.len <= diff) {
-                       m->m_data += (sizeof(struct usie_desc) + pad);
-                       m->m_pkthdr.len = m->m_len = ipl;
-                       m->m_pkthdr.rcvif = ifp;
-                       BPF_MTAP(sc->sc_ifp, m);
-                       netisr_dispatch(ipv, m);
-                       break;
-               }
-               /* copy aggregated frames to another mbuf */
-               m0 = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
-               if (__predict_false(m0 == NULL)) {
-                       DPRINTF("could not allocate mbuf\n");
-                       err++;
-                       m_freem(m);
-                       break;
-               }
-               m_copydata(m, sizeof(struct usie_desc) + pad, ipl, mtod(m0, caddr_t));
-               m0->m_pkthdr.rcvif = ifp;
-               m0->m_pkthdr.len = m0->m_len = ipl;
-
-               BPF_MTAP(sc->sc_ifp, m0);
-               netisr_dispatch(ipv, m0);
-
-               m->m_data += diff;
-               m->m_pkthdr.len = (m->m_len -= diff);
-       }
-
-       mtx_lock(&sc->sc_mtx);
-
-       ifp->if_ierrors += err;
-       ifp->if_ipackets += pkt;
-}
-
-static void
-usie_if_tx_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct usie_softc *sc = usbd_xfer_softc(xfer);
-       struct usb_page_cache *pc;
-       struct ifnet *ifp = sc->sc_ifp;
-       struct mbuf *m;
-       uint16_t size;
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               DPRINTFN(11, "transfer complete\n");
-               ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-               ifp->if_opackets++;
-
-               /* fall though */
-       case USB_ST_SETUP:
-tr_setup:
-
-               if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
-                       break;
-
-               IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
-               if (m == NULL)
-                       break;
-
-               if (m->m_pkthdr.len > (MCLBYTES - ETHER_HDR_LEN +
-                   ETHER_CRC_LEN - sizeof(sc->sc_txd))) {
-                       DPRINTF("packet len is too big: %d\n",
-                           m->m_pkthdr.len);
-                       break;
-               }
-               pc = usbd_xfer_get_frame(xfer, 0);
-
-               sc->sc_txd.hip.len = htobe16(m->m_pkthdr.len +
-                   ETHER_HDR_LEN + ETHER_CRC_LEN);
-               size = sizeof(sc->sc_txd);
-
-               usbd_copy_in(pc, 0, &sc->sc_txd, size);
-               usbd_m_copy_in(pc, size, m, 0, m->m_pkthdr.len);
-               usbd_xfer_set_frame_len(xfer, 0, m->m_pkthdr.len +
-                   size + ETHER_CRC_LEN);
-
-               BPF_MTAP(ifp, m);
-
-               m_freem(m);
-
-               usbd_transfer_submit(xfer);
-               break;
-
-       default:                        /* Error */
-               DPRINTF("USB transfer error, %s\n",
-                   usbd_errstr(error));
-               ifp->if_oerrors++;
-
-               if (error != USB_ERR_CANCELLED) {
-                       usbd_xfer_set_stall(xfer);
-                       ifp->if_ierrors++;
-                       goto tr_setup;
-               }
-               break;
-       }
-}
-
-static void
-usie_if_status_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct usie_softc *sc = usbd_xfer_softc(xfer);
-       struct usb_page_cache *pc;
-       struct usb_cdc_notification cdc;
-       uint32_t actlen;
-
-       usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               DPRINTFN(4, "info received, actlen=%d\n", actlen);
-
-               /* usb_cdc_notification - .data[16] */
-               if (actlen < (sizeof(cdc) - 16)) {
-                       DPRINTF("data too short %d\n", actlen);
-                       goto tr_setup;
-               }
-               pc = usbd_xfer_get_frame(xfer, 0);
-               usbd_copy_out(pc, 0, &cdc, (sizeof(cdc) - 16));
-
-               DPRINTFN(4, "bNotification=%x\n", cdc.bNotification);
-
-               if (cdc.bNotification & UCDC_N_RESPONSE_AVAILABLE) {
-                       taskqueue_enqueue(taskqueue_thread,
-                           &sc->sc_if_status_task);
-               }
-               /* fall though */
-       case USB_ST_SETUP:
-tr_setup:
-               usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
-               usbd_transfer_submit(xfer);
-               break;
-
-       default:                        /* Error */
-               DPRINTF("USB transfer error, %s\n",
-                   usbd_errstr(error));
-
-               if (error != USB_ERR_CANCELLED) {
-                       usbd_xfer_set_stall(xfer);
-                       goto tr_setup;
-               }
-               break;
-       }
-}
-
-static void
-usie_if_sync_to(void *arg)
-{
-       struct usie_softc *sc = arg;
-
-       taskqueue_enqueue(taskqueue_thread, &sc->sc_if_sync_task);
-}
-
-static void
-usie_if_sync_cb(void *arg, int pending)
-{
-       struct usie_softc *sc = arg;
-
-       mtx_lock(&sc->sc_mtx);
-
-       /* call twice */
-       usie_if_cmd(sc, USIE_HIP_SYNC2M);
-       usie_if_cmd(sc, USIE_HIP_SYNC2M);
-
-       usb_callout_reset(&sc->sc_if_sync_ch, 2 * hz, usie_if_sync_to, sc);
-
-       mtx_unlock(&sc->sc_mtx);
-}
-
-static void
-usie_if_status_cb(void *arg, int pending)
-{
-       struct usie_softc *sc = arg;
-       struct ifnet *ifp = sc->sc_ifp;
-       struct usb_device_request req;
-       struct usie_hip *hip;
-       struct usie_lsi *lsi;
-       uint16_t actlen;
-       uint8_t ntries;
-       uint8_t pad;
-
-       mtx_lock(&sc->sc_mtx);
-
-       req.bmRequestType = UT_READ_CLASS_INTERFACE;
-       req.bRequest = UCDC_GET_ENCAPSULATED_RESPONSE;
-       USETW(req.wValue, 0);
-       USETW(req.wIndex, sc->sc_if_ifnum);
-       USETW(req.wLength, sizeof(sc->sc_status_temp));
-
-       for (ntries = 0; ntries != 10; ntries++) {
-               int err;
-
-               err = usbd_do_request_flags(sc->sc_udev,
-                   &sc->sc_mtx, &req, sc->sc_status_temp, USB_SHORT_XFER_OK,
-                   &actlen, USB_DEFAULT_TIMEOUT);
-
-               if (err == 0)
-                       break;
-
-               DPRINTF("Control request failed: %s %d/10\n",
-                   usbd_errstr(err), ntries);
-
-               usb_pause_mtx(&sc->sc_mtx, USB_MS_TO_TICKS(10));
-       }
-
-       if (ntries == 10) {
-               mtx_unlock(&sc->sc_mtx);
-               DPRINTF("Timeout\n");
-               return;
-       }
-
-       hip = (struct usie_hip *)sc->sc_status_temp;
-
-       pad = (hip->id & USIE_HIP_PAD) ? 1 : 0;
-
-       DPRINTF("hip.id=%x hip.len=%d actlen=%u pad=%d\n",
-           hip->id, be16toh(hip->len), actlen, pad);
-
-       switch (hip->id & USIE_HIP_MASK) {
-       case USIE_HIP_SYNC2H:
-               usie_if_cmd(sc, USIE_HIP_SYNC2M);
-               break;
-       case USIE_HIP_RESTR:
-               usb_callout_stop(&sc->sc_if_sync_ch);
-               break;
-       case USIE_HIP_UMTS:
-               lsi = (struct usie_lsi *)(
-                   sc->sc_status_temp + sizeof(struct usie_hip) + pad);
-
-               DPRINTF("lsi.proto=%x lsi.len=%d\n", lsi->proto,
-                   be16toh(lsi->len));
-
-               if (lsi->proto != USIE_LSI_UMTS)
-                       break;
-
-               if (lsi->area == USIE_LSI_AREA_NO ||
-                   lsi->area == USIE_LSI_AREA_NODATA) {
-                       device_printf(sc->sc_dev, "no service available\n");
-                       break;
-               }
-               if (lsi->state == USIE_LSI_STATE_IDLE) {
-                       DPRINTF("lsi.state=%x\n", lsi->state);
-                       break;
-               }
-               DPRINTF("ctx=%x\n", hip->param);
-               sc->sc_txd.hip.param = hip->param;
-
-               sc->sc_net.addr_len = lsi->pdp_addr_len;
-               memcpy(&sc->sc_net.dns1_addr, &lsi->dns1_addr, 16);
-               memcpy(&sc->sc_net.dns2_addr, &lsi->dns2_addr, 16);
-               memcpy(sc->sc_net.pdp_addr, lsi->pdp_addr, 16);
-               memcpy(sc->sc_net.gw_addr, lsi->gw_addr, 16);
-               ifp->if_flags |= IFF_UP;
-               ifp->if_drv_flags |= IFF_DRV_RUNNING;
-
-               device_printf(sc->sc_dev, "IP Addr=%d.%d.%d.%d\n",
-                   *lsi->pdp_addr, *(lsi->pdp_addr + 1),
-                   *(lsi->pdp_addr + 2), *(lsi->pdp_addr + 3));
-               device_printf(sc->sc_dev, "Gateway Addr=%d.%d.%d.%d\n",
-                   *lsi->gw_addr, *(lsi->gw_addr + 1),
-                   *(lsi->gw_addr + 2), *(lsi->gw_addr + 3));
-               device_printf(sc->sc_dev, "Prim NS Addr=%d.%d.%d.%d\n",
-                   *lsi->dns1_addr, *(lsi->dns1_addr + 1),
-                   *(lsi->dns1_addr + 2), *(lsi->dns1_addr + 3));
-               device_printf(sc->sc_dev, "Scnd NS Addr=%d.%d.%d.%d\n",
-                   *lsi->dns2_addr, *(lsi->dns2_addr + 1),
-                   *(lsi->dns2_addr + 2), *(lsi->dns2_addr + 3));
-
-               usie_cns_req(sc, USIE_CNS_ID_RSSI, USIE_CNS_OB_RSSI);
-               break;
-
-       case USIE_HIP_RCGI:
-               /* ignore, workaround for sloppy windows */
-               break;
-       default:
-               DPRINTF("undefined msgid: %x\n", hip->id);
-               break;
-       }
-
-       mtx_unlock(&sc->sc_mtx);
-}
-
-static void
-usie_if_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
-{
-       struct usie_softc *sc = ifp->if_softc;
-
-       ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq);
-
-       if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-               DPRINTF("Not running\n");
-               return;
-       }
-       mtx_lock(&sc->sc_mtx);
-       usbd_transfer_start(sc->sc_if_xfer[USIE_IF_TX]);
-       mtx_unlock(&sc->sc_mtx);
-
-       DPRINTFN(3, "interface started\n");
-}
-
-static int
-usie_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
-    struct route *ro)
-{
-       int err;
-
-       DPRINTF("proto=%x\n", dst->sa_family);
-
-       switch (dst->sa_family) {
-#ifdef INET6
-       case AF_INET6;
-       /* fall though */
-#endif
-       case AF_INET:
-               break;
-
-               /* silently drop dhclient packets */
-       case AF_UNSPEC:
-               m_freem(m);
-               return (0);
-
-               /* drop other packet types */
-       default:
-               m_freem(m);
-               return (EAFNOSUPPORT);
-       }
-
-       err = (ifp->if_transmit)(ifp, m);
-       if (err) {
-               ifp->if_oerrors++;
-               return (ENOBUFS);
-       }
-       ifp->if_opackets++;
-
-       return (0);
-}
-
-static void
-usie_if_init(void *arg)
-{
-       struct usie_softc *sc = arg;
-       struct ifnet *ifp = sc->sc_ifp;
-       uint8_t i;
-
-       mtx_lock(&sc->sc_mtx);
-
-       /* write tx descriptor */
-       sc->sc_txd.hip.id = USIE_HIP_CTX;
-       sc->sc_txd.hip.param = 0;       /* init value */
-       sc->sc_txd.desc_type = htobe16(USIE_IP_TX);
-
-       for (i = 0; i != USIE_IF_N_XFER; i++)
-               usbd_xfer_set_stall(sc->sc_if_xfer[i]);
-
-       usbd_transfer_start(sc->sc_uc_xfer[USIE_HIP_IF][USIE_UC_RX]);
-       usbd_transfer_start(sc->sc_if_xfer[USIE_IF_STATUS]);
-       usbd_transfer_start(sc->sc_if_xfer[USIE_IF_RX]);
-
-       /* if not running, initiate the modem */
-       if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
-               usie_cns_req(sc, USIE_CNS_ID_INIT, USIE_CNS_OB_LINK_UPDATE);
-
-       mtx_unlock(&sc->sc_mtx);
-
-       DPRINTF("ifnet initialized\n");
-}
-
-static void
-usie_if_stop(struct usie_softc *sc)
-{
-       usb_callout_drain(&sc->sc_if_sync_ch);
-
-       mtx_lock(&sc->sc_mtx);
-
-       /* usie_cns_req() clears IFF_* flags */
-       usie_cns_req(sc, USIE_CNS_ID_STOP, USIE_CNS_OB_LINK_UPDATE);
-
-       usbd_transfer_stop(sc->sc_if_xfer[USIE_IF_TX]);
-       usbd_transfer_stop(sc->sc_if_xfer[USIE_IF_RX]);
-       usbd_transfer_stop(sc->sc_if_xfer[USIE_IF_STATUS]);
-
-       /* shutdown device */
-       usie_if_cmd(sc, USIE_HIP_DOWN);
-
-       mtx_unlock(&sc->sc_mtx);
-}
-
-static int
-usie_if_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
-       struct usie_softc *sc = ifp->if_softc;
-       struct ieee80211req *ireq;
-       struct ieee80211req_sta_info si;
-       struct ifmediareq *ifmr;
-
-       switch (cmd) {
-       case SIOCSIFFLAGS:
-               if (ifp->if_flags & IFF_UP) {
-                       if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
-                               usie_if_init(sc);
-               } else {
-                       if (ifp->if_drv_flags & IFF_DRV_RUNNING)
-                               usie_if_stop(sc);
-               }
-               break;
-
-       case SIOCSIFCAP:
-               if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-                       device_printf(sc->sc_dev,
-                           "Connect to the network first.\n");
-                       break;
-               }
-               mtx_lock(&sc->sc_mtx);
-               usie_cns_req(sc, USIE_CNS_ID_RSSI, USIE_CNS_OB_RSSI);
-               mtx_unlock(&sc->sc_mtx);
-               break;
-
-       case SIOCG80211:
-               ireq = (struct ieee80211req *)data;
-
-               if (ireq->i_type != IEEE80211_IOC_STA_INFO)
-                       break;
-
-               memset(&si, 0, sizeof(si));
-               si.isi_len = sizeof(si);
-               /*
-                * ifconfig expects RSSI in 0.5dBm units
-                * relative to the noise floor.
-                */
-               si.isi_rssi = 2 * sc->sc_rssi;
-               if (copyout(&si, (uint8_t *)ireq->i_data + 8,
-                   sizeof(struct ieee80211req_sta_info)))
-                       DPRINTF("copyout failed\n");
-               DPRINTF("80211\n");
-               break;
-
-       case SIOCGIFMEDIA:              /* to fool ifconfig */
-               ifmr = (struct ifmediareq *)data;
-               ifmr->ifm_count = 1;
-               DPRINTF("media\n");
-               break;
-
-       case SIOCSIFADDR:
-       case SIOCSIFDSTADDR:
-               break;
-
-       default:
-               return (EINVAL);
-       }
-       return (0);
-}
-
-static int
-usie_do_request(struct usie_softc *sc, struct usb_device_request *req,
-    void *data)
-{
-       int err = 0;
-       int ntries;
-
-       mtx_assert(&sc->sc_mtx, MA_OWNED);
-
-       for (ntries = 0; ntries != 10; ntries++) {
-               err = usbd_do_request(sc->sc_udev,
-                   &sc->sc_mtx, req, data);
-               if (err == 0)
-                       break;
-
-               DPRINTF("Control request failed: %s %d/10\n",
-                   usbd_errstr(err), ntries);
-
-               usb_pause_mtx(&sc->sc_mtx, USB_MS_TO_TICKS(10));
-       }
-       return (err);
-}
-
-static int
-usie_if_cmd(struct usie_softc *sc, uint8_t cmd)
-{
-       struct usb_device_request req;
-       struct usie_hip msg;
-
-       msg.len = 0;
-       msg.id = cmd;
-       msg.param = 0;
-
-       req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
-       req.bRequest = UCDC_SEND_ENCAPSULATED_COMMAND;
-       USETW(req.wValue, 0);
-       USETW(req.wIndex, sc->sc_if_ifnum);
-       USETW(req.wLength, sizeof(msg));
-
-       DPRINTF("cmd=%x\n", cmd);
-
-       return (usie_do_request(sc, &req, &msg));
-}
-
-static void
-usie_cns_req(struct usie_softc *sc, uint32_t id, uint16_t obj)
-{
-       struct ifnet *ifp = sc->sc_ifp;
-       struct mbuf *m;
-       struct usb_xfer *xfer;
-       struct usie_hip *hip;
-       struct usie_cns *cns;
-       uint8_t *param;
-       uint8_t *tmp;
-       uint8_t cns_len;
-
-       m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
-       if (__predict_false(m == NULL)) {
-               DPRINTF("could not allocate mbuf\n");
-               ifp->if_ierrors++;
-               return;
-       }
-       /* to align usie_hip{} on 32 bit */
-       m->m_data += 3;
-       param = mtod(m, uint8_t *);
-       *param++ = USIE_HIP_FRM_CHR;
-       hip = (struct usie_hip *)param;
-       cns = (struct usie_cns *)(hip + 1);
-
-       tmp = param + USIE_HIPCNS_MIN - 2;
-
-       switch (obj) {
-       case USIE_CNS_OB_LINK_UPDATE:
-               cns_len = 2;
-               cns->op = USIE_CNS_OP_SET;
-               *tmp++ = 1;             /* profile ID, always use 1 for now */
-               *tmp++ = id == USIE_CNS_ID_INIT ? 1 : 0;
-               break;
-
-       case USIE_CNS_OB_PROF_WRITE:
-               cns_len = 245;
-               cns->op = USIE_CNS_OP_SET;
-               *tmp++ = 1;             /* profile ID, always use 1 for now */
-               *tmp++ = 2;
-               memcpy(tmp, &sc->sc_net, 34);
-               memset(tmp + 35, 0, 245 - 36);
-               tmp += 243;
-               break;
-
-       case USIE_CNS_OB_RSSI:
-               cns_len = 0;
-               cns->op = USIE_CNS_OP_REQ;
-               break;
-
-       default:
-               DPRINTF("unsupported CnS object type\n");
-               return;
-       }
-       *tmp = USIE_HIP_FRM_CHR;
-
-       hip->len = htobe16(sizeof(struct usie_cns) + cns_len);
-       hip->id = USIE_HIP_CNS2M;
-       hip->param = 0;                 /* none for CnS */
-
-       cns->obj = htobe16(obj);
-       cns->id = htobe32(id);
-       cns->len = cns_len;
-       cns->rsv0 = cns->rsv1 = 0;      /* always '0' */
-
-       param = (uint8_t *)(cns + 1);
-
-       DPRINTF("param: %16D\n", param, ":");
-
-       m->m_pkthdr.len = m->m_len = USIE_HIPCNS_MIN + cns_len + 2;
-
-       xfer = sc->sc_uc_xfer[USIE_HIP_IF][USIE_UC_TX];
-
-       if (usbd_xfer_get_priv(xfer) == NULL) {
-               usbd_xfer_set_priv(xfer, m);
-               usbd_transfer_start(xfer);
-       } else {
-               DPRINTF("Dropped CNS event\n");
-               m_freem(m);
-       }
-}
-
-static void
-usie_cns_rsp(struct usie_softc *sc, struct usie_cns *cns)
-{
-       struct ifnet *ifp = sc->sc_ifp;
-
-       DPRINTF("received CnS\n");
-
-       switch (be16toh(cns->obj)) {
-       case USIE_CNS_OB_LINK_UPDATE:
-               if (be32toh(cns->id) & USIE_CNS_ID_INIT)
-                       usie_if_sync_to(sc);
-               else if (be32toh(cns->id) & USIE_CNS_ID_STOP) {
-                       ifp->if_flags &= ~IFF_UP;
-                       ifp->if_drv_flags &=
-                           ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-               } else
-                       DPRINTF("undefined link update\n");
-               break;
-
-       case USIE_CNS_OB_RSSI:
-               sc->sc_rssi = be16toh(*(int16_t *)(cns + 1));
-               if (sc->sc_rssi <= 0)
-                       device_printf(sc->sc_dev, "No signal\n");
-               else {
-                       device_printf(sc->sc_dev, "RSSI=%ddBm\n",
-                           sc->sc_rssi - 110);
-               }
-               break;
-
-       case USIE_CNS_OB_PROF_WRITE:
-               break;
-
-       case USIE_CNS_OB_PDP_READ:
-               break;
-
-       default:
-               DPRINTF("undefined CnS\n");
-               break;
-       }
-}
-
-static void
-usie_hip_rsp(struct usie_softc *sc, uint8_t *rsp, uint32_t len)
-{
-       struct usie_hip *hip;
-       struct usie_cns *cns;
-       uint32_t i;
-       uint32_t j;
-       uint32_t off;
-       uint8_t tmp[USIE_HIPCNS_MAX] __aligned(4);
-
-       for (off = 0; (off + USIE_HIPCNS_MIN) <= len; off++) {
-
-               uint8_t pad;
-
-               while ((off < len) && (rsp[off] == USIE_HIP_FRM_CHR))
-                       off++;
-
-               /* Unstuff the bytes */
-               for (i = j = 0; ((i + off) < len) &&
-                   (j < USIE_HIPCNS_MAX); i++) {
-
-                       if (rsp[i + off] == USIE_HIP_FRM_CHR)
-                               break;
-
-                       if (rsp[i + off] == USIE_HIP_ESC_CHR) {
-                               if ((i + off + 1) >= len)
-                                       break;
-                               tmp[j++] = rsp[i++ + off + 1] ^ 0x20;
-                       } else {
-                               tmp[j++] = rsp[i + off];
-                       }
-               }
-
-               off += i;
-
-               DPRINTF("frame len=%d\n", j);
-
-               if (j < sizeof(struct usie_hip)) {
-                       DPRINTF("too little data\n");
-                       break;
-               }
-               /*
-                * Make sure we are not reading the stack if something
-                * is wrong.
-                */
-               memset(tmp + j, 0, sizeof(tmp) - j);
-
-               hip = (struct usie_hip *)tmp;
-
-               DPRINTF("hip: len=%d msgID=%02x, param=%02x\n",
-                   be16toh(hip->len), hip->id, hip->param);
-
-               pad = (hip->id & USIE_HIP_PAD) ? 1 : 0;
-
-               if ((hip->id & USIE_HIP_MASK) == USIE_HIP_CNS2H) {
-                       cns = (struct usie_cns *)(((uint8_t *)(hip + 1)) + pad);
-
-                       if (j < (sizeof(struct usie_cns) +
-                           sizeof(struct usie_hip) + pad)) {
-                               DPRINTF("too little data\n");
-                               break;
-                       }
-                       DPRINTF("cns: obj=%04x, op=%02x, rsv0=%02x, "
-                           "app=%08x, rsv1=%02x, len=%d\n",
-                           be16toh(cns->obj), cns->op, cns->rsv0,
-                           be32toh(cns->id), cns->rsv1, cns->len);
-
-                       if (cns->op & USIE_CNS_OP_ERR)
-                               DPRINTF("CnS error response\n");
-                       else
-                               usie_cns_rsp(sc, cns);
-
-                       i = sizeof(struct usie_hip) + pad + sizeof(struct usie_cns);
-                       j = cns->len;
-               } else {
-                       i = sizeof(struct usie_hip) + pad;
-                       j = be16toh(hip->len);
-               }
-#ifdef USB_DEBUG
-               if (usie_debug == 0)
-                       continue;
-
-               while (i < USIE_HIPCNS_MAX && j > 0) {
-                       DPRINTF("param[0x%02x] = 0x%02x\n", i, tmp[i]);
-                       i++;
-                       j--;
-               }
-#endif
-       }
-}
-
-static int
-usie_driver_loaded(struct module *mod, int what, void *arg)
-{
-       switch (what) {
-       case MOD_LOAD:
-               /* register autoinstall handler */
-               usie_etag = EVENTHANDLER_REGISTER(usb_dev_configured,
-                   usie_autoinst, NULL, EVENTHANDLER_PRI_ANY);
-               break;
-       case MOD_UNLOAD:
-               EVENTHANDLER_DEREGISTER(usb_dev_configured, usie_etag);
-               break;
-       default:
-               return (EOPNOTSUPP);
-       }
-       return (0);
-}
-
diff --git a/sys/bus/u4b/net/if_usievar.h b/sys/bus/u4b/net/if_usievar.h
deleted file mode 100644 (file)
index 9ba0dc8..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2011 Anybots Inc
- * written by Akinori Furukoshi <moonlightakkiy@yahoo.ca>
- *  - ucom part is based on u3g.c
- *
- * 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 AUTHOR 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 AUTHOR 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.
- */
-
-#ifndef _IF_USEVAR_H_
-#define        _IF_USEVAR_H_
-
-#define        USIE_DCD                0x0001
-#define        USIE_DSR                0x0002
-#define        USIE_DTR                0x0004
-#define        USIE_RI                 0x0008
-#define        USIE_CTS                0x0100
-#define        USIE_RTS                0x0200
-
-#define        USIE_HIP_FRM_CHR        0x7e
-#define        USIE_HIP_ESC_CHR        0x7d
-#define        USIE_HIP_IF             0
-
-#define        USIE_HIPCNS_MIN         16      /* HIP + CnS + 2 framing char */
-#define        USIE_HIPCNS_MAX         261     /* HIP + max CnS 255 + 2 framing char */
-
-#define        USIE_CNFG_INDEX         0
-#define        USIE_IFACE_INDEX        0
-#define        USIE_IFACE_MAX          12
-#define        USIE_BUFSIZE            2048
-#define        USIE_MTU_MAX            1500
-#define        USIE_RXSZ_MAX           4096
-
-/* USB control pipe request */
-#define        USIE_POWER              0x00
-#define        USIE_FW_ATTR            0x06
-#define        USIE_NMEA               0x07
-#define        USIE_LINK_STATE         0x22
-
-/* firmware attr flags */
-#define        USIE_PM_AUTO            (1 << 1)
-#define        USIE_FW_DHCP            (1 << 3)        /* DHCP capable */
-
-/* line state flags */
-#define        USIE_LS_DTR             (1 << 0)
-#define        USIE_LS_RTS             (1 << 1)
-
-/* Host Interface Porotocol Header */
-struct usie_hip {
-       uint16_t len;
-#define        USIE_HIP_LEN_MASK       0x3fff
-#define        USIE_HIP_IP_LEN_MASK    0x07ff
-
-       uint8_t id;
-#define        USIE_HIP_PAD            (1 << 7)
-#define        USIE_HIP_MASK           0x7f
-#define        USIE_HIP_SYNC2M         0x20    /* host -> modem */
-#define        USIE_HIP_DOWN           0x26
-#define        USIE_HIP_CNS2M          0x2b    /* h -> m */
-#define        USIE_HIP_CTX            0x3f
-#define        USIE_HIP_SYNC2H         0x60    /* h <- m */
-#define        USIE_HIP_RESTR          0x62
-#define        USIE_HIP_RCGI           0x64
-#define        USIE_HIP_CNS2H          0x6b    /* h <- m */
-#define        USIE_HIP_UMTS           0x78
-#define        USIE_HIP_IP             0x7f
-
-       uint8_t param;
-} __packed __aligned(4);
-
-/* Control and Status Header */
-struct usie_cns {
-       uint16_t obj;                   /* object type */
-#define        USIE_CNS_OB_RSSI        0x1001  /* read RSSI */
-#define        USIE_CNS_OB_HW_DISABLE  0x1011  /* disable h/w */
-#define        USIE_CNS_OB_PW_SW       0x1071  /* power on/off */
-#define        USIE_CNS_OB_PROF_WRITE  0x7003  /* write profile */
-#define        USIE_CNS_OB_LINK_UPDATE 0x7004  /* dis/connect */
-#define        USIE_CNS_OB_PDP_READ    0x7006  /* read out IP addr */
-
-       uint8_t op;                     /* operation type */
-#define        USIE_CNS_OP_ERR         (1 << 7)/* | == error */
-#define        USIE_CNS_OP_REQ         0x01    /* host -> modem */
-#define        USIE_CNS_OP_RSP         0x02    /* h <- m */
-#define        USIE_CNS_OP_SET         0x03    /* h -> m */
-#define        USIE_CNS_OP_ACK         0x04    /* h <- m */
-#define        USIE_CNS_OP_NOTIF_ON    0x05    /* h -> m */
-#define        USIE_CNS_OP_RSP_ON      0x06    /* h <- m */
-#define        USIE_CNS_OP_NOTIF       0x07    /* h <- m */
-#define        USIE_CNS_OP_NOTIF_OFF   0x08    /* h -> m */
-#define        USIE_CNS_OP_RSP_OFF     0x09    /* h <- m */
-#define        USIE_CNS_OP_REQ_CHG     0x0a    /* h -> m */
-#define        USIE_CNS_OP_RSP_CHG     0x0b    /* h <- m */
-
-       uint8_t rsv0;                   /* reserved, always '0' */
-       uint32_t id;                    /* caller ID */
-/*
- * .id is to identify calling functions
- * h/w responses with the same .id used in request. Only '0' is reserved
- * for notification (asynchronous message generated by h/w without any
- * request). All other values are user defineable.
- */
-#define        USIE_CNS_ID_NOTIF       0x00000000      /* reserved */
-#define        USIE_CNS_ID_INIT        0x00000001
-#define        USIE_CNS_ID_STOP        0x00000002
-#define        USIE_CNS_ID_DNS         0x00000003
-#define        USIE_CNS_ID_RSSI        0x00000004
-
-       uint8_t rsv1;                   /* reserved, always '0' */
-       uint8_t len;                    /* length of param */
-} __packed;
-
-/*
- * CnS param attached to struct usie_cns
- * usie_cns.len is total size of this param
- * max 255
- */
-#define        USIE_CNS_PM_UP          0x01
-#define        USIE_CNS_PM_DOWN        0x00
-
-/* Link Sense Indication data structure */
-struct usie_lsi {
-       uint8_t proto;
-#define        USIE_LSI_UMTS           0x01
-
-       uint8_t pad0;
-       uint16_t len;
-       uint8_t area;
-#define        USIE_LSI_AREA_NO        0x00
-#define        USIE_LSI_AREA_NODATA    0x01
-
-       uint8_t pad1[41];
-       uint8_t state;
-#define        USIE_LSI_STATE_IDLE     0x00
-
-       uint8_t pad2[33];
-       uint8_t type;
-#define        USIE_LSI_IP4            0x00
-
-       uint8_t pdp_addr_len;           /* PDP addr */
-       uint8_t pdp_addr[16];
-       uint8_t pad3[23];
-       uint8_t dns1_addr_len;          /* DNS addr */
-       uint8_t dns1_addr[16];
-       uint8_t dns2_addr_len;
-       uint8_t dns2_addr[16];
-       uint8_t wins1_addr_len;         /* Wins addr */
-       uint8_t wins1_addr[16];
-       uint8_t wins2_addr_len;
-       uint8_t wins2_addr[16];
-       uint8_t pad4[4];
-       uint8_t gw_addr_len;            /* GW addr */
-       uint8_t gw_addr[16];
-       uint8_t rsv[8];
-} __packed;
-
-struct usie_net_info {
-       uint8_t addr_len;
-       uint8_t pdp_addr[16];
-       uint8_t dns1_addr[16];
-       uint8_t dns2_addr[16];
-       uint8_t gw_addr[16];
-} __packed;
-
-/* Tx/Rx IP packet descriptor */
-struct usie_desc {
-       struct usie_hip hip;
-       uint16_t desc_type;
-#define        USIE_TYPE_MASK  0x03ff
-#define        USIE_IP_TX      0x0002
-#define        USIE_IP_RX      0x0202
-
-       struct ether_header ethhdr;
-} __packed;
-
-enum {
-       USIE_UC_STATUS,
-       USIE_UC_RX,
-       USIE_UC_TX,
-       USIE_UC_N_XFER
-};
-
-enum {
-       USIE_IF_STATUS,
-       USIE_IF_RX,
-       USIE_IF_TX,
-       USIE_IF_N_XFER
-};
-
-struct usie_softc {
-       struct ucom_super_softc sc_super_ucom;
-
-#define        USIE_UCOM_MAX   6
-       struct ucom_softc sc_ucom[USIE_UCOM_MAX];
-       uint8_t sc_uc_ifnum[USIE_UCOM_MAX];
-
-       struct mtx sc_mtx;
-
-       struct task sc_if_status_task;
-       struct task sc_if_sync_task;
-       struct usb_callout sc_if_sync_ch;
-
-       struct usie_net_info sc_net;
-
-       struct usie_desc sc_txd;
-
-       struct usb_xfer *sc_uc_xfer[USIE_UCOM_MAX][USIE_UC_N_XFER];
-       struct usb_xfer *sc_if_xfer[USIE_IF_N_XFER];
-
-       struct ifnet *sc_ifp;
-       struct usb_device *sc_udev;
-       device_t sc_dev;
-
-       struct mbuf *sc_rxm;
-
-       uint16_t sc_if_ifnum;
-
-       int16_t sc_rssi;
-
-       uint8_t sc_msr;
-       uint8_t sc_lsr;
-       uint8_t sc_nucom;
-
-       uint8_t sc_resp_temp[USIE_BUFSIZE] __aligned(4);
-       uint8_t sc_status_temp[USIE_BUFSIZE] __aligned(4);
-};
-
-/* Some code assumptions */
-
-extern uint8_t usie_assert[((sizeof(struct usie_hip) +
-    sizeof(struct usie_lsi) + 1) <= USIE_BUFSIZE) ? 1 : -1];
-
-extern uint8_t ucdc_assert[(sizeof(struct usb_cdc_notification)
-     >= 16) ? 1 : -1];
-
-#endif                                 /* _IF_USEVAR_H_ */
diff --git a/sys/bus/u4b/net/uhso.c b/sys/bus/u4b/net/uhso.c
deleted file mode 100644 (file)
index 7057a86..0000000
+++ /dev/null
@@ -1,1910 +0,0 @@
-/*-
- * Copyright (c) 2010 Fredrik Lindberg <fli@shapeshifter.se>
- * All rights reserved.
- *
- * 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 AUTHOR ``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 AUTHOR 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.
- *
- */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/socket.h>
-#include <sys/tty.h>
-#include <sys/sysctl.h>
-#include <sys/condvar.h>
-#include <sys/sx.h>
-#include <sys/proc.h>
-#include <sys/conf.h>
-#include <sys/bus.h>
-#include <sys/systm.h>
-#include <sys/limits.h>
-
-#include <machine/bus.h>
-
-#include <net/if.h>
-#include <net/if_types.h>
-#include <net/netisr.h>
-#include <net/bpf.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usb_cdc.h>
-#include "usbdevs.h"
-#define USB_DEBUG_VAR uhso_debug
-#include <dev/usb/usb_debug.h>
-#include <dev/usb/usb_process.h>
-#include <dev/usb/usb_busdma.h>
-#include <dev/usb/usb_msctest.h>
-
-#include <dev/usb/serial/usb_serial.h>
-
-struct uhso_tty {
-       struct uhso_softc *ht_sc;
-       struct usb_xfer *ht_xfer[3];
-       int             ht_muxport; /* Mux. port no */
-       int             ht_open;
-       char            ht_name[32];
-};
-
-struct uhso_softc {
-       device_t                sc_dev;
-       struct usb_device       *sc_udev;
-       struct mtx              sc_mtx;
-       uint32_t                sc_type;        /* Interface definition */
-       int                     sc_radio;
-
-       struct usb_xfer         *sc_xfer[3];
-       uint8_t                 sc_iface_no;
-       uint8_t                 sc_iface_index;
-
-       /* Control pipe */
-       struct usb_xfer *       sc_ctrl_xfer[2];
-       uint8_t                 sc_ctrl_iface_no;
-
-       /* Network */
-       struct usb_xfer         *sc_if_xfer[2];
-       struct ifnet            *sc_ifp;
-       struct mbuf             *sc_mwait;      /* Partial packet */
-       size_t                  sc_waitlen;     /* No. of outstanding bytes */
-       struct ifqueue          sc_rxq;
-       struct callout          sc_c;
-
-       /* TTY related structures */
-       struct ucom_super_softc sc_super_ucom;
-       int                     sc_ttys;
-       struct uhso_tty         *sc_tty;
-       struct ucom_softc       *sc_ucom;
-       int                     sc_msr;
-       int                     sc_lsr;
-       int                     sc_line;
-};
-
-#define UHSO_MAX_MTU           2048
-
-/*
- * There are mainly two type of cards floating around.
- * The first one has 2,3 or 4 interfaces with a multiplexed serial port
- * and packet interface on the first interface and bulk serial ports
- * on the others.
- * The second type of card has several other interfaces, their purpose
- * can be detected during run-time.
- */
-#define UHSO_IFACE_SPEC(usb_type, port, port_type) \
-       (((usb_type) << 24) | ((port) << 16) | (port_type))
-
-#define UHSO_IFACE_USB_TYPE(x) ((x >> 24) & 0xff)
-#define UHSO_IFACE_PORT(x) ((x >> 16) & 0xff)
-#define UHSO_IFACE_PORT_TYPE(x) (x & 0xff)
-
-/*
- * USB interface types
- */
-#define UHSO_IF_NET            0x01    /* Network packet interface */
-#define UHSO_IF_MUX            0x02    /* Multiplexed serial port */
-#define UHSO_IF_BULK           0x04    /* Bulk interface */
-
-/*
- * Port types
- */
-#define UHSO_PORT_UNKNOWN      0x00
-#define UHSO_PORT_SERIAL       0x01    /* Serial port */
-#define UHSO_PORT_NETWORK      0x02    /* Network packet interface */
-
-/*
- * Multiplexed serial port destination sub-port names
- */
-#define UHSO_MPORT_TYPE_CTL    0x00    /* Control port */
-#define UHSO_MPORT_TYPE_APP    0x01    /* Application */
-#define UHSO_MPORT_TYPE_PCSC   0x02
-#define UHSO_MPORT_TYPE_GPS    0x03
-#define UHSO_MPORT_TYPE_APP2   0x04    /* Secondary application */
-#define UHSO_MPORT_TYPE_MAX    UHSO_MPORT_TYPE_APP2
-#define UHSO_MPORT_TYPE_NOMAX  8       /* Max number of mux ports */
-
-/*
- * Port definitions
- * Note that these definitions are arbitrary and do not match the values
- * returned by the auto config descriptor.
- */
-#define UHSO_PORT_TYPE_UNKNOWN 0x00
-#define UHSO_PORT_TYPE_CTL     0x01
-#define UHSO_PORT_TYPE_APP     0x02
-#define UHSO_PORT_TYPE_APP2    0x03
-#define UHSO_PORT_TYPE_MODEM   0x04
-#define UHSO_PORT_TYPE_NETWORK 0x05
-#define UHSO_PORT_TYPE_DIAG    0x06
-#define UHSO_PORT_TYPE_DIAG2   0x07
-#define UHSO_PORT_TYPE_GPS     0x08
-#define UHSO_PORT_TYPE_GPSCTL  0x09
-#define UHSO_PORT_TYPE_PCSC    0x0a
-#define UHSO_PORT_TYPE_MSD     0x0b
-#define UHSO_PORT_TYPE_VOICE   0x0c
-#define UHSO_PORT_TYPE_MAX     0x0c
-
-static eventhandler_tag uhso_etag;
-
-/* Overall port type */
-static char *uhso_port[] = {
-       "Unknown",
-       "Serial",
-       "Network",
-       "Network/Serial"
-};
-
-/*
- * Map between interface port type read from device and description type.
- * The position in this array is a direct map to the auto config
- * descriptor values.
- */
-static unsigned char uhso_port_map[] = {
-       UHSO_PORT_TYPE_UNKNOWN,
-       UHSO_PORT_TYPE_DIAG,
-       UHSO_PORT_TYPE_GPS,
-       UHSO_PORT_TYPE_GPSCTL,
-       UHSO_PORT_TYPE_APP,
-       UHSO_PORT_TYPE_APP2,
-       UHSO_PORT_TYPE_CTL,
-       UHSO_PORT_TYPE_NETWORK,
-       UHSO_PORT_TYPE_MODEM,
-       UHSO_PORT_TYPE_MSD,
-       UHSO_PORT_TYPE_PCSC,
-       UHSO_PORT_TYPE_VOICE
-};
-static char uhso_port_map_max = sizeof(uhso_port_map) / sizeof(char);
-
-static unsigned char uhso_mux_port_map[] = {
-       UHSO_PORT_TYPE_CTL,
-       UHSO_PORT_TYPE_APP,
-       UHSO_PORT_TYPE_PCSC,
-       UHSO_PORT_TYPE_GPS,
-       UHSO_PORT_TYPE_APP2
-};
-
-static char *uhso_port_type[] = {
-       "Unknown",  /* Not a valid port */
-       "Control",
-       "Application",
-       "Application (Secondary)",
-       "Modem",
-       "Network",
-       "Diagnostic",
-       "Diagnostic (Secondary)",
-       "GPS",
-       "GPS Control",
-       "PC Smartcard",
-       "MSD",
-       "Voice",
-};
-
-static char *uhso_port_type_sysctl[] = {
-       "unknown",
-       "control",
-       "application",
-       "application",
-       "modem",
-       "network",
-       "diagnostic",
-       "diagnostic",
-       "gps",
-       "gps_control",
-       "pcsc",
-       "msd",
-       "voice",
-};
-
-#define UHSO_STATIC_IFACE      0x01
-#define UHSO_AUTO_IFACE                0x02
-
-/* ifnet device unit allocations */
-static struct unrhdr *uhso_ifnet_unit = NULL;
-
-static const STRUCT_USB_HOST_ID uhso_devs[] = {
-#define        UHSO_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
-       /* Option GlobeTrotter MAX 7.2 with upgraded firmware */
-       UHSO_DEV(OPTION, GTMAX72, UHSO_STATIC_IFACE),
-       /* Option GlobeSurfer iCON 7.2 */
-       UHSO_DEV(OPTION, GSICON72, UHSO_STATIC_IFACE),
-       /* Option iCON 225 */
-       UHSO_DEV(OPTION, GTHSDPA, UHSO_STATIC_IFACE),
-       /* Option GlobeSurfer iCON HSUPA */
-       UHSO_DEV(OPTION, GSICONHSUPA, UHSO_STATIC_IFACE),
-       /* Option GlobeTrotter HSUPA */
-       UHSO_DEV(OPTION, GTHSUPA, UHSO_STATIC_IFACE),
-       /* GE40x */
-       UHSO_DEV(OPTION, GE40X, UHSO_AUTO_IFACE),
-       UHSO_DEV(OPTION, GE40X_1, UHSO_AUTO_IFACE),
-       UHSO_DEV(OPTION, GE40X_2, UHSO_AUTO_IFACE),
-       UHSO_DEV(OPTION, GE40X_3, UHSO_AUTO_IFACE),
-       /* Option GlobeSurfer iCON 401 */
-       UHSO_DEV(OPTION, ICON401, UHSO_AUTO_IFACE),
-       /* Option GlobeTrotter Module 382 */
-       UHSO_DEV(OPTION, GMT382, UHSO_AUTO_IFACE),
-       /* Option iCON EDGE */
-       UHSO_DEV(OPTION, ICONEDGE, UHSO_STATIC_IFACE),
-       /* Option Module HSxPA */
-       UHSO_DEV(OPTION, MODHSXPA, UHSO_STATIC_IFACE),
-       /* Option iCON 321 */
-       UHSO_DEV(OPTION, ICON321, UHSO_STATIC_IFACE),
-       /* Option iCON 322 */
-       UHSO_DEV(OPTION, GTICON322, UHSO_STATIC_IFACE),
-       /* Option iCON 505 */
-       UHSO_DEV(OPTION, ICON505, UHSO_AUTO_IFACE),
-       /* Option iCON 452 */
-       UHSO_DEV(OPTION, ICON505, UHSO_AUTO_IFACE),
-#undef UHSO_DEV
-};
-
-static SYSCTL_NODE(_hw_usb, OID_AUTO, uhso, CTLFLAG_RW, 0, "USB uhso");
-static int uhso_autoswitch = 1;
-SYSCTL_INT(_hw_usb_uhso, OID_AUTO, auto_switch, CTLFLAG_RWTUN,
-    &uhso_autoswitch, 0, "Automatically switch to modem mode");
-
-#ifdef USB_DEBUG
-#ifdef UHSO_DEBUG
-static int uhso_debug = UHSO_DEBUG;
-#else
-static int uhso_debug = -1;
-#endif
-
-SYSCTL_INT(_hw_usb_uhso, OID_AUTO, debug, CTLFLAG_RWTUN,
-    &uhso_debug, 0, "Debug level");
-
-#define UHSO_DPRINTF(n, x, ...) {\
-       if (uhso_debug >= n) {\
-               printf("%s: " x, __func__, ##__VA_ARGS__);\
-       }\
-}
-#else
-#define UHSO_DPRINTF(n, x, ...)
-#endif
-
-#ifdef UHSO_DEBUG_HEXDUMP
-# define UHSO_HEXDUMP(_buf, _len) do { \
-  { \
-        size_t __tmp; \
-        const char *__buf = (const char *)_buf; \
-        for (__tmp = 0; __tmp < _len; __tmp++) \
-                printf("%02hhx ", *__buf++); \
-    printf("\n"); \
-  } \
-} while(0)
-#else
-# define UHSO_HEXDUMP(_buf, _len)
-#endif
-
-enum {
-       UHSO_MUX_ENDPT_INTR = 0,
-       UHSO_MUX_ENDPT_MAX
-};
-
-enum {
-       UHSO_CTRL_READ = 0,
-       UHSO_CTRL_WRITE,
-       UHSO_CTRL_MAX
-};
-
-enum {
-       UHSO_IFNET_READ = 0,
-       UHSO_IFNET_WRITE,
-       UHSO_IFNET_MAX
-};
-
-enum {
-       UHSO_BULK_ENDPT_READ = 0,
-       UHSO_BULK_ENDPT_WRITE,
-       UHSO_BULK_ENDPT_INTR,
-       UHSO_BULK_ENDPT_MAX
-};
-
-static usb_callback_t uhso_mux_intr_callback;
-static usb_callback_t uhso_mux_read_callback;
-static usb_callback_t uhso_mux_write_callback;
-static usb_callback_t uhso_bs_read_callback;
-static usb_callback_t uhso_bs_write_callback;
-static usb_callback_t uhso_bs_intr_callback;
-static usb_callback_t uhso_ifnet_read_callback;
-static usb_callback_t uhso_ifnet_write_callback;
-
-/* Config used for the default control pipes */
-static const struct usb_config uhso_ctrl_config[UHSO_CTRL_MAX] = {
-       [UHSO_CTRL_READ] = {
-               .type = UE_CONTROL,
-               .endpoint = 0x00,
-               .direction = UE_DIR_ANY,
-               .flags = { .pipe_bof = 1, .short_xfer_ok = 1 },
-               .bufsize = sizeof(struct usb_device_request) + 1024,
-               .callback = &uhso_mux_read_callback
-       },
-
-       [UHSO_CTRL_WRITE] = {
-               .type = UE_CONTROL,
-               .endpoint = 0x00,
-               .direction = UE_DIR_ANY,
-               .flags = { .pipe_bof = 1, .force_short_xfer = 1 },
-               .bufsize = sizeof(struct usb_device_request) + 1024,
-               .timeout = 1000,
-               .callback = &uhso_mux_write_callback
-       }
-};
-
-/* Config for the multiplexed serial ports */
-static const struct usb_config uhso_mux_config[UHSO_MUX_ENDPT_MAX] = {
-       [UHSO_MUX_ENDPT_INTR] = {
-               .type = UE_INTERRUPT,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_IN,
-               .flags = { .short_xfer_ok = 1 },
-               .bufsize = 0,
-               .callback = &uhso_mux_intr_callback,
-       }
-};
-
-/* Config for the raw IP-packet interface */
-static const struct usb_config uhso_ifnet_config[UHSO_IFNET_MAX] = {
-       [UHSO_IFNET_READ] = {
-               .type = UE_BULK,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_IN,
-               .flags = { .pipe_bof = 1, .short_xfer_ok = 1 },
-               .bufsize = MCLBYTES,
-               .callback = &uhso_ifnet_read_callback
-       },
-       [UHSO_IFNET_WRITE] = {
-               .type = UE_BULK,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_OUT,
-               .flags = { .pipe_bof = 1, .force_short_xfer = 1 },
-               .bufsize = MCLBYTES,
-               .timeout = 5 * USB_MS_HZ,
-               .callback = &uhso_ifnet_write_callback
-       }
-};
-
-/* Config for interfaces with normal bulk serial ports */
-static const struct usb_config uhso_bs_config[UHSO_BULK_ENDPT_MAX] = {
-       [UHSO_BULK_ENDPT_READ] = {
-               .type = UE_BULK,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_IN,
-               .flags = { .pipe_bof = 1, .short_xfer_ok = 1 },
-               .bufsize = 4096,
-               .callback = &uhso_bs_read_callback
-       },
-
-       [UHSO_BULK_ENDPT_WRITE] = {
-               .type = UE_BULK,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_OUT,
-               .flags = { .pipe_bof = 1, .force_short_xfer = 1 },
-               .bufsize = 8192,
-               .callback = &uhso_bs_write_callback
-       },
-
-       [UHSO_BULK_ENDPT_INTR] = {
-               .type = UE_INTERRUPT,
-               .endpoint = UE_ADDR_ANY,
-               .direction = UE_DIR_IN,
-               .flags = { .short_xfer_ok = 1 },
-               .bufsize = 0,
-               .callback = &uhso_bs_intr_callback,
-       }
-};
-
-static int  uhso_probe_iface(struct uhso_softc *, int,
-    int (*probe)(struct usb_device *, int));
-static int  uhso_probe_iface_auto(struct usb_device *, int);
-static int  uhso_probe_iface_static(struct usb_device *, int);
-static int  uhso_attach_muxserial(struct uhso_softc *, struct usb_interface *,
-    int type);
-static int  uhso_attach_bulkserial(struct uhso_softc *, struct usb_interface *,
-    int type);
-static int  uhso_attach_ifnet(struct uhso_softc *, struct usb_interface *,
-    int type);
-static void uhso_test_autoinst(void *, struct usb_device *,
-               struct usb_attach_arg *);
-static int  uhso_driver_loaded(struct module *, int, void *);
-static int uhso_radio_sysctl(SYSCTL_HANDLER_ARGS);
-static int uhso_radio_ctrl(struct uhso_softc *, int);
-
-static void uhso_ucom_start_read(struct ucom_softc *);
-static void uhso_ucom_stop_read(struct ucom_softc *);
-static void uhso_ucom_start_write(struct ucom_softc *);
-static void uhso_ucom_stop_write(struct ucom_softc *);
-static void uhso_ucom_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *);
-static void uhso_ucom_cfg_set_dtr(struct ucom_softc *, uint8_t);
-static void uhso_ucom_cfg_set_rts(struct ucom_softc *, uint8_t);
-static void uhso_if_init(void *);
-static void uhso_if_start(struct ifnet *, struct ifaltq_subque *);
-static void uhso_if_stop(struct uhso_softc *);
-static int  uhso_if_ioctl(struct ifnet *, u_long, caddr_t);
-static int  uhso_if_output(struct ifnet *, struct mbuf *, struct sockaddr *,
-    struct route *);
-static void uhso_if_rxflush(void *);
-
-static device_probe_t uhso_probe;
-static device_attach_t uhso_attach;
-static device_detach_t uhso_detach;
-
-static device_method_t uhso_methods[] = {
-       DEVMETHOD(device_probe,         uhso_probe),
-       DEVMETHOD(device_attach,        uhso_attach),
-       DEVMETHOD(device_detach,        uhso_detach),
-       DEVMETHOD_END
-};
-
-static driver_t uhso_driver = {
-       "uhso",
-       uhso_methods,
-       sizeof(struct uhso_softc)
-};
-
-static devclass_t uhso_devclass;
-DRIVER_MODULE(uhso, uhub, uhso_driver, uhso_devclass, uhso_driver_loaded, NULL);
-MODULE_DEPEND(uhso, ucom, 1, 1, 1);
-MODULE_DEPEND(uhso, usb, 1, 1, 1);
-MODULE_VERSION(uhso, 1);
-
-static struct ucom_callback uhso_ucom_callback = {
-       .ucom_cfg_get_status = &uhso_ucom_cfg_get_status,
-       .ucom_cfg_set_dtr = &uhso_ucom_cfg_set_dtr,
-       .ucom_cfg_set_rts = &uhso_ucom_cfg_set_rts,
-       .ucom_start_read = uhso_ucom_start_read,
-       .ucom_stop_read = uhso_ucom_stop_read,
-       .ucom_start_write = uhso_ucom_start_write,
-       .ucom_stop_write = uhso_ucom_stop_write
-};
-
-static int
-uhso_probe(device_t self)
-{
-       struct usb_attach_arg *uaa = device_get_ivars(self);
-       int error;
-
-       if (uaa->usb_mode != USB_MODE_HOST)
-               return (ENXIO);
-       if (uaa->info.bConfigIndex != 0)
-               return (ENXIO);
-       if (uaa->info.bDeviceClass != 0xff)
-               return (ENXIO);
-
-       error = usbd_lookup_id_by_uaa(uhso_devs, sizeof(uhso_devs), uaa);
-       if (error != 0)
-               return (error);
-
-       /*
-        * Probe device to see if we are able to attach
-        * to this interface or not.
-        */
-       if (USB_GET_DRIVER_INFO(uaa) == UHSO_AUTO_IFACE) {
-               if (uhso_probe_iface_auto(uaa->device,
-                   uaa->info.bIfaceNum) == 0)
-                       return (ENXIO);
-       }
-       return (error);
-}
-
-static int
-uhso_attach(device_t self)
-{
-       struct uhso_softc *sc = device_get_softc(self);
-       struct usb_attach_arg *uaa = device_get_ivars(self);
-       struct usb_config_descriptor *cd;
-       struct usb_interface_descriptor *id;
-       struct sysctl_ctx_list *sctx;
-       struct sysctl_oid *soid;
-       struct sysctl_oid *tree = NULL, *tty_node;
-       struct ucom_softc *ucom;
-       struct uhso_tty *ht;
-       int i, error, port;
-       void *probe_f;
-       usb_error_t uerr;
-       char *desc;
-
-       sc->sc_dev = self;
-       sc->sc_udev = uaa->device;
-       mtx_init(&sc->sc_mtx, "uhso", NULL, MTX_DEF);
-
-       sc->sc_ucom = NULL;
-       sc->sc_ttys = 0;
-       sc->sc_radio = 1;
-
-       cd = usbd_get_config_descriptor(uaa->device);
-       id = usbd_get_interface_descriptor(uaa->iface);
-       sc->sc_ctrl_iface_no = id->bInterfaceNumber;
-
-       sc->sc_iface_no = uaa->info.bIfaceNum;
-       sc->sc_iface_index = uaa->info.bIfaceIndex;
-
-       /* Setup control pipe */
-       uerr = usbd_transfer_setup(uaa->device,
-           &sc->sc_iface_index, sc->sc_ctrl_xfer,
-           uhso_ctrl_config, UHSO_CTRL_MAX, sc, &sc->sc_mtx);
-       if (uerr) {
-               device_printf(self, "Failed to setup control pipe: %s\n",
-                   usbd_errstr(uerr));
-               goto out;
-       }
-
-       if (USB_GET_DRIVER_INFO(uaa) == UHSO_STATIC_IFACE)
-               probe_f = uhso_probe_iface_static;
-       else if (USB_GET_DRIVER_INFO(uaa) == UHSO_AUTO_IFACE)
-               probe_f = uhso_probe_iface_auto;
-       else
-               goto out;
-
-       error = uhso_probe_iface(sc, uaa->info.bIfaceNum, probe_f);
-       if (error != 0)
-               goto out;
-
-       sctx = device_get_sysctl_ctx(sc->sc_dev);
-       soid = device_get_sysctl_tree(sc->sc_dev);
-
-       SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "type",
-           CTLFLAG_RD, uhso_port[UHSO_IFACE_PORT(sc->sc_type)], 0,
-           "Port available at this interface");
-       SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "radio",
-           CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0, uhso_radio_sysctl, "I", "Enable radio");
-
-       /*
-        * The default interface description on most Option devices isn't
-        * very helpful. So we skip device_set_usb_desc and set the
-        * device description manually.
-        */
-       device_set_desc_copy(self, uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)]); 
-       /* Announce device */
-       device_printf(self, "<%s port> at <%s %s> on %s\n",
-           uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)],
-           usb_get_manufacturer(uaa->device),
-           usb_get_product(uaa->device),
-           device_get_nameunit(device_get_parent(self)));
-
-       if (sc->sc_ttys > 0) {
-               SYSCTL_ADD_INT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "ports",
-                   CTLFLAG_RD, &sc->sc_ttys, 0, "Number of attached serial ports");
-
-               tree = SYSCTL_ADD_NODE(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
-                   "port", CTLFLAG_RD, NULL, "Serial ports");
-       }
-
-       /*
-        * Loop through the number of found TTYs and create sysctl
-        * nodes for them.
-        */
-       for (i = 0; i < sc->sc_ttys; i++) {
-               ht = &sc->sc_tty[i];
-               ucom = &sc->sc_ucom[i];
-
-               if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX)
-                       port = uhso_mux_port_map[ht->ht_muxport];
-               else
-                       port = UHSO_IFACE_PORT_TYPE(sc->sc_type);
-
-               desc = uhso_port_type_sysctl[port];
-
-               tty_node = SYSCTL_ADD_NODE(sctx, SYSCTL_CHILDREN(tree), OID_AUTO,
-                   desc, CTLFLAG_RD, NULL, "");
-
-               ht->ht_name[0] = 0;
-               if (sc->sc_ttys == 1)
-                       snprintf(ht->ht_name, 32, "cuaU%d", ucom->sc_super->sc_unit);
-               else {
-                       snprintf(ht->ht_name, 32, "cuaU%d.%d",
-                           ucom->sc_super->sc_unit, ucom->sc_subunit);
-               }
-
-               desc = uhso_port_type[port];
-               SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(tty_node), OID_AUTO,
-                   "tty", CTLFLAG_RD, ht->ht_name, 0, "");
-               SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(tty_node), OID_AUTO,
-                   "desc", CTLFLAG_RD, desc, 0, "");
-
-               if (bootverbose)
-                       device_printf(sc->sc_dev,
-                           "\"%s\" port at %s\n", desc, ht->ht_name);
-       }
-
-       return (0);
-out:
-       uhso_detach(sc->sc_dev);
-       return (ENXIO);
-}
-
-static int
-uhso_detach(device_t self)
-{
-       struct uhso_softc *sc = device_get_softc(self);
-       int i;
-
-       usbd_transfer_unsetup(sc->sc_xfer, 3);
-       usbd_transfer_unsetup(sc->sc_ctrl_xfer, UHSO_CTRL_MAX);
-       if (sc->sc_ttys > 0) {
-               ucom_detach(&sc->sc_super_ucom, sc->sc_ucom);
-
-               for (i = 0; i < sc->sc_ttys; i++) {
-                       if (sc->sc_tty[i].ht_muxport != -1) {
-                               usbd_transfer_unsetup(sc->sc_tty[i].ht_xfer,
-                                   UHSO_CTRL_MAX);
-                       }
-               }
-
-               free(sc->sc_tty, M_USBDEV);
-               free(sc->sc_ucom, M_USBDEV);
-       }
-
-       if (sc->sc_ifp != NULL) {
-               callout_drain(&sc->sc_c);
-               free_unr(uhso_ifnet_unit, sc->sc_ifp->if_dunit);
-               mtx_lock(&sc->sc_mtx);
-               uhso_if_stop(sc);
-               bpfdetach(sc->sc_ifp);
-               if_detach(sc->sc_ifp);
-               if_free(sc->sc_ifp);
-               mtx_unlock(&sc->sc_mtx);
-               usbd_transfer_unsetup(sc->sc_if_xfer, UHSO_IFNET_MAX);
-       }
-
-       mtx_destroy(&sc->sc_mtx);
-       return (0);
-}
-
-static void
-uhso_test_autoinst(void *arg, struct usb_device *udev,
-    struct usb_attach_arg *uaa)
-{
-       struct usb_interface *iface;
-       struct usb_interface_descriptor *id;
-
-       if (uaa->dev_state != UAA_DEV_READY || !uhso_autoswitch)
-               return;
-
-       iface = usbd_get_iface(udev, 0);
-       if (iface == NULL)
-               return;
-       id = iface->idesc;
-       if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
-               return;
-       if (usbd_lookup_id_by_uaa(uhso_devs, sizeof(uhso_devs), uaa))
-               return;         /* no device match */
-
-       if (usb_msc_eject(udev, 0, MSC_EJECT_REZERO) == 0) {
-               /* success, mark the udev as disappearing */
-               uaa->dev_state = UAA_DEV_EJECTING;
-       }
-}
-
-static int
-uhso_driver_loaded(struct module *mod, int what, void *arg)
-{
-       switch (what) {
-       case MOD_LOAD:
-               /* register our autoinstall handler */
-               uhso_etag = EVENTHANDLER_REGISTER(usb_dev_configured,
-                   uhso_test_autoinst, NULL, EVENTHANDLER_PRI_ANY);
-               /* create our unit allocator for inet devs */
-               uhso_ifnet_unit = new_unrhdr(0, INT_MAX, NULL);
-               break;
-       case MOD_UNLOAD:
-               EVENTHANDLER_DEREGISTER(usb_dev_configured, uhso_etag);
-               delete_unrhdr(uhso_ifnet_unit);
-               break;
-       default:
-               return (EOPNOTSUPP);
-       }
-       return (0);
-}
-
-/*
- * Probe the interface type by querying the device. The elements
- * of an array indicates the capabilities of a particular interface.
- * Returns a bit mask with the interface capabilities.
- */
-static int
-uhso_probe_iface_auto(struct usb_device *udev, int index)
-{
-       struct usb_device_request req;
-       usb_error_t uerr;
-       uint16_t actlen = 0;
-       char port;
-       char buf[17] = {0};
-
-       req.bmRequestType = UT_READ_VENDOR_DEVICE;
-       req.bRequest = 0x86;
-       USETW(req.wValue, 0);
-       USETW(req.wIndex, 0);
-       USETW(req.wLength, 17);
-
-       uerr = usbd_do_request_flags(udev, NULL, &req, buf,
-           0, &actlen, USB_MS_HZ);
-       if (uerr != 0) {
-               printf("%s: usbd_do_request_flags failed, %s\n",
-                   __func__, usbd_errstr(uerr));
-               return (0);
-       }
-
-       UHSO_DPRINTF(1, "actlen=%d\n", actlen);
-       UHSO_HEXDUMP(buf, 17);
-
-       if (index < 0 || index > 16) {
-               UHSO_DPRINTF(0, "Index %d out of range\n", index);
-               return (0);
-       }
-
-       UHSO_DPRINTF(1, "index=%d, type=%x[%s]\n", index, buf[index],
-           uhso_port_type[(int)uhso_port_map[(int)buf[index]]]);
-
-       if (buf[index] >= uhso_port_map_max)
-               port = 0;
-       else
-               port = uhso_port_map[(int)buf[index]];
-
-       switch (port) {
-       case UHSO_PORT_TYPE_NETWORK:
-               return (UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX,
-                   UHSO_PORT_SERIAL | UHSO_PORT_NETWORK, port));
-       case UHSO_PORT_TYPE_DIAG:
-       case UHSO_PORT_TYPE_DIAG2:
-       case UHSO_PORT_TYPE_CTL:
-       case UHSO_PORT_TYPE_APP:
-       case UHSO_PORT_TYPE_APP2:
-       case UHSO_PORT_TYPE_MODEM:
-               return (UHSO_IFACE_SPEC(UHSO_IF_BULK,
-                   UHSO_PORT_SERIAL, port));
-       case UHSO_PORT_TYPE_MSD:
-               return (0);
-       case UHSO_PORT_TYPE_UNKNOWN:
-       default:
-               return (0);
-       }
-
-       return (0);
-}
-
-/*
- * Returns the capabilities of interfaces for devices that don't
- * support the automatic query.
- * Returns a bit mask with the interface capabilities.
- */
-static int
-uhso_probe_iface_static(struct usb_device *udev, int index)
-{
-       struct usb_config_descriptor *cd;
-
-       cd = usbd_get_config_descriptor(udev);
-       if (cd->bNumInterface <= 3) {
-               /* Cards with 3 or less interfaces */
-               switch (index) {
-               case 0:
-                       return UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX,
-                           UHSO_PORT_SERIAL | UHSO_PORT_NETWORK,
-                           UHSO_PORT_TYPE_NETWORK);
-               case 1:
-                       return UHSO_IFACE_SPEC(UHSO_IF_BULK,
-                           UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG);
-               case 2:
-                       return UHSO_IFACE_SPEC(UHSO_IF_BULK,
-                           UHSO_PORT_SERIAL, UHSO_PORT_TYPE_MODEM);
-               }
-       } else {
-               /* Cards with 4 interfaces */
-               switch (index) {
-               case 0:
-                       return UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX,
-                           UHSO_PORT_SERIAL | UHSO_PORT_NETWORK,
-                           UHSO_PORT_TYPE_NETWORK);
-               case 1:
-                       return UHSO_IFACE_SPEC(UHSO_IF_BULK,
-                           UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG2);
-               case 2:
-                       return UHSO_IFACE_SPEC(UHSO_IF_BULK,
-                           UHSO_PORT_SERIAL, UHSO_PORT_TYPE_MODEM);
-               case 3:
-                       return UHSO_IFACE_SPEC(UHSO_IF_BULK,
-                           UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG);
-               }
-       }
-       return (0);
-}
-
-/*
- * Probes an interface for its particular capabilities and attaches if
- * it's a supported interface.
- */
-static int
-uhso_probe_iface(struct uhso_softc *sc, int index,
-    int (*probe)(struct usb_device *, int))
-{
-       struct usb_interface *iface;
-       int type, error;
-
-       UHSO_DPRINTF(1, "Probing for interface %d, probe_func=%p\n", index, probe);
-
-       type = probe(sc->sc_udev, index);
-       UHSO_DPRINTF(1, "Probe result %x\n", type);
-       if (type <= 0)
-               return (ENXIO);
-
-       sc->sc_type = type;
-       iface = usbd_get_iface(sc->sc_udev, index);
-
-       if (UHSO_IFACE_PORT_TYPE(type) == UHSO_PORT_TYPE_NETWORK) {
-               error = uhso_attach_ifnet(sc, iface, type);
-               if (error) {
-                       UHSO_DPRINTF(1, "uhso_attach_ifnet failed");
-                       return (ENXIO);
-               }
-
-               /*
-                * If there is an additional interrupt endpoint on this
-                * interface then we most likely have a multiplexed serial port
-                * available.
-                */
-               if (iface->idesc->bNumEndpoints < 3) {
-                       sc->sc_type = UHSO_IFACE_SPEC( 
-                           UHSO_IFACE_USB_TYPE(type) & ~UHSO_IF_MUX,
-                           UHSO_IFACE_PORT(type) & ~UHSO_PORT_SERIAL,
-                           UHSO_IFACE_PORT_TYPE(type));
-                       return (0);
-               }
-
-               UHSO_DPRINTF(1, "Trying to attach mux. serial\n");
-               error = uhso_attach_muxserial(sc, iface, type);
-               if (error == 0 && sc->sc_ttys > 0) {
-                       error = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom,
-                           sc->sc_ttys, sc, &uhso_ucom_callback, &sc->sc_mtx);
-                       if (error) {
-                               device_printf(sc->sc_dev, "ucom_attach failed\n");
-                               return (ENXIO);
-                       }
-                       ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev);
-
-                       mtx_lock(&sc->sc_mtx);
-                       usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
-                       mtx_unlock(&sc->sc_mtx);
-               }
-       } else if ((UHSO_IFACE_USB_TYPE(type) & UHSO_IF_BULK) &&
-           UHSO_IFACE_PORT(type) & UHSO_PORT_SERIAL) {
-
-               error = uhso_attach_bulkserial(sc, iface, type);
-               if (error)
-                       return (ENXIO);
-
-               error = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom,
-                   sc->sc_ttys, sc, &uhso_ucom_callback, &sc->sc_mtx);
-               if (error) {
-                       device_printf(sc->sc_dev, "ucom_attach failed\n");
-                       return (ENXIO);
-               }
-               ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev);
-       }
-       else {
-               UHSO_DPRINTF(0, "Unknown type %x\n", type);
-               return (ENXIO);
-       }
-
-       return (0);
-}
-
-static int
-uhso_radio_ctrl(struct uhso_softc *sc, int onoff)
-{
-       struct usb_device_request req;
-       usb_error_t uerr;
-
-       req.bmRequestType = UT_VENDOR;
-       req.bRequest = onoff ? 0x82 : 0x81;
-       USETW(req.wValue, 0);
-       USETW(req.wIndex, 0);
-       USETW(req.wLength, 0);
-
-       uerr = usbd_do_request(sc->sc_udev, NULL, &req, NULL);
-       if (uerr != 0) {
-               device_printf(sc->sc_dev, "usbd_do_request_flags failed: %s\n",
-                   usbd_errstr(uerr));
-               return (-1);
-       }
-       return (onoff);
-}
-
-static int
-uhso_radio_sysctl(SYSCTL_HANDLER_ARGS)
-{
-       struct uhso_softc *sc = arg1;
-       int error, radio;
-
-       radio = sc->sc_radio;
-       error = sysctl_handle_int(oidp, &radio, 0, req);
-       if (error)
-               return (error);
-       if (radio != sc->sc_radio) {
-               radio = radio != 0 ? 1 : 0;
-               error = uhso_radio_ctrl(sc, radio);
-               if (error != -1)
-                       sc->sc_radio = radio;
-       }
-       return (0);
-}
-
-/*
- * Expands allocated memory to fit an additional TTY.
- * Two arrays are kept with matching indexes, one for ucom and one
- * for our private data.
- */
-static int
-uhso_alloc_tty(struct uhso_softc *sc)
-{
-
-       sc->sc_ttys++;
-       sc->sc_tty = reallocf(sc->sc_tty, sizeof(struct uhso_tty) * sc->sc_ttys,
-           M_USBDEV, M_WAITOK | M_ZERO);
-       if (sc->sc_tty == NULL)
-               return (-1);
-
-       sc->sc_ucom = reallocf(sc->sc_ucom,
-           sizeof(struct ucom_softc) * sc->sc_ttys, M_USBDEV, M_WAITOK | M_ZERO);
-       if (sc->sc_ucom == NULL)
-               return (-1);
-
-       sc->sc_tty[sc->sc_ttys - 1].ht_sc = sc;
-
-       UHSO_DPRINTF(1, "Allocated TTY %d\n", sc->sc_ttys - 1);
-       return (sc->sc_ttys - 1);
-}
-
-/*
- * Attach a multiplexed serial port
- * Data is read/written with requests on the default control pipe. An interrupt
- * endpoint returns when there is new data to be read.
- */
-static int
-uhso_attach_muxserial(struct uhso_softc *sc, struct usb_interface *iface,
-    int type)
-{
-       struct usb_descriptor *desc;
-       int i, port, tty;
-       usb_error_t uerr;
-
-       /*
-        * The class specific interface (type 0x24) descriptor subtype field
-        * contains a bitmask that specifies which (and how many) ports that
-        * are available through this multiplexed serial port.
-        */
-       desc = usbd_find_descriptor(sc->sc_udev, NULL,
-           iface->idesc->bInterfaceNumber, UDESC_CS_INTERFACE, 0xff, 0, 0);
-       if (desc == NULL) {
-               UHSO_DPRINTF(0, "Failed to find UDESC_CS_INTERFACE\n");
-               return (ENXIO);
-       }
-
-       UHSO_DPRINTF(1, "Mux port mask %x\n", desc->bDescriptorSubtype);
-       if (desc->bDescriptorSubtype == 0)
-               return (ENXIO);
-
-       /*
-        * The bitmask is one octet, loop through the number of
-        * bits that are set and create a TTY for each.
-        */
-       for (i = 0; i < 8; i++) {
-               port = (1 << i);
-               if ((port & desc->bDescriptorSubtype) == port) {
-                       UHSO_DPRINTF(2, "Found mux port %x (%d)\n", port, i);
-                       tty = uhso_alloc_tty(sc);
-                       if (tty < 0)
-                               return (ENOMEM);
-                       sc->sc_tty[tty].ht_muxport = i;
-                       uerr = usbd_transfer_setup(sc->sc_udev,
-                           &sc->sc_iface_index, sc->sc_tty[tty].ht_xfer,
-                           uhso_ctrl_config, UHSO_CTRL_MAX, sc, &sc->sc_mtx);
-                       if (uerr) {
-                               device_printf(sc->sc_dev,
-                                   "Failed to setup control pipe: %s\n",
-                                   usbd_errstr(uerr));
-                               return (ENXIO);
-                       }
-               }
-       }
-
-       /* Setup the intr. endpoint */
-       uerr = usbd_transfer_setup(sc->sc_udev,
-           &iface->idesc->bInterfaceNumber, sc->sc_xfer,
-           uhso_mux_config, 1, sc, &sc->sc_mtx);
-       if (uerr)
-               return (ENXIO);
-
-       return (0);
-}
-
-/*
- * Interrupt callback for the multiplexed serial port. Indicates
- * which serial port has data waiting.
- */
-static void
-uhso_mux_intr_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct usb_page_cache *pc;
-       struct usb_page_search res;
-       struct uhso_softc *sc = usbd_xfer_softc(xfer);
-       unsigned int i, mux;
-
-       UHSO_DPRINTF(3, "status %d\n", USB_GET_STATE(xfer));
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               /*
-                * The multiplexed port number can be found at the first byte.
-                * It contains a bit mask, we transform this in to an integer.
-                */
-               pc = usbd_xfer_get_frame(xfer, 0);
-               usbd_get_page(pc, 0, &res);
-
-               i = *((unsigned char *)res.buffer);
-               mux = 0;
-               while (i >>= 1) {
-                       mux++;
-               }
-
-               UHSO_DPRINTF(3, "mux port %d (%d)\n", mux, i);
-               if (mux > UHSO_MPORT_TYPE_NOMAX)
-                       break;
-
-               /* Issue a read for this serial port */
-               usbd_xfer_set_priv(
-                   sc->sc_tty[mux].ht_xfer[UHSO_CTRL_READ],
-                   &sc->sc_tty[mux]);
-               usbd_transfer_start(sc->sc_tty[mux].ht_xfer[UHSO_CTRL_READ]);
-
-               break;
-       case USB_ST_SETUP:
-tr_setup:
-               usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
-               usbd_transfer_submit(xfer);
-               break;
-       default:
-               UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
-               if (error == USB_ERR_CANCELLED)
-                       break;
-
-               usbd_xfer_set_stall(xfer);
-               goto tr_setup;
-       }
-}
-
-static void
-uhso_mux_read_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct uhso_softc *sc = usbd_xfer_softc(xfer);
-       struct usb_page_cache *pc;
-       struct usb_device_request req;
-       struct uhso_tty *ht;
-       int actlen, len;
-
-       usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-
-       UHSO_DPRINTF(3, "status %d\n", USB_GET_STATE(xfer));
-
-       ht = usbd_xfer_get_priv(xfer);
-       UHSO_DPRINTF(3, "ht=%p open=%d\n", ht, ht->ht_open);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               /* Got data, send to ucom */
-               pc = usbd_xfer_get_frame(xfer, 1);
-               len = usbd_xfer_frame_len(xfer, 1);
-
-               UHSO_DPRINTF(3, "got %d bytes on mux port %d\n", len,
-                   ht->ht_muxport);
-               if (len <= 0) {
-                       usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
-                       break;
-               }
-
-               /* Deliver data if the TTY is open, discard otherwise */
-               if (ht->ht_open)
-                       ucom_put_data(&sc->sc_ucom[ht->ht_muxport], pc, 0, len);
-               /* FALLTHROUGH */
-       case USB_ST_SETUP:
-tr_setup:
-               memset(&req, 0, sizeof(struct usb_device_request));
-               req.bmRequestType = UT_READ_CLASS_INTERFACE;
-               req.bRequest = UCDC_GET_ENCAPSULATED_RESPONSE;
-               USETW(req.wValue, 0);
-               USETW(req.wIndex, ht->ht_muxport);
-               USETW(req.wLength, 1024);
-
-               pc = usbd_xfer_get_frame(xfer, 0);
-               usbd_copy_in(pc, 0, &req, sizeof(req));
-
-               usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
-               usbd_xfer_set_frame_len(xfer, 1, 1024);
-               usbd_xfer_set_frames(xfer, 2);
-               usbd_transfer_submit(xfer);
-               break;
-       default:
-               UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
-               if (error == USB_ERR_CANCELLED)
-                       break;
-               usbd_xfer_set_stall(xfer);
-               goto tr_setup;
-       }
-}
-
-static void
-uhso_mux_write_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct uhso_softc *sc = usbd_xfer_softc(xfer);
-       struct uhso_tty *ht;
-       struct usb_page_cache *pc;
-       struct usb_device_request req;
-       int actlen;
-       struct usb_page_search res;
-
-       usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-
-       ht = usbd_xfer_get_priv(xfer);
-       UHSO_DPRINTF(3, "status=%d, using mux port %d\n",
-           USB_GET_STATE(xfer), ht->ht_muxport);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               UHSO_DPRINTF(3, "wrote %zd data bytes to muxport %d\n",
-                   actlen - sizeof(struct usb_device_request) ,
-                   ht->ht_muxport);
-               /* FALLTHROUGH */
-       case USB_ST_SETUP:
-               pc = usbd_xfer_get_frame(xfer, 1);
-               if (ucom_get_data(&sc->sc_ucom[ht->ht_muxport], pc,
-                   0, 32, &actlen)) {
-
-                       usbd_get_page(pc, 0, &res);
-
-                       memset(&req, 0, sizeof(struct usb_device_request));
-                       req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
-                       req.bRequest = UCDC_SEND_ENCAPSULATED_COMMAND;
-                       USETW(req.wValue, 0);
-                       USETW(req.wIndex, ht->ht_muxport);
-                       USETW(req.wLength, actlen);
-
-                       pc = usbd_xfer_get_frame(xfer, 0);
-                       usbd_copy_in(pc, 0, &req, sizeof(req));
-
-                       usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
-                       usbd_xfer_set_frame_len(xfer, 1, actlen);
-                       usbd_xfer_set_frames(xfer, 2);
-
-                       UHSO_DPRINTF(3, "Prepared %d bytes for transmit "
-                           "on muxport %d\n", actlen, ht->ht_muxport);
-
-                       usbd_transfer_submit(xfer);
-               }
-               break;
-       default:
-               UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
-               if (error == USB_ERR_CANCELLED)
-                       break;
-               break;
-       }
-}
-
-static int
-uhso_attach_bulkserial(struct uhso_softc *sc, struct usb_interface *iface,
-    int type)
-{
-       usb_error_t uerr;
-       int tty;
-
-       /* Try attaching RD/WR/INTR first */
-       uerr = usbd_transfer_setup(sc->sc_udev,
-           &iface->idesc->bInterfaceNumber, sc->sc_xfer,
-           uhso_bs_config, UHSO_BULK_ENDPT_MAX, sc, &sc->sc_mtx);
-       if (uerr) {
-               /* Try only RD/WR */
-               uerr = usbd_transfer_setup(sc->sc_udev,
-                   &iface->idesc->bInterfaceNumber, sc->sc_xfer,
-                   uhso_bs_config, UHSO_BULK_ENDPT_MAX - 1, sc, &sc->sc_mtx);
-       }
-       if (uerr) {
-               UHSO_DPRINTF(0, "usbd_transfer_setup failed");
-               return (-1);
-       }
-
-       tty = uhso_alloc_tty(sc);
-       if (tty < 0) {
-               usbd_transfer_unsetup(sc->sc_xfer, UHSO_BULK_ENDPT_MAX);
-               return (ENOMEM);
-       }
-
-       sc->sc_tty[tty].ht_muxport = -1;
-       return (0);
-}
-
-static void
-uhso_bs_read_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct uhso_softc *sc = usbd_xfer_softc(xfer);
-       struct usb_page_cache *pc;
-       int actlen;
-
-       usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-
-       UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               pc = usbd_xfer_get_frame(xfer, 0);
-               ucom_put_data(&sc->sc_ucom[0], pc, 0, actlen);
-               /* FALLTHROUGH */
-       case USB_ST_SETUP:
-tr_setup:
-               usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
-               usbd_transfer_submit(xfer);
-       break;
-       default:
-               UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
-               if (error == USB_ERR_CANCELLED)
-                       break;
-               usbd_xfer_set_stall(xfer);
-               goto tr_setup;
-       }
-}
-
-static void
-uhso_bs_write_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct uhso_softc *sc = usbd_xfer_softc(xfer);
-       struct usb_page_cache *pc;
-       int actlen;
-
-       usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-
-       UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-       case USB_ST_SETUP:
-tr_setup:
-               pc = usbd_xfer_get_frame(xfer, 0);
-               if (ucom_get_data(&sc->sc_ucom[0], pc, 0, 8192, &actlen)) {
-                       usbd_xfer_set_frame_len(xfer, 0, actlen);
-                       usbd_transfer_submit(xfer);
-               }
-               break;
-       break;
-       default:
-               UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
-               if (error == USB_ERR_CANCELLED)
-                       break;
-               usbd_xfer_set_stall(xfer);
-               goto tr_setup;
-       }
-}
-
-static void
-uhso_bs_cfg(struct uhso_softc *sc)
-{
-       struct usb_device_request req;
-       usb_error_t uerr;
-
-       if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK))
-               return;
-
-       req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
-       req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
-       USETW(req.wValue, sc->sc_line);
-       USETW(req.wIndex, sc->sc_iface_no);
-       USETW(req.wLength, 0);
-
-       uerr = ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom[0], &req, NULL, 0, 1000);
-       if (uerr != 0) {
-               device_printf(sc->sc_dev, "failed to set ctrl line state to "
-                   "0x%02x: %s\n", sc->sc_line, usbd_errstr(uerr));
-       }
-}
-
-static void
-uhso_bs_intr_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct uhso_softc *sc = usbd_xfer_softc(xfer);
-       struct usb_page_cache *pc;
-       int actlen;
-       struct usb_cdc_notification cdc;
-
-       usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-       UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               if (actlen < UCDC_NOTIFICATION_LENGTH) {
-                       UHSO_DPRINTF(0, "UCDC notification too short: %d\n", actlen);
-                       goto tr_setup;
-               }
-               else if (actlen > sizeof(struct usb_cdc_notification)) {
-                       UHSO_DPRINTF(0, "UCDC notification too large: %d\n", actlen);
-                       actlen = sizeof(struct usb_cdc_notification);
-               }
-
-               pc = usbd_xfer_get_frame(xfer, 0);
-               usbd_copy_out(pc, 0, &cdc, actlen);
-
-               if (UGETW(cdc.wIndex) != sc->sc_iface_no) {
-                       UHSO_DPRINTF(0, "Interface mismatch, got %d expected %d\n",
-                           UGETW(cdc.wIndex), sc->sc_iface_no);
-                       goto tr_setup;
-               }
-
-               if (cdc.bmRequestType == UCDC_NOTIFICATION &&
-                   cdc.bNotification == UCDC_N_SERIAL_STATE) {
-                       UHSO_DPRINTF(2, "notify = 0x%02x\n", cdc.data[0]);
-
-                       sc->sc_msr = 0;
-                       sc->sc_lsr = 0;
-                       if (cdc.data[0] & UCDC_N_SERIAL_RI)
-                               sc->sc_msr |= SER_RI;
-                       if (cdc.data[0] & UCDC_N_SERIAL_DSR)
-                               sc->sc_msr |= SER_DSR;
-                       if (cdc.data[0] & UCDC_N_SERIAL_DCD)
-                               sc->sc_msr |= SER_DCD;
-
-                       ucom_status_change(&sc->sc_ucom[0]);
-               }
-       case USB_ST_SETUP:
-tr_setup:
-       default:
-               if (error == USB_ERR_CANCELLED)
-                       break;
-               usbd_xfer_set_stall(xfer);
-               goto tr_setup;
-       }
-}
-
-static void
-uhso_ucom_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr)
-{
-       struct uhso_softc *sc = ucom->sc_parent;
-
-       *lsr = sc->sc_lsr;
-       *msr = sc->sc_msr;
-}
-
-static void
-uhso_ucom_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff)
-{
-       struct uhso_softc *sc = ucom->sc_parent;
-
-       if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK))
-               return;
-
-       if (onoff)
-               sc->sc_line |= UCDC_LINE_DTR;
-       else
-               sc->sc_line &= ~UCDC_LINE_DTR;
-
-       uhso_bs_cfg(sc);
-}
-
-static void
-uhso_ucom_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff)
-{
-       struct uhso_softc *sc = ucom->sc_parent;
-
-       if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK))
-               return;
-
-       if (onoff)
-               sc->sc_line |= UCDC_LINE_RTS;
-       else
-               sc->sc_line &= ~UCDC_LINE_RTS;
-
-       uhso_bs_cfg(sc);
-}
-
-static void
-uhso_ucom_start_read(struct ucom_softc *ucom)
-{
-       struct uhso_softc *sc = ucom->sc_parent;
-
-       UHSO_DPRINTF(3, "unit=%d, subunit=%d\n",
-           ucom->sc_super->sc_unit, ucom->sc_subunit);
-
-       if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
-               sc->sc_tty[ucom->sc_subunit].ht_open = 1;
-               usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
-       }
-       else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
-               sc->sc_tty[0].ht_open = 1;
-               usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_READ]);
-               if (sc->sc_xfer[UHSO_BULK_ENDPT_INTR] != NULL)
-                       usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_INTR]);
-       }
-}
-
-static void
-uhso_ucom_stop_read(struct ucom_softc *ucom)
-{
-
-       struct uhso_softc *sc = ucom->sc_parent;
-
-       if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
-               sc->sc_tty[ucom->sc_subunit].ht_open = 0;
-               usbd_transfer_stop(
-                   sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_READ]);
-       }
-       else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
-               sc->sc_tty[0].ht_open = 0;
-               usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_READ]);
-               if (sc->sc_xfer[UHSO_BULK_ENDPT_INTR] != NULL)
-                       usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_INTR]);
-       }
-}
-
-static void
-uhso_ucom_start_write(struct ucom_softc *ucom)
-{
-       struct uhso_softc *sc = ucom->sc_parent;
-
-       if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
-               UHSO_DPRINTF(3, "local unit %d\n", ucom->sc_subunit);
-
-               usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
-
-               usbd_xfer_set_priv(
-                   sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE],
-                   &sc->sc_tty[ucom->sc_subunit]);
-               usbd_transfer_start(
-                   sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]);
-
-       }
-       else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
-               usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]);
-       }
-}
-
-static void
-uhso_ucom_stop_write(struct ucom_softc *ucom)
-{
-       struct uhso_softc *sc = ucom->sc_parent;
-
-       if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
-               usbd_transfer_stop(
-                   sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]);
-       }
-       else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
-               usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]);
-       }
-}
-
-static int
-uhso_attach_ifnet(struct uhso_softc *sc, struct usb_interface *iface, int type)
-{
-       struct ifnet *ifp;
-       usb_error_t uerr;
-       struct sysctl_ctx_list *sctx;
-       struct sysctl_oid *soid;
-       unsigned int devunit;
-
-       uerr = usbd_transfer_setup(sc->sc_udev,
-           &iface->idesc->bInterfaceNumber, sc->sc_if_xfer,
-           uhso_ifnet_config, UHSO_IFNET_MAX, sc, &sc->sc_mtx);
-       if (uerr) {
-               UHSO_DPRINTF(0, "usbd_transfer_setup failed: %s\n",
-                   usbd_errstr(uerr));
-               return (-1);
-       }
-
-       sc->sc_ifp = ifp = if_alloc(IFT_OTHER);
-       if (sc->sc_ifp == NULL) {
-               device_printf(sc->sc_dev, "if_alloc() failed\n");
-               return (-1);
-       }
-
-       callout_init_mtx(&sc->sc_c, &sc->sc_mtx, 0);
-       mtx_lock(&sc->sc_mtx);
-       callout_reset(&sc->sc_c, 1, uhso_if_rxflush, sc);
-       mtx_unlock(&sc->sc_mtx);
-
-       /*
-        * We create our own unit numbers for ifnet devices because the
-        * USB interface unit numbers can be at arbitrary positions yielding
-        * odd looking device names.
-        */
-       devunit = alloc_unr(uhso_ifnet_unit);
-
-       if_initname(ifp, device_get_name(sc->sc_dev), devunit);
-       ifp->if_mtu = UHSO_MAX_MTU;
-       ifp->if_ioctl = uhso_if_ioctl;
-       ifp->if_init = uhso_if_init;
-       ifp->if_start = uhso_if_start;
-       ifp->if_output = uhso_if_output;
-       ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_NOARP;
-       ifp->if_softc = sc;
-       IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
-       ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
-       IFQ_SET_READY(&ifp->if_snd);
-
-       if_attach(ifp);
-       bpfattach(ifp, DLT_RAW, 0);
-
-       sctx = device_get_sysctl_ctx(sc->sc_dev);
-       soid = device_get_sysctl_tree(sc->sc_dev);
-       /* Unlocked read... */
-       SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "netif",
-           CTLFLAG_RD, ifp->if_xname, 0, "Attached network interface");
-
-       return (0);
-}
-
-static void
-uhso_ifnet_read_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct uhso_softc *sc = usbd_xfer_softc(xfer);
-       struct mbuf *m;
-       struct usb_page_cache *pc;
-       int actlen;
-
-       usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-
-       UHSO_DPRINTF(3, "status=%d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               if (actlen > 0 && (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-                       pc = usbd_xfer_get_frame(xfer, 0);
-                       m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
-                       usbd_copy_out(pc, 0, mtod(m, uint8_t *), actlen);
-                       m->m_pkthdr.len = m->m_len = actlen;
-                       /* Enqueue frame for further processing */
-                       _IF_ENQUEUE(&sc->sc_rxq, m);
-                       if (!callout_pending(&sc->sc_c) ||
-                           !callout_active(&sc->sc_c)) {
-                               callout_schedule(&sc->sc_c, 1);
-                       }
-               }
-       /* FALLTHROUGH */
-       case USB_ST_SETUP:
-tr_setup:
-               usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
-               usbd_transfer_submit(xfer);
-               break;
-       default:
-               UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
-               if (error == USB_ERR_CANCELLED)
-                       break;
-               usbd_xfer_set_stall(xfer);
-               goto tr_setup;
-       }
-}
-
-/*
- * Deferred RX processing, called with mutex locked.
- *
- * Each frame we receive might contain several small ip-packets as well
- * as partial ip-packets. We need to separate/assemble them into individual
- * packets before sending them to the ip-layer.
- */
-static void
-uhso_if_rxflush(void *arg)
-{
-       struct uhso_softc *sc = arg;
-       struct ifnet *ifp = sc->sc_ifp;
-       uint8_t *cp;
-       struct mbuf *m, *m0, *mwait;
-       struct ip *ip;
-#ifdef INET6
-       struct ip6_hdr *ip6;
-#endif
-       uint16_t iplen;
-       int len, isr;
-
-       m = NULL;
-       mwait = sc->sc_mwait;
-       for (;;) {
-               if (m == NULL) {
-                       _IF_DEQUEUE(&sc->sc_rxq, m);
-                       if (m == NULL)
-                               break;
-                       UHSO_DPRINTF(3, "dequeue m=%p, len=%d\n", m, m->m_len);
-               }
-               mtx_unlock(&sc->sc_mtx);
-
-               /* Do we have a partial packet waiting? */
-               if (mwait != NULL) {
-                       m0 = mwait;
-                       mwait = NULL;
-
-                       UHSO_DPRINTF(3, "partial m0=%p(%d), concat w/ m=%p(%d)\n",
-                           m0, m0->m_len, m, m->m_len);
-                       len = m->m_len + m0->m_len;
-
-                       /* Concat mbufs and fix headers */
-                       m_cat(m0, m);
-                       m0->m_pkthdr.len = len;
-                       m->m_flags &= ~M_PKTHDR;
-
-                       m = m_pullup(m0, sizeof(struct ip));
-                       if (m == NULL) {
-                               ifp->if_ierrors++;
-                               UHSO_DPRINTF(0, "m_pullup failed\n");
-                               mtx_lock(&sc->sc_mtx);
-                               continue;
-                       }
-                       UHSO_DPRINTF(3, "Constructed mbuf=%p, len=%d\n",
-                           m, m->m_pkthdr.len);
-               }
-
-               cp = mtod(m, uint8_t *);
-               ip = (struct ip *)cp;
-#ifdef INET6
-               ip6 = (struct ip6_hdr *)cp;
-#endif
-
-               /* Check for IPv4 */
-               if (ip->ip_v == IPVERSION) {
-                       iplen = htons(ip->ip_len);
-                       isr = NETISR_IP;
-               }
-#ifdef INET6
-               /* Check for IPv6 */
-               else if ((ip6->ip6_vfc & IPV6_VERSION_MASK) == IPV6_VERSION) {
-                       iplen = htons(ip6->ip6_plen);
-                       isr = NETISR_IPV6;
-               }
-#endif
-               else {
-                       UHSO_DPRINTF(0, "got unexpected ip version %d, "
-                           "m=%p, len=%d\n", (*cp & 0xf0) >> 4, m, m->m_len);
-                       ifp->if_ierrors++;
-                       UHSO_HEXDUMP(cp, 4);
-                       m_freem(m);
-                       m = NULL;
-                       mtx_lock(&sc->sc_mtx);
-                       continue;
-               }
-
-               if (iplen == 0) {
-                       UHSO_DPRINTF(0, "Zero IP length\n");
-                       ifp->if_ierrors++;
-                       m_freem(m);
-                       m = NULL;
-                       mtx_lock(&sc->sc_mtx);
-                       continue;
-               }
-
-               UHSO_DPRINTF(3, "m=%p, len=%d, cp=%p, iplen=%d\n",
-                   m, m->m_pkthdr.len, cp, iplen);
-
-               m0 = NULL;
-
-               /* More IP packets in this mbuf */
-               if (iplen < m->m_pkthdr.len) {
-                       m0 = m;
-
-                       /*
-                        * Allocate a new mbuf for this IP packet and
-                        * copy the IP-packet into it.
-                        */
-                       m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
-                       memcpy(mtod(m, uint8_t *), mtod(m0, uint8_t *), iplen);
-                       m->m_pkthdr.len = m->m_len = iplen;
-
-                       /* Adjust the size of the original mbuf */
-                       m_adj(m0, iplen);
-                       m0 = m_defrag(m0, M_WAIT);
-
-                       UHSO_DPRINTF(3, "New mbuf=%p, len=%d/%d, m0=%p, "
-                           "m0_len=%d/%d\n", m, m->m_pkthdr.len, m->m_len,
-                           m0, m0->m_pkthdr.len, m0->m_len);
-               }
-               else if (iplen > m->m_pkthdr.len) {
-                       UHSO_DPRINTF(3, "Deferred mbuf=%p, len=%d\n",
-                           m, m->m_pkthdr.len);
-                       mwait = m;
-                       m = NULL;
-                       mtx_lock(&sc->sc_mtx);
-                       continue;
-               }
-
-               ifp->if_ipackets++;
-               m->m_pkthdr.rcvif = ifp;
-
-               /* Dispatch to IP layer */
-               BPF_MTAP(sc->sc_ifp, m);
-               M_SETFIB(m, ifp->if_fib);
-               netisr_dispatch(isr, m);
-               m = m0 != NULL ? m0 : NULL;
-               mtx_lock(&sc->sc_mtx);
-       }
-       sc->sc_mwait = mwait;
-}
-
-static void
-uhso_ifnet_write_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-       struct uhso_softc *sc = usbd_xfer_softc(xfer);
-       struct ifnet *ifp = sc->sc_ifp;
-       struct usb_page_cache *pc;
-       struct mbuf *m;
-       int actlen;
-
-       usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-
-       UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
-
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               ifp->if_opackets++;
-               ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-       case USB_ST_SETUP:
-tr_setup:
-               IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
-               if (m == NULL)
-                       break;
-
-               ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-
-               if (m->m_pkthdr.len > MCLBYTES)
-                       m->m_pkthdr.len = MCLBYTES;
-
-               usbd_xfer_set_frame_len(xfer, 0, m->m_pkthdr.len);
-               pc = usbd_xfer_get_frame(xfer, 0);
-               usbd_m_copy_in(pc, 0, m, 0, m->m_pkthdr.len);
-               usbd_transfer_submit(xfer);
-
-               BPF_MTAP(ifp, m);
-               m_freem(m);
-               break;
-       default:
-               UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
-               if (error == USB_ERR_CANCELLED)
-                       break;
-               usbd_xfer_set_stall(xfer);
-               goto tr_setup;
-       }
-}
-
-static int
-uhso_if_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
-       struct uhso_softc *sc;
-
-       sc = ifp->if_softc;
-
-       switch (cmd) {
-       case SIOCSIFFLAGS:
-               if (ifp->if_flags & IFF_UP) {
-                       if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-                               uhso_if_init(sc);
-                       }
-               }
-               else {
-                       if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-                               mtx_lock(&sc->sc_mtx);
-                               uhso_if_stop(sc);
-                               mtx_unlock(&sc->sc_mtx);
-                       }
-               }
-               break;
-       case SIOCSIFADDR:
-       case SIOCSIFDSTADDR:
-       case SIOCADDMULTI:
-       case SIOCDELMULTI:
-               break;
-       default:
-               return (EINVAL);
-       }
-       return (0);
-}
-
-static void
-uhso_if_init(void *priv)
-{
-       struct uhso_softc *sc = priv;
-       struct ifnet *ifp = sc->sc_ifp;
-
-       mtx_lock(&sc->sc_mtx);
-       uhso_if_stop(sc);
-       ifp = sc->sc_ifp;
-       ifp->if_flags |= IFF_UP;
-       ifp->if_drv_flags |= IFF_DRV_RUNNING;
-       mtx_unlock(&sc->sc_mtx);
-
-       UHSO_DPRINTF(2, "ifnet initialized\n");
-}
-
-static int
-uhso_if_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst,
-    struct route *ro)
-{
-       int error;
-
-       /* Only IPv4/6 support */
-       if (dst->sa_family != AF_INET
-#ifdef INET6
-          && dst->sa_family != AF_INET6
-#endif
-        ) {
-               return (EAFNOSUPPORT);
-       }
-
-       error = (ifp->if_transmit)(ifp, m0);
-       if (error) {
-               ifp->if_oerrors++;
-               return (ENOBUFS);
-       }
-       ifp->if_opackets++;
-       return (0);
-}
-
-static void
-uhso_if_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
-{
-       struct uhso_softc *sc = ifp->if_softc;
-
-       ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq);
-
-       if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
-               UHSO_DPRINTF(1, "Not running\n");
-               return;
-       }
-
-       mtx_lock(&sc->sc_mtx);
-       usbd_transfer_start(sc->sc_if_xfer[UHSO_IFNET_READ]);
-       usbd_transfer_start(sc->sc_if_xfer[UHSO_IFNET_WRITE]);
-       mtx_unlock(&sc->sc_mtx);
-       UHSO_DPRINTF(3, "interface started\n");
-}
-
-static void
-uhso_if_stop(struct uhso_softc *sc)
-{
-
-       usbd_transfer_stop(sc->sc_if_xfer[UHSO_IFNET_READ]);
-       usbd_transfer_stop(sc->sc_if_xfer[UHSO_IFNET_WRITE]);
-       sc->sc_ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-}
index ccf8a32..63c4b68 100644 (file)
@@ -2,8 +2,6 @@
 
 KMOD=  usb
 
-# XXX usb_compat_linux.c
-
 SRCS=  bus_if.h device_if.h usb_if.h usb_if.c \
        opt_usb.h opt_ddb.h \
        usbdevs.h usbdevs_data.h \
diff --git a/sys/bus/u4b/usb_compat_linux.c b/sys/bus/u4b/usb_compat_linux.c
deleted file mode 100644 (file)
index 80bbac9..0000000
+++ /dev/null
@@ -1,1730 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2007 Luigi Rizzo - Universita` di Pisa. All rights reserved.
- * Copyright (c) 2007 Hans Petter Selasky. All rights reserved.
- *
- * 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 AUTHOR 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 AUTHOR 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)
-&n