Add u3g(4) driver from FreeBSD. This driver provides better support for
3G datacards than ugensa and will replace the latter for the supported devices.
This commit is contained in:
parent
4c43f08c6f
commit
db5825abd5
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.1103 2008/10/08 01:15:11 pgoyette Exp $
|
||||
# $NetBSD: mi,v 1.1104 2008/10/10 16:37:15 joerg Exp $
|
||||
#
|
||||
# Note: don't delete entries from here - mark them as "obsolete" instead.
|
||||
#
|
||||
|
@ -1504,6 +1504,7 @@
|
|||
./usr/share/man/cat4/twa.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/twe.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/txp.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/u3g.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/uaudio.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/uax.0 man-obsolete obsolete
|
||||
./usr/share/man/cat4/uberry.0 man-sys-catman .cat
|
||||
|
@ -3952,6 +3953,7 @@
|
|||
./usr/share/man/html4/twa.html man-sys-htmlman html
|
||||
./usr/share/man/html4/twe.html man-sys-htmlman html
|
||||
./usr/share/man/html4/txp.html man-sys-htmlman html
|
||||
./usr/share/man/html4/u3g.html man-sys-htmlman html
|
||||
./usr/share/man/html4/uaudio.html man-sys-htmlman html
|
||||
./usr/share/man/html4/uberry.html man-sys-htmlman html
|
||||
./usr/share/man/html4/ubsa.html man-sys-htmlman html
|
||||
|
@ -6326,6 +6328,7 @@
|
|||
./usr/share/man/man4/twa.4 man-sys-man .man
|
||||
./usr/share/man/man4/twe.4 man-sys-man .man
|
||||
./usr/share/man/man4/txp.4 man-sys-man .man
|
||||
./usr/share/man/man4/u3g.4 man-sys-man .man
|
||||
./usr/share/man/man4/uaudio.4 man-sys-man .man
|
||||
./usr/share/man/man4/uax.4 man-obsolete obsolete
|
||||
./usr/share/man/man4/uberry.4 man-sys-man .man
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.478 2008/10/08 01:15:11 pgoyette Exp $
|
||||
# $NetBSD: Makefile,v 1.479 2008/10/10 16:37:15 joerg Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/18/93
|
||||
|
||||
MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 acpidalb.4 \
|
||||
|
@ -62,7 +62,7 @@ MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 acpidalb.4 \
|
|||
zero.4 zstty.4 zyd.4
|
||||
|
||||
# USB devices
|
||||
MAN+= stuirda.4 uaudio.4 uberry.4 ubsa.4 ubt.4 uchcom.4 ucom.4 ucycom.4 \
|
||||
MAN+= stuirda.4 u3g.4 uaudio.4 uberry.4 ubsa.4 ubt.4 uchcom.4 ucom.4 ucycom.4 \
|
||||
udsbr.4 uftdi.4 ugen.4 ugensa.4 uhid.4 \
|
||||
uhidev.4 uhmodem.4 uipaq.4 uirda.4 ukbd.4 ukyopon.4 ulpt.4 \
|
||||
umass.4 umct.4 umidi.4 umodem.4 ums.4 uplcom.4 urio.4 usb.4 \
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
.\"
|
||||
.\" Copyright (c) 2008 AnyWi Technologies
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from uark.c
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.\" $NetBSD: u3g.4,v 1.1 2008/10/10 16:37:16 joerg Exp $
|
||||
.\"
|
||||
.Dd October 7, 2008
|
||||
.Dt U3G 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm u3g
|
||||
.Nd USB support for 3G datacards
|
||||
.Sh SYNOPSIS
|
||||
To compile this driver into the kernel,
|
||||
place the following lines in your
|
||||
kernel configuration file:
|
||||
.Bd -ragged -offset indent
|
||||
.Cd "device u3g"
|
||||
.Cd "device ucom"
|
||||
.Ed
|
||||
.Pp
|
||||
Alternatively, to load the driver as a
|
||||
module at boot time, place the following line in
|
||||
.Xr loader.conf 5 :
|
||||
.Bd -literal -offset indent
|
||||
u3g_load="YES"
|
||||
.Ed
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
driver provides support for the multiple USB-to-serial interfaces exposed by
|
||||
many 3G usb/pccard modems.
|
||||
.Pp
|
||||
The device is accessed through the
|
||||
.Xr ucom 4
|
||||
driver which makes it behave like a
|
||||
.Xr tty 4 .
|
||||
.Sh HARDWARE
|
||||
The
|
||||
.Nm
|
||||
driver supports the following adapters:
|
||||
.Pp
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
Option Globetrotter 3G Fusion (only 3G part, not WLAN)
|
||||
.It
|
||||
Option Globetrotter 3G Fusion Quad (only 3G part, not WLAN)
|
||||
.It
|
||||
Option Globetrotter 3G Quad
|
||||
.It
|
||||
Option Globetrotter 3G
|
||||
.It
|
||||
Vodafone Mobile Connect Card 3G
|
||||
.It
|
||||
Huawei E220 (E270?)
|
||||
.It
|
||||
Huawei Mobile
|
||||
.It
|
||||
Novatel MC950D
|
||||
.El
|
||||
.Pp
|
||||
The supported 3G cards provide the necessary modem port for ppp,
|
||||
pppd, or mpd connections as well as extra ports (depending on the specific
|
||||
device) to provide other functions (diagnostic port, SIM toolkit port)
|
||||
.Sh SEE ALSO
|
||||
.Xr tty 4 ,
|
||||
.Xr ucom 4 ,
|
||||
.Xr usb 4 ,
|
||||
.Xr ubsa 4
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
driver
|
||||
appeared in
|
||||
.Nx 5.0 .
|
||||
The
|
||||
.Xr ubsa 4
|
||||
manual page was modified for
|
||||
.Nm
|
||||
by
|
||||
.An Andrea Guzzo Aq aguzzo@anywi.com
|
||||
in September 2008.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
driver was written by
|
||||
.An Andrea Guzzo Aq aguzzo@anywi.com .
|
||||
Hardware for testing provided by AnyWi Technologies, Leiden, NL.
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.usb,v 1.89 2008/09/19 11:29:35 jmcneill Exp $
|
||||
# $NetBSD: files.usb,v 1.90 2008/10/10 16:37:16 joerg Exp $
|
||||
#
|
||||
# Config file and device description for machine-independent USB code.
|
||||
# Included by ports that need it. Ports that use it must provide
|
||||
|
@ -170,6 +170,11 @@ device ugensa: ucombus
|
|||
attach ugensa at usbdevif
|
||||
file dev/usb/ugensa.c ugensa
|
||||
|
||||
# Generic Serial Adapter
|
||||
device u3g: ucombus
|
||||
attach u3g at usbdevif
|
||||
file dev/usb/u3g.c u3g
|
||||
|
||||
# YAP phone firmware loader
|
||||
device uyap: ezload
|
||||
attach uyap at usbdevif
|
||||
|
|
|
@ -0,0 +1,330 @@
|
|||
/*
|
||||
* Copyright (c) 2008 AnyWi Technologies
|
||||
* Author: Andrea Guzzo <aguzzo@anywi.com>
|
||||
* * based on uark.c 1.1 2006/08/14 08:30:22 jsg *
|
||||
* * parts from ubsa.c 183348 2008-09-25 12:00:56Z phk *
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/ioccom.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/selinfo.h>
|
||||
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbdi.h>
|
||||
#include <dev/usb/usbdivar.h>
|
||||
#include <dev/usb/usbdi_util.h>
|
||||
|
||||
#include <dev/usb/ucomvar.h>
|
||||
|
||||
#include "usbdevs.h"
|
||||
|
||||
#define U3GBUFSZ 1024
|
||||
#define U3G_MAXPORTS 4
|
||||
|
||||
struct u3g_softc {
|
||||
device_t sc_ucom[U3G_MAXPORTS];;
|
||||
device_t sc_dev;
|
||||
usbd_device_handle sc_udev;
|
||||
u_char sc_msr;
|
||||
u_char sc_lsr;
|
||||
u_char numports;
|
||||
|
||||
usbd_interface_handle sc_intr_iface; /* interrupt interface */
|
||||
#ifdef U3G_DEBUG
|
||||
int sc_intr_number; /* interrupt number */
|
||||
usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */
|
||||
u_char *sc_intr_buf; /* interrupt buffer */
|
||||
#endif
|
||||
int sc_isize;
|
||||
};
|
||||
|
||||
struct ucom_methods u3g_methods = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct usb_devno u3g_devs[] = {
|
||||
/* OEM: Option N.V. */
|
||||
{ USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_QUADUMTS2 },
|
||||
{ USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_QUADUMTS },
|
||||
{ USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_QUADPLUSUMTS },
|
||||
{ USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_HSDPA },
|
||||
{ USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_VODAFONEMC3G },
|
||||
/* OEM: Huawei */
|
||||
{ USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE },
|
||||
{ USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E220 },
|
||||
/* OEM: Novatel */
|
||||
{ USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_MC950D },
|
||||
// { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_MC950D_DRIVER },
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
#ifdef U3G_DEBUG
|
||||
static void
|
||||
u3g_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
|
||||
{
|
||||
struct u3g_softc *sc = (struct u3g_softc *)priv;
|
||||
aprint_normal_dev(sc->sc_dev, "INTERRUPT CALLBACK\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
u3g_huawei_reinit(usbd_device_handle dev)
|
||||
{
|
||||
/* The Huawei device presents itself as a umass device with Windows
|
||||
* drivers on it. After installation of the driver, it reinits into a
|
||||
* 3G serial device.
|
||||
*/
|
||||
usb_device_request_t req;
|
||||
usb_config_descriptor_t *cdesc;
|
||||
|
||||
/* Get the config descriptor */
|
||||
cdesc = usbd_get_config_descriptor(dev);
|
||||
if (cdesc == NULL)
|
||||
return (UMATCH_NONE);
|
||||
|
||||
/* One iface means umass mode, more than 1 (4 usually) means 3G mode */
|
||||
if (cdesc->bNumInterface > 1)
|
||||
return (UMATCH_VENDOR_PRODUCT);
|
||||
|
||||
req.bmRequestType = UT_WRITE_DEVICE;
|
||||
req.bRequest = UR_SET_FEATURE;
|
||||
USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
|
||||
USETW(req.wIndex, UHF_PORT_SUSPEND);
|
||||
USETW(req.wLength, 0);
|
||||
|
||||
(void) usbd_do_request(dev, &req, 0);
|
||||
|
||||
return UMATCH_NONE; /* mismatch; it will be gone and reappear */
|
||||
}
|
||||
|
||||
static int
|
||||
u3g_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct usb_attach_arg *uaa = aux;
|
||||
|
||||
if (uaa->vendor == USB_VENDOR_HUAWEI)
|
||||
return u3g_huawei_reinit(uaa->device);
|
||||
|
||||
if (usb_lookup(u3g_devs, uaa->vendor, uaa->product))
|
||||
return UMATCH_VENDOR_PRODUCT;
|
||||
|
||||
return UMATCH_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
u3g_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct u3g_softc *sc = device_private(self);
|
||||
struct usb_attach_arg *uaa = aux;
|
||||
usbd_device_handle dev = uaa->device;
|
||||
usbd_interface_handle iface;
|
||||
usb_interface_descriptor_t *id;
|
||||
usb_endpoint_descriptor_t *ed;
|
||||
usbd_status error;
|
||||
int i, n;
|
||||
usb_config_descriptor_t *cdesc;
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal("\n");
|
||||
|
||||
sc->sc_dev = self;
|
||||
#ifdef U3G_DEBUG
|
||||
sc->sc_intr_number = -1;
|
||||
sc->sc_intr_pipe = NULL;
|
||||
#endif
|
||||
/* Move the device into the configured state. */
|
||||
error = usbd_set_config_index(dev, 0, 1);
|
||||
if (error) {
|
||||
aprint_error_dev(self, "failed to set configuration: %s\n",
|
||||
usbd_errstr(error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the config descriptor */
|
||||
cdesc = usbd_get_config_descriptor(dev);
|
||||
|
||||
if (cdesc == NULL) {
|
||||
aprint_error_dev(self, "failed to get configuration descriptor\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_udev = dev;
|
||||
sc->numports = (cdesc->bNumInterface <= U3G_MAXPORTS)?cdesc->bNumInterface:U3G_MAXPORTS;
|
||||
for ( i = 0; i < sc->numports; i++ ) {
|
||||
struct ucom_attach_args uca;
|
||||
|
||||
error = usbd_device2interface_handle(dev, i, &iface);
|
||||
if (error) {
|
||||
aprint_error_dev(self,
|
||||
"failed to get interface, err=%s\n",
|
||||
usbd_errstr(error));
|
||||
return;
|
||||
}
|
||||
id = usbd_get_interface_descriptor(iface);
|
||||
|
||||
uca.info = "Generic 3G Serial Device";
|
||||
uca.ibufsize = U3GBUFSZ;
|
||||
uca.obufsize = U3GBUFSZ;
|
||||
uca.ibufsizepad = U3GBUFSZ;
|
||||
uca.portno = i;
|
||||
uca.opkthdrlen = 0;
|
||||
uca.device = dev;
|
||||
uca.iface = iface;
|
||||
uca.methods = &u3g_methods;
|
||||
uca.arg = sc;
|
||||
|
||||
uca.bulkin = uca.bulkout = -1;
|
||||
for (n = 0; n < id->bNumEndpoints; n++) {
|
||||
ed = usbd_interface2endpoint_descriptor(iface, n);
|
||||
if (ed == NULL) {
|
||||
aprint_error_dev(self,
|
||||
"could not read endpoint descriptor\n");
|
||||
return;
|
||||
}
|
||||
if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
|
||||
UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
|
||||
uca.bulkin = ed->bEndpointAddress;
|
||||
else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
|
||||
UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
|
||||
uca.bulkout = ed->bEndpointAddress;
|
||||
}
|
||||
if (uca.bulkin == -1 || uca.bulkout == -1) {
|
||||
aprint_error_dev(self, "missing endpoint\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_ucom[i] = config_found_sm_loc(self, "ucombus", NULL, &uca,
|
||||
ucomprint, ucomsubmatch);
|
||||
}
|
||||
|
||||
#ifdef U3G_DEBUG
|
||||
if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
|
||||
sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
|
||||
error = usbd_open_pipe_intr(sc->sc_intr_iface,
|
||||
sc->sc_intr_number,
|
||||
USBD_SHORT_XFER_OK,
|
||||
&sc->sc_intr_pipe,
|
||||
sc,
|
||||
sc->sc_intr_buf,
|
||||
sc->sc_isize,
|
||||
u3g_intr,
|
||||
100);
|
||||
if (error) {
|
||||
aprint_error_dev(self,
|
||||
"cannot open interrupt pipe (addr %d)\n",
|
||||
sc->sc_intr_number);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (!pmf_device_register(self, NULL, NULL))
|
||||
aprint_error_dev(self, "couldn't establish power handler\n");
|
||||
}
|
||||
|
||||
static int
|
||||
u3g_detach(device_t self, int flags)
|
||||
{
|
||||
struct u3g_softc *sc = device_private(self);
|
||||
int rv = 0;
|
||||
int i;
|
||||
|
||||
pmf_device_deregister(self);
|
||||
|
||||
for (i = 0; i < sc->numports; i++) {
|
||||
if(sc->sc_ucom[i]) {
|
||||
rv = config_detach(sc->sc_ucom[i], flags);
|
||||
if(rv != 0) {
|
||||
aprint_verbose_dev(self, "Can't deallocat port %d", i);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef U3G_DEBUG
|
||||
if (sc->sc_intr_pipe != NULL) {
|
||||
int err = usbd_abort_pipe(sc->sc_intr_pipe);
|
||||
if (err)
|
||||
aprint_error_dev(self,
|
||||
"abort interrupt pipe failed: %s\n",
|
||||
usbd_errstr(err));
|
||||
err = usbd_close_pipe(sc->sc_intr_pipe);
|
||||
if (err)
|
||||
aprint_error_dev(self,
|
||||
"close interrupt pipe failed: %s\n",
|
||||
usbd_errstr(err));
|
||||
free(sc->sc_intr_buf, M_USBDEV);
|
||||
sc->sc_intr_pipe = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
u3g_childdet(device_t self, device_t child)
|
||||
{
|
||||
struct u3g_softc *sc = device_private(self);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sc->numports; i++) {
|
||||
if (sc->sc_ucom[i] == child)
|
||||
sc->sc_ucom[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
u3g_activate(device_t self, enum devact act)
|
||||
{
|
||||
struct u3g_softc *sc = device_private(self);
|
||||
int i, rv = 0;
|
||||
|
||||
switch (act) {
|
||||
case DVACT_ACTIVATE:
|
||||
return (EOPNOTSUPP);
|
||||
break;
|
||||
|
||||
case DVACT_DEACTIVATE:
|
||||
for (i = 0; i < sc->numports; i++) {
|
||||
if (sc->sc_ucom[i] && config_deactivate(sc->sc_ucom[i]))
|
||||
rv = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
CFATTACH_DECL2_NEW(u3g, sizeof(struct u3g_softc), u3g_match,
|
||||
u3g_attach, u3g_detach, u3g_activate, NULL, u3g_childdet);
|
Loading…
Reference in New Issue