From owner-freebsd-usb@FreeBSD.ORG Mon Jan 1 00:08:02 2007 Return-Path: X-Original-To: freebsd-usb@freebsd.org Delivered-To: freebsd-usb@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id A9A2816A403 for ; Mon, 1 Jan 2007 00:08:02 +0000 (UTC) (envelope-from nate@root.org) Received: from root.org (root.org [67.118.192.226]) by mx1.freebsd.org (Postfix) with ESMTP id 8FF7913C45E for ; Mon, 1 Jan 2007 00:08:02 +0000 (UTC) (envelope-from nate@root.org) Received: (qmail 63629 invoked from network); 31 Dec 2006 23:41:23 -0000 Received: from ppp-71-139-40-196.dsl.snfc21.pacbell.net (HELO ?10.0.5.59?) (nate-mail@71.139.40.196) by root.org with ESMTPA; 31 Dec 2006 23:41:23 -0000 Message-ID: <45984A97.3080201@root.org> Date: Sun, 31 Dec 2006 15:41:11 -0800 From: Nate Lawson User-Agent: Thunderbird 1.5.0.9 (Windows/20061207) MIME-Version: 1.0 To: Ivan Frosty References: <7fd638000612310125n672d11e9j6cfc20a080c443de@mail.gmail.com> In-Reply-To: <7fd638000612310125n672d11e9j6cfc20a080c443de@mail.gmail.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-scsi@freebsd.org, freebsd-usb@freebsd.org Subject: Re: problem with samsung flash X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Jan 2007 00:08:02 -0000 Ivan Frosty wrote: > hello there, i have freebsd 6.1 pentiumII 355mhz processor and 128mb > of ram. everytime i put my samsung 512mb in tha usb the machine doesnt > boot it halts where the error be at if i pull it out it > boots.........then if i put it back in i get an error.......whats with > umass? i basically installed everybit and software of the unix i have > so i dont know why i get the error anyhelp will be highly appreciated! > > this is the error: > > da0 at umass-sim0 bus0 target0wn0 > da0: Removable Direct Access SCSI-0 device > da0:1.000MB/s transfers > da0:511mb(1046720 512 byte sectors:64H 32s/T s11c) > umass0:phase Error, residue = 0 > (da0:umass-sim0:0:0:0):synchronize cache failed, status == 0x4,scsi > status == 0x0 opened disk da0->5! > > thank you for your time Hi, this is a common error and should be a FAQ somewhere. Some USB devices can't handle SYNC CACHE, the command that says to write their data out to storage. Most can or reject it with an error and continue. Some hang, including yours. You can add a SCSI quirk (no sync cache). See the entries at the beginning of scsi_da.c for an example how to do it. Your string would be "SAMSUNG", "flash Disk", "*". See if that helps. As far has fixing this problem permanently, does anyone have an idea on how the experimental work went with disabling sync cache if the INQ data indicates the device doesn't cache data (similar to Linux)? Also, what do the scsi@ guys think of me adding a tunable/sysctl that is unit-specific so people can disable it without a quirk? Example: dev.da.0.no_sync_cache="1". It would be off by default, of course. -- Nate From owner-freebsd-usb@FreeBSD.ORG Mon Jan 1 04:40:22 2007 Return-Path: X-Original-To: freebsd-usb@hub.freebsd.org Delivered-To: freebsd-usb@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id BAB9316A40F for ; Mon, 1 Jan 2007 04:40:22 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id 9763C13C44C for ; Mon, 1 Jan 2007 04:40:22 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l014eMCb015851 for ; Mon, 1 Jan 2007 04:40:22 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l014eMTv015850; Mon, 1 Jan 2007 04:40:22 GMT (envelope-from gnats) Resent-Date: Mon, 1 Jan 2007 04:40:22 GMT Resent-Message-Id: <200701010440.l014eMTv015850@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-usb@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Keith Jones Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 5651516A407 for ; Mon, 1 Jan 2007 04:39:08 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [69.147.83.33]) by mx1.freebsd.org (Postfix) with ESMTP id 43F9413C43E for ; Mon, 1 Jan 2007 04:39:08 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.13.1/8.13.1) with ESMTP id l014d831003231 for ; Mon, 1 Jan 2007 04:39:08 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.13.1/8.13.1/Submit) id l014d8E8003230; Mon, 1 Jan 2007 04:39:08 GMT (envelope-from nobody) Message-Id: <200701010439.l014d8E8003230@www.freebsd.org> Date: Mon, 1 Jan 2007 04:39:08 GMT From: Keith Jones To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.0 Cc: Subject: usb/107388: [PATCH] Add utoppy device from NetBSD X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Jan 2007 04:40:22 -0000 >Number: 107388 >Category: usb >Synopsis: [PATCH] Add utoppy device from NetBSD >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-usb >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Mon Jan 01 04:40:16 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Keith Jones >Release: 6.2-PRERELEASE >Organization: >Environment: FreeBSD beastie.local 6.2-PRERELEASE FreeBSD 6.2-PRERELEASE #4: Sun Dec 31 18:50:38 GMT 2006 root@beastie.local:/usr/obj/usr/src/sys/BEASTIE i386 >Description: The following diffs amount to a port to FreeBSD of Steve Woodford's utoppy(4) driver, originally written for NetBSD 4.0, for communication over USB with Topfield TF5000PVR and TF5800PVR digital video recorders. >How-To-Repeat: This device is not currently supported in FreeBSD-STABLE or -CURRENT. >Fix: Apply the following patch to the source tree (diff -Nru format). The patch was applied to -STABLE so there may be some minor differences with -CURRENT. Patch attached with submission follows: diff -Nru /usr/local/cvsup-stable/src/share/man/man4/Makefile /usr/src/share/man/man4/Makefile --- /usr/local/cvsup-stable/src/share/man/man4/Makefile Sat Dec 30 17:55:14 2006 +++ /usr/src/share/man/man4/Makefile Sun Dec 31 20:01:31 2006 @@ -370,6 +370,7 @@ usb.4 \ uscanner.4 \ utopia.4 \ + utoppy.4 \ uvisor.4 \ uvscom.4 \ vga.4 \ diff -Nru /usr/local/cvsup-stable/src/share/man/man4/utoppy.4 /usr/src/share/man/man4/utoppy.4 --- /usr/local/cvsup-stable/src/share/man/man4/utoppy.4 Thu Jan 1 01:00:00 1970 +++ /usr/src/share/man/man4/utoppy.4 Sun Dec 31 19:58:01 2006 @@ -0,0 +1,313 @@ +.\" $NetBSD: utoppy.4,v 1.3 2006/04/04 20:34:46 wiz Exp $ +.\" +.\" Copyright (c) 2006 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Steve C. Woodford. +.\" +.\" 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 the NetBSD +.\" Foundation, Inc. and its contributors. +.\" 4. Neither the name of The NetBSD Foundation 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 THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd April 3, 2006 +.Dt UTOPPY 4 +.Os +.Sh NAME +.Nm utoppy +.Nd USB driver for the Topfield TF5000PVR range of digital video recorders +.Sh SYNOPSIS +.Cd "utoppy* at uhub? port ?" +.Pp +.In dev/usb/utoppy.h +.Sh DESCRIPTION +The +.Nm +driver provides support for the Topfield TF5000PVR range of DVB recorders +(nicknamed +.Ql Toppy ) +which are popular in Europe and Australia. +These recorders have a +.Tn USB +device interface which can be used to transfer +recordings to and from the unit's hard disk. +The +.Tn USB +interface can also be used to upload binary images for execution +on the Toppy's MIPS cpu. +.Pp +The Toppy's +.Tn USB +protocol has not been officially documented by Topfield, +but the basic features have been reverse engineered by others in order +to write replacements for the official +.Ql Altair +download/upload program from Topfield. +.Pp +Existing replacements for Altair suffer from the fact that they are +ultimately built on top of +.Xr ugen 4 . +This has a number of detrimental side-effects: +.Bl -enum +.It +Performance suffers since all Toppy command packets have to cross the +user-kernel interface. +.It +The userland programs are full of clutter to deal with interpreting the +command/status packets, not to mention byte-swapping and host endian +issues. +.It +Signals can interrupt a data transfer at a critical point, leaving the +Toppy in an undefined state. +For example, interrupting a download with +.Ql Turbo +mode enabled will leave the Toppy completely unresponsive to the remote +control, and prevent timer-based recordings from starting. +.El +.Pp +The +.Nm +driver provides a clean and stable interface to the Toppy protocol, and +ensures that an interrupt caused by a signal does not leave the Toppy in +an undefined state. +.Sh UTOPPY INTERFACE +Use the following header file to get access to the +.Tn utoppy +specific structures and defines. +.Bd -literal +#include \*[Lt]dev/usb/utoppy.h\*[Gt] +.Ed +.Pp +The +.Nm +driver can be accessed through the +.Pa /dev/utoppyN +character device. +The primary means of controlling the driver is by issuing a series of +.Xr ioctl 2 +system calls followed by +.Xr read 2 +or +.Xr write 2 +system calls as appropriate. +.Pp +The following +.Xr ioctl 2 +commands are supported by the +.Nm +driver: +.Bl -tag -width xxxxxx +.It Dv UTOPPYIOTURBO Fa "int *mode" +This command can be used to enable or disable +.Ql Turbo +mode for subsequent +.Dv UTOPPYIOREADFILE +or +.Dv UTOPPYIOWRITEFILE +commands (see below). +If +.Fa num +is non-zero, Turbo mode will be enabled. +Otherwise Turbo mode will be disabled. +In non-Turbo mode, the Toppy's +.Tn USB +interface is capable of sustaining around 5.6 Mbit/s during a file transfer. +With Turbo mode enabled, it can sustain just over 16 Mbit/s. +Of course, these figures are valid only if the Toppy is connected via a +.Tn USB +2.0 interface. +Performance using an older +.Tn USB +1 interface will be significantly lower. +.It Dv UTOPPYIOCANCEL Fa void +This command can be used to abort an in-progress +.Dv UTOPPYIOREADDIR , +.Dv UTOPPYIOREADFILE , +or +.Dv UTOPPYIOWRITEFILE +command. +.It Dv UTOPPYIOREBOOT Fa void +This command will cause the Toppy to reboot cleanly. +.It Dv UTOPPYIOSTATS Fa "struct utoppy_stats *stats" +This command retrieves statistics for the Toppy's hard disk. +.Bd -literal +struct utoppy_stats { + uint64_t us_hdd_size; /* Size of the disk, in bytes */ + uint64_t us_hdd_free; /* Free space, in bytes */ +}; +.Ed +.It UTOPPYIORENAME Fa "struct utoppy_rename *rename" +This command is used to rename a file or directory on the Toppy's +hard disk. +The full pathname to each file must be provided. +.Bd -literal +struct utoppy_rename { + char *ur_old_path; /* Path to existing file */ + char *ur_new_path; /* Path to new file */ +}; +.Ed +.It UTOPPYIOMKDIR Fa "char *path" +This command creates the directory specified by +.Fa path . +.It UTOPPYIODELETE Fa "char *path" +This command deletes the file or directory specified by +.Fa path . +.It UTOPPYIOREADDIR Fa "char *path" +This command initiates a read of the contents of the directory specified by +.Fa path . +After issuing this command, the directory contents must be read using +consecutive +.Xr read 2 +system calls. +Each +.Xr read 2 +will transfer one or more directory entries into the user-supplied buffer. +The buffer must be large enough to receive at least one directory entry. +When +.Xr read 2 +returns zero, all directory entries have been read. +.Pp +A directory entry is described using the following data structure: +.Bd -literal +struct utoppy_dirent { + char ud_path[UTOPPY_MAX_FILENAME_LEN + 1]; + enum { + UTOPPY_DIRENT_UNKNOWN, + UTOPPY_DIRENT_DIRECTORY, + UTOPPY_DIRENT_FILE + } ud_type; + off_t ud_size; + time_t ud_mtime; + uint32_t ud_attributes; +}; +.Ed +.Pp +The +.Va ud_path +field contains the name of the directory entry. +.Pp +The +.Va ud_type +field specifies whether the entry corresponds to a file or a sub-directory. +.Pp +The +.Va ud_size +field is valid for files only, and specifies the file's size in bytes. +.Pp +The +.Va ud_mtime +field describes the file or directory's modification time, specified as +seconds from the Unix epoch. +The timestamp is relative to the current timezone, so +.Xr localtime 3 +can be used to convert it into human readable form. +Note that the Toppy sets directory timestamps to a predefined value so +they are not particularly useful. +.Pp +The +.Va ud_attributes +field is not used at this time. +.It UTOPPYIOREADFILE Fa "struct utoppy_readfile *" +This command is used to initiate reading a file from the Toppy's hard disk. +The full pathname, together with the file offset at which to start reading, +is specified using the following data structure: +.Bd -literal +struct utoppy_readfile { + char *ur_path; + off_t ur_offset; +}; +.Ed +.Pp +After issuing this command, the file must be read using consecutive +.Xr read 2 +system calls. +When +.Xr read 2 +returns zero, the entire file has been read. +.It UTOPPYIOWRITEFILE Fa "struct utoppy_writefile *" +This command is used to initiate writing to a file on the Toppy's hard disk. +The file to be written is described using the following data structure: +.Bd -literal +struct utoppy_writefile { + char *uw_path; + off_t uw_offset; + off_t uw_size; + time_t uw_mtime; +}; +.Ed +.Pp +The +.Va uw_path +field specifies the full pathname of the file to be written. +.Pp +The +.Va uw_offset +field specifies the file offset at which to start writing, assuming the file +already exists. +Otherwise, +.Va uw_offset +must be zero. +.Pp +The protocol requires that the Toppy must be informed of a file's size in +advance of the file being written. +This is accomplished using the +.Va uw_size +field. +It may be possible to work around this limitation in a future version of +the driver. +.Pp +The +.Va uw_mtime +field specifies the file's timestamp expressed as seconds from the Unix epoch +in the local timezone. +.El +.Pp +Due to limitations with the protocol, a +.Nm +device can be opened by only one application at a time. +Also, only a single +.Dv UTOPPYIOREADDIR , +.Dv UTOPPYIOREADFILE , +or +.Dv UTOPPYIOWRITEFILE +command can be in progress at any given time. +.Sh FILES +.Bl -tag -width /dev/utoppy0 -compact +.It Pa /dev/utoppy0 +device node +.El +.Sh SEE ALSO +.Xr utoppya 1 , +.Xr usb 4 +.Sh HISTORY +The +.Nm +driver +appeared in +.Nx 4.0 . +.Sh AUTHORS +.An Steve C. Woodford Aq scw@netbsd.org diff -Nru /usr/local/cvsup-stable/src/sys/conf/files /usr/src/sys/conf/files --- /usr/local/cvsup-stable/src/sys/conf/files Sat Dec 30 17:55:15 2006 +++ /usr/src/sys/conf/files Sun Dec 31 16:39:00 2006 @@ -1002,6 +1002,7 @@ dev/usb/usbdi.c optional usb dev/usb/usbdi_util.c optional usb dev/usb/uscanner.c optional uscanner +dev/usb/utoppy.c optional utoppy dev/usb/uvisor.c optional uvisor ucom dev/usb/uvscom.c optional uvscom ucom dev/utopia/idtphy.c optional utopia diff -Nru /usr/local/cvsup-stable/src/sys/dev/usb/usbdevs /usr/src/sys/dev/usb/usbdevs --- /usr/local/cvsup-stable/src/sys/dev/usb/usbdevs Sat Dec 30 17:55:15 2006 +++ /usr/src/sys/dev/usb/usbdevs Sun Dec 31 17:47:07 2006 @@ -500,6 +500,7 @@ vendor SERVERWORKS 0x1166 ServerWorks vendor ACERCM 0x1189 Acer Communications & Multimedia vendor SIERRA 0x1199 Sierra Wireless +vendor TOPFIELD 0x11db Topfield Co., Ltd vendor PROLIFIC2 0x11f6 Prolific vendor TWINMOS 0x126f TwinMOS vendor TSUNAMI 0x1241 Tsunami @@ -1627,6 +1628,9 @@ /* Thrustmaster products */ product THRUST FUSION_PAD 0xa0a3 Fusion Digital Gamepad + +/* Topfield Co., Ltd products */ +product TOPFIELD TF5000PVR 0x1000 TF5000PVR Digital Video Recorder /* Toshiba Corporation products */ product TOSHIBA POCKETPC_E740 0x0706 PocketPC e740 diff -Nru /usr/local/cvsup-stable/src/sys/dev/usb/utoppy.c /usr/src/sys/dev/usb/utoppy.c --- /usr/local/cvsup-stable/src/sys/dev/usb/utoppy.c Thu Jan 1 01:00:00 1970 +++ /usr/src/sys/dev/usb/utoppy.c Sun Dec 31 18:47:44 2006 @@ -0,0 +1,2029 @@ +/* $NetBSD: utoppy.c,v 1.8 2006/11/16 01:33:27 christos Exp $ */ + +/*- + * Copyright (c) 2006 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Steve C. Woodford. + * + * 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 the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#if defined(__NetBSD__) || defined(__OpenBSD__) +__KERNEL_RCSID(0, "$NetBSD: utoppy.c,v 1.8 2006/11/16 01:33:27 christos Exp $"); +#elif defined(__FreeBSD__) +__FBSDID("$FreeBSD$"); +#endif + +#include +#include +#include +#include +#include +#include +#if defined(__NetBSD__) || defined(__OpenBSD__) +#include +#include +#elif defined(__FreeBSD__) +#include +#include +#include +#include +#include +#endif +#if __FreeBSD_version >= 500014 +#include +#else +#include +#endif +#include +#include +#include + +#include +#include +#include +#if defined(__NetBSD__) || defined(__OpenBSD__) +#include +#elif defined(__FreeBSD__) +#include "usbdevs.h" +#endif +#include +#include + +#if defined(__FreeBSD__) && defined(USB_DEBUG) +#define UTOPPY_DEBUG +#else +#undef UTOPPY_DEBUG +#endif +#ifdef UTOPPY_DEBUG +#define UTOPPY_DBG_OPEN 0x0001 +#define UTOPPY_DBG_CLOSE 0x0002 +#define UTOPPY_DBG_READ 0x0004 +#define UTOPPY_DBG_WRITE 0x0008 +#define UTOPPY_DBG_IOCTL 0x0010 +#define UTOPPY_DBG_SEND_PACKET 0x0020 +#define UTOPPY_DBG_RECV_PACKET 0x0040 +#define UTOPPY_DBG_ADDPATH 0x0080 +#define UTOPPY_DBG_READDIR 0x0100 +#define UTOPPY_DBG_DUMP 0x0200 +#define DPRINTF(l, m) \ + do { \ + if (utoppy_debug & l) \ + printf m; \ + } while (/*CONSTCOND*/0) +static int utoppy_debug = 0; +static void utoppy_dump_packet(const void *, size_t); +#define DDUMP_PACKET(p, l) \ + do { \ + if (utoppy_debug & UTOPPY_DBG_DUMP) \ + utoppy_dump_packet((p), (l)); \ + } while (/*CONSTCOND*/0) +#else +#define DPRINTF(l, m) /* nothing */ +#define DDUMP_PACKET(p, l) /* nothing */ +#endif + + +#define UTOPPY_CONFIG_NO 1 +#define UTOPPY_NUMENDPOINTS 2 + +#define UTOPPY_BSIZE 0xffff +#define UTOPPY_FRAG_SIZE 0x1000 +#define UTOPPY_HEADER_SIZE 8 +#define UTOPPY_SHORT_TIMEOUT (500) /* 0.5 seconds */ +#define UTOPPY_LONG_TIMEOUT (10 * 1000) /* 10 seconds */ + +/* Protocol Commands and Responses */ +#define UTOPPY_RESP_ERROR 0x0001 +#define UTOPPY_CMD_ACK 0x0002 +#define UTOPPY_RESP_SUCCESS UTOPPY_CMD_ACK +#define UTOPPY_CMD_CANCEL 0x0003 +#define UTOPPY_CMD_READY 0x0100 +#define UTOPPY_CMD_RESET 0x0101 +#define UTOPPY_CMD_TURBO 0x0102 +#define UTOPPY_CMD_STATS 0x1000 +#define UTOPPY_RESP_STATS_DATA 0x1001 +#define UTOPPY_CMD_READDIR 0x1002 +#define UTOPPY_RESP_READDIR_DATA 0x1003 +#define UTOPPY_RESP_READDIR_END 0x1004 +#define UTOPPY_CMD_DELETE 0x1005 +#define UTOPPY_CMD_RENAME 0x1006 +#define UTOPPY_CMD_MKDIR 0x1007 +#define UTOPPY_CMD_FILE 0x1008 +#define UTOPPY_FILE_WRITE 0 +#define UTOPPY_FILE_READ 1 +#define UTOPPY_RESP_FILE_HEADER 0x1009 +#define UTOPPY_RESP_FILE_DATA 0x100a +#define UTOPPY_RESP_FILE_END 0x100b + +enum utoppy_state { + UTOPPY_STATE_CLOSED, + UTOPPY_STATE_OPENING, + UTOPPY_STATE_IDLE, + UTOPPY_STATE_READDIR, + UTOPPY_STATE_READFILE, + UTOPPY_STATE_WRITEFILE +}; + +struct utoppy_softc { + USBBASEDEVICE sc_dev; + usbd_device_handle sc_udev; /* device */ + usbd_interface_handle sc_iface; /* interface */ +#if defined(__FreeBSD__) + struct cdev *dev; +#endif + int sc_dying; + int sc_refcnt; + + enum utoppy_state sc_state; + u_int sc_turbo_mode; + + int sc_out; + usbd_pipe_handle sc_out_pipe; /* bulk out pipe */ + usbd_xfer_handle sc_out_xfer; + void *sc_out_buf; + void *sc_out_data; + uint64_t sc_wr_offset; + uint64_t sc_wr_size; + + int sc_in; + usbd_pipe_handle sc_in_pipe; /* bulk in pipe */ + usbd_xfer_handle sc_in_xfer; + void *sc_in_buf; + void *sc_in_data; + size_t sc_in_len; + u_int sc_in_offset; +}; + +struct utoppy_header { + uint16_t h_len; + uint16_t h_crc; + uint16_t h_cmd2; + uint16_t h_cmd; + uint8_t h_data[0]; +}; +#define UTOPPY_OUT_INIT(sc) \ + do { \ + struct utoppy_header *_h = sc->sc_out_data; \ + _h->h_len = 0; \ + } while (/*CONSTCOND*/0) + +#define UTOPPY_MJD_1970 40587u /* MJD value for Jan 1 00:00:00 1970 */ + +#define UTOPPY_FTYPE_DIR 1 +#define UTOPPY_FTYPE_FILE 2 + +#define UTOPPY_IN_DATA(sc) \ + ((void*)&(((uint8_t*)(sc)->sc_in_data)[(sc)->sc_in_offset+UTOPPY_HEADER_SIZE])) + +#if defined(__NetBSD__) +dev_type_open(utoppyopen); +dev_type_close(utoppyclose); +dev_type_read(utoppyread); +dev_type_write(utoppywrite); +dev_type_ioctl(utoppyioctl); + +const struct cdevsw utoppy_cdevsw = { + utoppyopen, utoppyclose, utoppyread, utoppywrite, utoppyioctl, + nostop, notty, nopoll, nommap, nokqfilter, D_OTHER, +}; +#elif defined(__OpenBSD__) +cdev_decl(utoppy); +#elif defined(__FreeBSD__) +d_open_t utoppyopen; +d_close_t utoppyclose; +d_write_t utoppywrite; +d_read_t utoppyread; +d_ioctl_t utoppyioctl; + +Static struct cdevsw utoppy_cdevsw = { + .d_version = D_VERSION, + .d_flags = D_NEEDGIANT, + .d_open = utoppyopen, + .d_close = utoppyclose, + .d_write = utoppywrite, + .d_read = utoppyread, + .d_ioctl = utoppyioctl, + .d_name = "utoppy", +#if __FreeBSD_version < 500014 + .d_bmaj = -1 +#endif +}; +#endif + +#define UTOPPYUNIT(n) (minor(n)) + +USB_DECLARE_DRIVER(utoppy); + +USB_MATCH(utoppy) +{ + USB_MATCH_START(utoppy, uaa); + + if (uaa->iface == NULL) + return (UMATCH_NONE); + + if (uaa->vendor == USB_VENDOR_TOPFIELD && + uaa->product == USB_PRODUCT_TOPFIELD_TF5000PVR) + return (UMATCH_VENDOR_PRODUCT); + + return (UMATCH_NONE); +} + +USB_ATTACH(utoppy) +{ + USB_ATTACH_START(utoppy, sc, uaa); + usbd_device_handle dev = uaa->device; + usb_endpoint_descriptor_t *ed; +#if defined(__NetBSD__) || defined(__OpenBSD__) + char *devinfo; +#elif defined(__FreeBSD__) + char devinfo[1024]; +#endif + u_int8_t epcount; + int i; + +#if defined(__NetBSD__) || defined(__OpenBSD__) + devinfo = usbd_devinfo_alloc(dev, 0); +#elif defined(__FreeBSD__) + usbd_devinfo(dev, 0, devinfo); +#endif + USB_ATTACH_SETUP; + printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo); +#if defined(__NetBSD__) || defined(__OpenBSD__) + usbd_devinfo_free(devinfo); +#endif + + sc->sc_dying = 0; + sc->sc_refcnt = 0; + sc->sc_udev = dev; + + epcount = 0; + (void) usbd_endpoint_count(uaa->iface, &epcount); + if (epcount != UTOPPY_NUMENDPOINTS) { + printf("%s: Expected %d endpoints, got %d\n", + USBDEVNAME(sc->sc_dev), UTOPPY_NUMENDPOINTS, epcount); + USB_ATTACH_ERROR_RETURN; + } + + sc->sc_in = -1; + sc->sc_out = -1; + + for (i = 0; i < epcount; i++) { + ed = usbd_interface2endpoint_descriptor(uaa->iface, i); + if (ed == NULL) { + printf("%s: couldn't get ep %d\n", + USBDEVNAME(sc->sc_dev), i); + USB_ATTACH_ERROR_RETURN; + } + + if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { + sc->sc_in = ed->bEndpointAddress; + } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { + sc->sc_out = ed->bEndpointAddress; + } + } + + if (sc->sc_out == -1 || sc->sc_in == -1) { + printf("%s: could not find bulk in/out endpoints\n", + USBDEVNAME(sc->sc_dev)); + sc->sc_dying = 1; + USB_ATTACH_ERROR_RETURN; + } + + sc->sc_iface = uaa->iface; + sc->sc_udev = dev; + + sc->sc_out_xfer = usbd_alloc_xfer(sc->sc_udev); + if (sc->sc_out_xfer == NULL) { + printf("%s: could not allocate bulk out xfer\n", + USBDEVNAME(sc->sc_dev)); + goto fail0; + } + + sc->sc_out_buf = usbd_alloc_buffer(sc->sc_out_xfer, UTOPPY_FRAG_SIZE); + if (sc->sc_out_buf == NULL) { + printf("%s: could not allocate bulk out buffer\n", + USBDEVNAME(sc->sc_dev)); + goto fail1; + } + + sc->sc_in_xfer = usbd_alloc_xfer(sc->sc_udev); + if (sc->sc_in_xfer == NULL) { + printf("%s: could not allocate bulk in xfer\n", + USBDEVNAME(sc->sc_dev)); + goto fail1; + } + + sc->sc_in_buf = usbd_alloc_buffer(sc->sc_in_xfer, UTOPPY_FRAG_SIZE); + if (sc->sc_in_buf == NULL) { + printf("%s: could not allocate bulk in buffer\n", + USBDEVNAME(sc->sc_dev)); + goto fail2; + } + +#if defined(__FreeBSD__) + sc->dev = make_dev(&utoppy_cdevsw, device_get_unit(self), + UID_ROOT, GID_OPERATOR, 0644, "utoppy%d", device_get_unit(self)); +#endif + + usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, + USBDEV(sc->sc_dev)); + + USB_ATTACH_SUCCESS_RETURN; + + fail2: usbd_free_xfer(sc->sc_in_xfer); + sc->sc_in_xfer = NULL; + + fail1: usbd_free_xfer(sc->sc_out_xfer); + sc->sc_out_xfer = NULL; + + fail0: sc->sc_dying = 1; + USB_ATTACH_ERROR_RETURN; +} + +#if defined(__NetBSD__) || defined(__OpenBSD__) +int +utoppy_activate(device_ptr_t self, enum devact act) +{ + struct utoppy_softc *sc = (struct utoppy_softc *)self; + + switch (act) { + case DVACT_ACTIVATE: + return (EOPNOTSUPP); + + case DVACT_DEACTIVATE: + sc->sc_dying = 1; + break; + } + return (0); +} +#endif + +USB_DETACH(utoppy) +{ + USB_DETACH_START(utoppy, sc); +#if defined(__NetBSD__) || defined(__OpenBSD__) + int maj, mn; +#endif + int s; + + sc->sc_dying = 1; + if (sc->sc_out_pipe != NULL) + usbd_abort_pipe(sc->sc_out_pipe); + if (sc->sc_in_pipe != NULL) + usbd_abort_pipe(sc->sc_in_pipe); + + if (sc->sc_in_xfer != NULL) + usbd_free_xfer(sc->sc_in_xfer); + if (sc->sc_out_xfer != NULL) + usbd_free_xfer(sc->sc_out_xfer); + + s = splusb(); + if (--sc->sc_refcnt >= 0) + usb_detach_wait(USBDEV(sc->sc_dev)); + splx(s); + +#if defined(__NetBSD__) || defined(__OpenBSD__) + /* locate the major number */ + maj = cdevsw_lookup_major(&utoppy_cdevsw); + + /* Nuke the vnodes for any open instances (calls close). */ + mn = self->dv_unit; + vdevgone(maj, mn, mn, VCHR); +#elif defined(__FreeBSD__) + destroy_dev(sc->dev); +#endif + + usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, + USBDEV(sc->sc_dev)); + + return (0); +} + +static const uint16_t utoppy_crc16_lookup[] = { + 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, + 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, + 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, + 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, + 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, + 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, + 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, + 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, + 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, + 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, + 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, + 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, + 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, + 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, + 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, + 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, + 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, + 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, + 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, + 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, + 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, + 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, + 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, + 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, + 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, + 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, + 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, + 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, + 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, + 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, + 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, + 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 +}; + +#define UTOPPY_CRC16(ccrc,b) \ + (utoppy_crc16_lookup[((ccrc) ^ (b)) & 0xffu] ^ ((ccrc) >> 8)) + +static const int utoppy_usbdstatus_lookup[] = { + 0, /* USBD_NORMAL_COMPLETION */ + EINPROGRESS, /* USBD_IN_PROGRESS */ + EALREADY, /* USBD_PENDING_REQUESTS */ + EAGAIN, /* USBD_NOT_STARTED */ + EINVAL, /* USBD_INVAL */ + ENOMEM, /* USBD_NOMEM */ + ECONNRESET, /* USBD_CANCELLED */ + EFAULT, /* USBD_BAD_ADDRESS */ + EBUSY, /* USBD_IN_USE */ + EADDRNOTAVAIL, /* USBD_NO_ADDR */ + ENETDOWN, /* USBD_SET_ADDR_FAILED */ + EIO, /* USBD_NO_POWER */ + EMLINK, /* USBD_TOO_DEEP */ + EIO, /* USBD_IOERROR */ + ENXIO, /* USBD_NOT_CONFIGURED */ + ETIMEDOUT, /* USBD_TIMEOUT */ + EBADMSG, /* USBD_SHORT_XFER */ + EHOSTDOWN, /* USBD_STALLED */ + EINTR /* USBD_INTERRUPTED */ +}; + +static __inline int +utoppy_usbd_status2errno(usbd_status err) +{ + + if (err >= USBD_ERROR_MAX) + return (EFAULT); + return (utoppy_usbdstatus_lookup[err]); +} + +#ifdef UTOPPY_DEBUG +static const char * +utoppy_state_string(enum utoppy_state state) +{ + const char *str; + + switch (state) { + case UTOPPY_STATE_CLOSED: + str = "CLOSED"; + break; + case UTOPPY_STATE_OPENING: + str = "OPENING"; + break; + case UTOPPY_STATE_IDLE: + str = "IDLE"; + break; + case UTOPPY_STATE_READDIR: + str = "READ DIRECTORY"; + break; + case UTOPPY_STATE_READFILE: + str = "READ FILE"; + break; + case UTOPPY_STATE_WRITEFILE: + str = "WRITE FILE"; + break; + default: + str = "INVALID!"; + break; + } + + return (str); +} + +static void +utoppy_dump_packet(const void *b, size_t len) +{ + const uint8_t *buf = b, *l; + uint8_t c; + size_t i, j; + + if (len == 0) + return; + + len = min(len, 256); + + printf("00: "); + + for (i = 0, l = buf; i < len; i++) { + printf("%02x ", *buf++); + + if ((i % 16) == 15) { + for (j = 0; j < 16; j++) { + c = *l++; + if (c < ' ' || c > 0x7e) + c = '.'; + printf("%c", c); + } + + printf("\n"); + l = buf; + + if ((i + 1) < len) + printf("%02x: ", (u_int)i + 1); + } + } + + while ((i++ % 16) != 0) + printf(" "); + + if (l < buf) { + while (l < buf) { + c = *l++; + if (c < ' ' || c > 0x7e) + c = '.'; + printf("%c", c); + } + + printf("\n"); + } +} +#endif + +/* + * Very much like usbd_bulk_transfer(), except don't catch signals + */ +static void +utoppy_bulk_transfer_cb(usbd_xfer_handle xfer, + usbd_private_handle priv, + usbd_status status) +{ + + wakeup(xfer); +} + +static usbd_status +utoppy_bulk_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe, + u_int16_t flags, u_int32_t timeout, void *buf, u_int32_t *size, + const char *lbl) +{ + usbd_status err; + int s, error; + + usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout, + utoppy_bulk_transfer_cb); + s = splusb(); + err = usbd_transfer(xfer); + if (err != USBD_IN_PROGRESS) { + splx(s); + return (err); + } + error = tsleep((caddr_t)xfer, PZERO, lbl, 0); + splx(s); + if (error) { + usbd_abort_pipe(pipe); + return (USBD_INTERRUPTED); + } + usbd_get_xfer_status(xfer, NULL, NULL, size, &err); + return (err); +} + +static int +utoppy_send_packet(struct utoppy_softc *sc, uint16_t cmd, uint32_t timeout) +{ + struct utoppy_header *h; + usbd_status err; + uint32_t len; + uint16_t dlen, crc; + uint8_t *data, *e, t1, t2; + + h = sc->sc_out_data; + + DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: cmd 0x%04x, " + "len %d\n", USBDEVNAME(sc->sc_dev), (u_int)cmd, h->h_len)); + + dlen = h->h_len; + len = dlen + UTOPPY_HEADER_SIZE; + + if (len & 1) + len++; + if ((len % 64) == 0) + len += 2; + + if (len >= UTOPPY_BSIZE) { + DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: " + "packet too big (%d)\n", USBDEVNAME(sc->sc_dev), (int)len)); + return (EINVAL); + } + + h->h_len = htole16(dlen + UTOPPY_HEADER_SIZE); + h->h_cmd2 = 0; + h->h_cmd = htole16(cmd); + + /* The command word is part of the CRC */ + crc = UTOPPY_CRC16(0, 0); + crc = UTOPPY_CRC16(crc, 0); + crc = UTOPPY_CRC16(crc, cmd >> 8); + crc = UTOPPY_CRC16(crc, cmd); + + /* + * If there is data following the header, calculate the CRC and + * byte-swap as we go. + */ + if (dlen) { + data = h->h_data; + e = data + (dlen & ~1); + + do { + t1 = data[0]; + t2 = data[1]; + crc = UTOPPY_CRC16(crc, t1); + crc = UTOPPY_CRC16(crc, t2); + *data++ = t2; + *data++ = t1; + } while (data < e); + + if (dlen & 1) { + t1 = data[0]; + crc = UTOPPY_CRC16(crc, t1); + data[1] = t1; + } + } + + h->h_crc = htole16(crc); + data = sc->sc_out_data; + + DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: total len " + "%d...\n", USBDEVNAME(sc->sc_dev), (int)len)); + DDUMP_PACKET(data, len); + + do { + uint32_t thislen; + + thislen = min(len, UTOPPY_FRAG_SIZE); + + memcpy(sc->sc_out_buf, data, thislen); + + err = utoppy_bulk_transfer(sc->sc_out_xfer, sc->sc_out_pipe, + USBD_NO_COPY, timeout, sc->sc_out_buf, &thislen, + "utoppytx"); + + if (thislen != min(len, UTOPPY_FRAG_SIZE)) { + DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: " + "utoppy_send_packet: sent %ld, err %d\n", + USBDEVNAME(sc->sc_dev), (u_long)thislen, err)); + } + + if (err == 0) { + len -= thislen; + data += thislen; + } + } while (err == 0 && len); + + DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: " + "usbd_bulk_transfer() returned %d.\n", USBDEVNAME(sc->sc_dev),err)); + + return (err ? utoppy_usbd_status2errno(err) : 0); +} + +static int +utoppy_recv_packet(struct utoppy_softc *sc, uint16_t *respp, uint32_t timeout) +{ + struct utoppy_header *h; + usbd_status err; + uint32_t len, thislen, requested, bytesleft; + uint16_t crc; + uint8_t *data, *e, t1, t2; + + data = sc->sc_in_data; + len = 0; + bytesleft = UTOPPY_BSIZE; + + DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: ...\n", + USBDEVNAME(sc->sc_dev))); + + do { + requested = thislen = min(bytesleft, UTOPPY_FRAG_SIZE); + + err = utoppy_bulk_transfer(sc->sc_in_xfer, sc->sc_in_pipe, + USBD_NO_COPY | USBD_SHORT_XFER_OK, timeout, sc->sc_in_buf, + &thislen, "utoppyrx"); + + DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: " + "usbd_bulk_transfer() returned %d, thislen %d, data %p\n", + USBDEVNAME(sc->sc_dev), err, (u_int)thislen, data)); + + if (err == 0) { + memcpy(data, sc->sc_in_buf, thislen); + DDUMP_PACKET(data, thislen); + len += thislen; + bytesleft -= thislen; + data += thislen; + } + } while (err == 0 && bytesleft && thislen == requested); + + if (err) + return (utoppy_usbd_status2errno(err)); + + h = sc->sc_in_data; + + DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: received %d " + "bytes in total to %p\n", USBDEVNAME(sc->sc_dev), (u_int)len, h)); + DDUMP_PACKET(h, len); + + if (len < UTOPPY_HEADER_SIZE || len < (uint32_t)le16toh(h->h_len)) { + DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: bad " + " length (len %d, h_len %d)\n", USBDEVNAME(sc->sc_dev), + (int)len, le16toh(h->h_len))); + return (EIO); + } + + len = h->h_len = le16toh(h->h_len); + h->h_crc = le16toh(h->h_crc); + *respp = h->h_cmd = le16toh(h->h_cmd); + h->h_cmd2 = le16toh(h->h_cmd2); + + /* + * To maximise data throughput when transferring files, acknowledge + * data blocks as soon as we receive them. If we detect an error + * later on, we can always cancel. + */ + if (*respp == UTOPPY_RESP_FILE_DATA) { + DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: " + "ACKing file data\n", USBDEVNAME(sc->sc_dev))); + + UTOPPY_OUT_INIT(sc); + err = utoppy_send_packet(sc, UTOPPY_CMD_ACK, + UTOPPY_SHORT_TIMEOUT); + if (err) { + DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: " + "utoppy_recv_packet: failed to ACK file data: %d\n", + USBDEVNAME(sc->sc_dev), err)); + return (err); + } + } + + /* The command word is part of the CRC */ + crc = UTOPPY_CRC16(0, h->h_cmd2 >> 8); + crc = UTOPPY_CRC16(crc, h->h_cmd2); + crc = UTOPPY_CRC16(crc, h->h_cmd >> 8); + crc = UTOPPY_CRC16(crc, h->h_cmd); + + /* + * Extract any payload, byte-swapping and calculating the CRC16 + * as we go. + */ + if (len > UTOPPY_HEADER_SIZE) { + data = h->h_data; + e = data + ((len & ~1) - UTOPPY_HEADER_SIZE); + + while (data < e) { + t1 = data[0]; + t2 = data[1]; + crc = UTOPPY_CRC16(crc, t2); + crc = UTOPPY_CRC16(crc, t1); + *data++ = t2; + *data++ = t1; + } + + if (len & 1) { + t1 = data[1]; + crc = UTOPPY_CRC16(crc, t1); + *data = t1; + } + } + + sc->sc_in_len = (size_t) len - UTOPPY_HEADER_SIZE; + sc->sc_in_offset = 0; + + DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: len %d, " + "crc 0x%04x, hdrcrc 0x%04x\n", USBDEVNAME(sc->sc_dev), + (int)len, crc, h->h_crc)); + DDUMP_PACKET(h, len); + + return ((crc == h->h_crc) ? 0 : EBADMSG); +} + +static __inline void * +utoppy_current_ptr(void *b) +{ + struct utoppy_header *h = b; + + return (&h->h_data[h->h_len]); +} + +static __inline void +utoppy_advance_ptr(void *b, size_t len) +{ + struct utoppy_header *h = b; + + h->h_len += len; +} + +static __inline void +utoppy_add_8(struct utoppy_softc *sc, uint8_t v) +{ + struct utoppy_header *h = sc->sc_out_data; + uint8_t *p; + + p = utoppy_current_ptr(h); + *p = v; + utoppy_advance_ptr(h, sizeof(v)); +} + +static __inline void +utoppy_add_16(struct utoppy_softc *sc, uint16_t v) +{ + struct utoppy_header *h = sc->sc_out_data; + uint8_t *p; + + p = utoppy_current_ptr(h); + *p++ = (uint8_t)(v >> 8); + *p = (uint8_t)v; + utoppy_advance_ptr(h, sizeof(v)); +} + +static __inline void +utoppy_add_32(struct utoppy_softc *sc, uint32_t v) +{ + struct utoppy_header *h = sc->sc_out_data; + uint8_t *p; + + p = utoppy_current_ptr(h); + *p++ = (uint8_t)(v >> 24); + *p++ = (uint8_t)(v >> 16); + *p++ = (uint8_t)(v >> 8); + *p = (uint8_t)v; + utoppy_advance_ptr(h, sizeof(v)); +} + +static __inline void +utoppy_add_64(struct utoppy_softc *sc, uint64_t v) +{ + struct utoppy_header *h = sc->sc_out_data; + uint8_t *p; + + p = utoppy_current_ptr(h); + *p++ = (uint8_t)(v >> 56); + *p++ = (uint8_t)(v >> 48); + *p++ = (uint8_t)(v >> 40); + *p++ = (uint8_t)(v >> 32); + *p++ = (uint8_t)(v >> 24); + *p++ = (uint8_t)(v >> 16); + *p++ = (uint8_t)(v >> 8); + *p = (uint8_t)v; + utoppy_advance_ptr(h, sizeof(v)); +} + +static __inline void +utoppy_add_string(struct utoppy_softc *sc, const char *str, size_t len) +{ + struct utoppy_header *h = sc->sc_out_data; + char *p; + + p = utoppy_current_ptr(h); + memset(p, 0, len); + strncpy(p, str, len); + utoppy_advance_ptr(h, len); +} + +static int +utoppy_add_path(struct utoppy_softc *sc, const char *path, int putlen) +{ + struct utoppy_header *h = sc->sc_out_data; + uint8_t *p, *str, *s; + size_t len; + int err; + + p = utoppy_current_ptr(h); + + str = putlen ? (p + sizeof(uint16_t)) : p; + + err = copyinstr(path, str, UTOPPY_MAX_FILENAME_LEN, &len); + + DPRINTF(UTOPPY_DBG_ADDPATH, ("utoppy_add_path: err %d, len %d\n", + err, (int)len)); + + if (err) + return (err); + + if (len < 2) + return (EINVAL); + + /* + * copyinstr(9) has already copied the terminating NUL character, + * but we append another one in case we have to pad the length + * later on. + */ + str[len] = '\0'; + + /* + * The Toppy uses backslash as the directory separator, so convert + * all forward slashes. + */ + for (s = &str[len - 2]; s >= str; s--) + if (*s == '/') + *s = '\\'; + + if ((len + h->h_len) & 1) + len++; + + if (putlen) + utoppy_add_16(sc, len); + + utoppy_advance_ptr(h, len); + + DPRINTF(UTOPPY_DBG_ADDPATH, ("utoppy_add_path: final len %d\n", + (u_int)len)); + + return (0); +} + +static __inline int +utoppy_get_8(struct utoppy_softc *sc, uint8_t *vp) +{ + uint8_t *p; + + if (sc->sc_in_len < sizeof(*vp)) + return (1); + + p = UTOPPY_IN_DATA(sc); + *vp = *p; + sc->sc_in_offset += sizeof(*vp); + sc->sc_in_len -= sizeof(*vp); + return (0); +} + +static __inline int +utoppy_get_16(struct utoppy_softc *sc, uint16_t *vp) +{ + uint16_t v; + uint8_t *p; + + if (sc->sc_in_len < sizeof(v)) + return (1); + + p = UTOPPY_IN_DATA(sc); + v = *p++; + v = (v << 8) | *p; + *vp = v; + sc->sc_in_offset += sizeof(v); + sc->sc_in_len -= sizeof(v); + return (0); +} + +static __inline int +utoppy_get_32(struct utoppy_softc *sc, uint32_t *vp) +{ + uint32_t v; + uint8_t *p; + + if (sc->sc_in_len < sizeof(v)) + return (1); + + p = UTOPPY_IN_DATA(sc); + v = *p++; + v = (v << 8) | *p++; + v = (v << 8) | *p++; + v = (v << 8) | *p; + *vp = v; + sc->sc_in_offset += sizeof(v); + sc->sc_in_len -= sizeof(v); + return (0); +} + +static __inline int +utoppy_get_64(struct utoppy_softc *sc, uint64_t *vp) +{ + uint64_t v; + uint8_t *p; + + if (sc->sc_in_len < sizeof(v)) + return (1); + + p = UTOPPY_IN_DATA(sc); + v = *p++; + v = (v << 8) | *p++; + v = (v << 8) | *p++; + v = (v << 8) | *p++; + v = (v << 8) | *p++; + v = (v << 8) | *p++; + v = (v << 8) | *p++; + v = (v << 8) | *p; + *vp = v; + sc->sc_in_offset += sizeof(v); + sc->sc_in_len -= sizeof(v); + return (0); +} + +static __inline int +utoppy_get_string(struct utoppy_softc *sc, char *str, size_t len) +{ + char *p; + + if (sc->sc_in_len < len) + return (1); + + memset(str, 0, len); + p = UTOPPY_IN_DATA(sc); + strncpy(str, p, len); + sc->sc_in_offset += len; + sc->sc_in_len -= len; + return (0); +} + +static int +utoppy_command(struct utoppy_softc *sc, uint16_t cmd, int timeout, + uint16_t *presp) +{ + int err; + + err = utoppy_send_packet(sc, cmd, timeout); + if (err) + return (err); + + err = utoppy_recv_packet(sc, presp, timeout); + if (err == EBADMSG) { + UTOPPY_OUT_INIT(sc); + utoppy_send_packet(sc, UTOPPY_RESP_ERROR, timeout); + } + + return (err); +} + +static int +utoppy_timestamp_decode(struct utoppy_softc *sc, time_t *tp) +{ + uint16_t mjd; + uint8_t hour, minute, sec; + uint32_t rv; + + if (utoppy_get_16(sc, &mjd) || utoppy_get_8(sc, &hour) || + utoppy_get_8(sc, &minute) || utoppy_get_8(sc, &sec)) + return (1); + + if (mjd == 0xffffu && hour == 0xffu && minute == 0xffu && sec == 0xffu){ + *tp = 0; + return (0); + } + + rv = (mjd < UTOPPY_MJD_1970) ? UTOPPY_MJD_1970 : (uint32_t) mjd; + + /* Calculate seconds since 1970 */ + rv = (rv - UTOPPY_MJD_1970) * 60 * 60 * 24; + + /* Add in the hours, minutes, and seconds */ + rv += (uint32_t)hour * 60 * 60; + rv += (uint32_t)minute * 60; + rv += sec; + *tp = (time_t)rv; + + return (0); +} + +static void +utoppy_timestamp_encode(struct utoppy_softc *sc, time_t t) +{ + u_int mjd, hour, minute; + + mjd = t / (60 * 60 * 24); + t -= mjd * 60 * 60 * 24; + + hour = t / (60 * 60); + t -= hour * 60 * 60; + + minute = t / 60; + t -= minute * 60; + + utoppy_add_16(sc, mjd + UTOPPY_MJD_1970); + utoppy_add_8(sc, hour); + utoppy_add_8(sc, minute); + utoppy_add_8(sc, t); +} + +static int +utoppy_turbo_mode(struct utoppy_softc *sc, int state) +{ + uint16_t r; + int err; + + UTOPPY_OUT_INIT(sc); + utoppy_add_32(sc, state); + + err = utoppy_command(sc, UTOPPY_CMD_TURBO, UTOPPY_SHORT_TIMEOUT, &r); + if (err) + return (err); + + return ((r == UTOPPY_RESP_SUCCESS) ? 0 : EIO); +} + +static int +utoppy_check_ready(struct utoppy_softc *sc) +{ + uint16_t r; + int err; + + UTOPPY_OUT_INIT(sc); + + err = utoppy_command(sc, UTOPPY_CMD_READY, UTOPPY_LONG_TIMEOUT, &r); + if (err) + return (err); + + return ((r == UTOPPY_RESP_SUCCESS) ? 0 : EIO); +} + +static int +utoppy_cancel(struct utoppy_softc *sc) +{ + uint16_t r; + int err, i; + + /* + * Issue the cancel command serveral times. the Toppy doesn't + * always respond to the first. + */ + for (i = 0; i < 3; i++) { + UTOPPY_OUT_INIT(sc); + err = utoppy_command(sc, UTOPPY_CMD_CANCEL, + UTOPPY_SHORT_TIMEOUT, &r); + if (err == 0 && r == UTOPPY_RESP_SUCCESS) + break; + err = ETIMEDOUT; + } + + if (err) + return (err); + + /* + * Make sure turbo mode is off, otherwise the Toppy will not + * respond to remote control input. + */ + (void) utoppy_turbo_mode(sc, 0); + + sc->sc_state = UTOPPY_STATE_IDLE; + return (0); +} + +static int +utoppy_stats(struct utoppy_softc *sc, struct utoppy_stats *us) +{ + uint32_t hsize, hfree; + uint16_t r; + int err; + + UTOPPY_OUT_INIT(sc); + err = utoppy_command(sc, UTOPPY_CMD_STATS, UTOPPY_LONG_TIMEOUT, &r); + if (err) + return (err); + + if (r != UTOPPY_RESP_STATS_DATA) + return (EIO); + + if (utoppy_get_32(sc, &hsize) || utoppy_get_32(sc, &hfree)) + return (EIO); + + us->us_hdd_size = hsize; + us->us_hdd_size *= 1024; + us->us_hdd_free = hfree; + us->us_hdd_free *= 1024; + + return (0); +} + +static int +utoppy_readdir_next(struct utoppy_softc *sc) +{ + uint16_t resp; + int err; + + DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: running...\n", + USBDEVNAME(sc->sc_dev))); + + /* + * Fetch the next READDIR response + */ + err = utoppy_recv_packet(sc, &resp, UTOPPY_LONG_TIMEOUT); + if (err) { + DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: " + "utoppy_recv_packet() returned %d\n", + USBDEVNAME(sc->sc_dev), err)); + if (err == EBADMSG) { + UTOPPY_OUT_INIT(sc); + utoppy_send_packet(sc, UTOPPY_RESP_ERROR, + UTOPPY_LONG_TIMEOUT); + } + utoppy_cancel(sc); + return (err); + } + + DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: " + "utoppy_recv_packet() returned %d, len %ld\n", + USBDEVNAME(sc->sc_dev), err, (u_long)sc->sc_in_len)); + + switch (resp) { + case UTOPPY_RESP_READDIR_DATA: + DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: " + "UTOPPY_RESP_READDIR_DATA\n", USBDEVNAME(sc->sc_dev))); + + UTOPPY_OUT_INIT(sc); + err = utoppy_send_packet(sc, UTOPPY_CMD_ACK, + UTOPPY_LONG_TIMEOUT); + if (err) { + DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: " + "utoppy_send_packet(ACK) returned %d\n", + USBDEVNAME(sc->sc_dev), err)); + utoppy_cancel(sc); + return (err); + } + sc->sc_state = UTOPPY_STATE_READDIR; + sc->sc_in_offset = 0; + break; + + case UTOPPY_RESP_READDIR_END: + DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: " + "UTOPPY_RESP_READDIR_END\n", USBDEVNAME(sc->sc_dev))); + + UTOPPY_OUT_INIT(sc); + utoppy_send_packet(sc, UTOPPY_CMD_ACK, UTOPPY_SHORT_TIMEOUT); + sc->sc_state = UTOPPY_STATE_IDLE; + sc->sc_in_len = 0; + break; + + default: + DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: " + "bad response: 0x%x\n", USBDEVNAME(sc->sc_dev), resp)); + sc->sc_state = UTOPPY_STATE_IDLE; + sc->sc_in_len = 0; + return (EIO); + } + + return (0); +} + +static size_t +utoppy_readdir_decode(struct utoppy_softc *sc, struct utoppy_dirent *ud) +{ + uint8_t ftype; + + DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_decode: bytes left" + " %d\n", USBDEVNAME(sc->sc_dev), (int)sc->sc_in_len)); + + if (utoppy_timestamp_decode(sc, &ud->ud_mtime) || + utoppy_get_8(sc, &ftype) || utoppy_get_64(sc, &ud->ud_size) || + utoppy_get_string(sc, ud->ud_path, UTOPPY_MAX_FILENAME_LEN + 1) || + utoppy_get_32(sc, &ud->ud_attributes)) { + DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_decode: no " + "more to decode\n", USBDEVNAME(sc->sc_dev))); + return (0); + } + + switch (ftype) { + case UTOPPY_FTYPE_DIR: + ud->ud_type = UTOPPY_DIRENT_DIRECTORY; + break; + case UTOPPY_FTYPE_FILE: + ud->ud_type = UTOPPY_DIRENT_FILE; + break; + default: + ud->ud_type = UTOPPY_DIRENT_UNKNOWN; + break; + } + + DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_decode: %s '%s', " + "size %lld, time 0x%08lx, attr 0x%08x\n", USBDEVNAME(sc->sc_dev), + (ftype == UTOPPY_FTYPE_DIR) ? "DIR" : + ((ftype == UTOPPY_FTYPE_FILE) ? "FILE" : "UNKNOWN"), ud->ud_path, + ud->ud_size, (u_long)ud->ud_mtime, ud->ud_attributes)); + + return (1); +} + +static int +utoppy_readfile_next(struct utoppy_softc *sc) +{ + uint64_t off; + uint16_t resp; + int err; + + err = utoppy_recv_packet(sc, &resp, UTOPPY_LONG_TIMEOUT); + if (err) { + DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: " + "utoppy_recv_packet() returned %d\n", + USBDEVNAME(sc->sc_dev), err)); + utoppy_cancel(sc); + return (err); + } + + switch (resp) { + case UTOPPY_RESP_FILE_HEADER: + /* ACK it */ + UTOPPY_OUT_INIT(sc); + err = utoppy_send_packet(sc, UTOPPY_CMD_ACK, + UTOPPY_LONG_TIMEOUT); + if (err) { + DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: " + "utoppy_send_packet(UTOPPY_CMD_ACK) returned %d\n", + USBDEVNAME(sc->sc_dev), err)); + utoppy_cancel(sc); + return (err); + } + + sc->sc_in_len = 0; + DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: " + "FILE_HEADER done\n", USBDEVNAME(sc->sc_dev))); + break; + + case UTOPPY_RESP_FILE_DATA: + /* Already ACK'd */ + if (utoppy_get_64(sc, &off)) { + DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: " + "UTOPPY_RESP_FILE_DATA did not provide offset\n", + USBDEVNAME(sc->sc_dev))); + utoppy_cancel(sc); + return (EBADMSG); + } + + DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: " + "UTOPPY_RESP_FILE_DATA: offset %lld, bytes left %ld\n", + USBDEVNAME(sc->sc_dev), off, (u_long)sc->sc_in_len)); + break; + + case UTOPPY_RESP_FILE_END: + DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: " + "UTOPPY_RESP_FILE_END: sending ACK\n", + USBDEVNAME(sc->sc_dev))); + UTOPPY_OUT_INIT(sc); + utoppy_send_packet(sc, UTOPPY_CMD_ACK, UTOPPY_SHORT_TIMEOUT); + /*FALLTHROUGH*/ + + case UTOPPY_RESP_SUCCESS: + sc->sc_state = UTOPPY_STATE_IDLE; + (void) utoppy_turbo_mode(sc, 0); + DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: all " + "done\n", USBDEVNAME(sc->sc_dev))); + break; + + case UTOPPY_RESP_ERROR: + default: + DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: bad " + "response code 0x%0x\n", USBDEVNAME(sc->sc_dev), resp)); + utoppy_cancel(sc); + return (EIO); + } + + return (0); +} + + +#if defined(__NetBSD__) || defined(__OpenBSD__) +int +utoppyopen(dev_t dev, int flag, int mode, + struct lwp *l) +#elif defined(__FreeBSD__) +int +utoppyopen(struct cdev *dev, int flag, int mode, usb_proc_ptr l) +#endif +{ + struct utoppy_softc *sc; + int error = 0; + + USB_GET_SC_OPEN(utoppy, UTOPPYUNIT(dev), sc); + + if (sc == NULL || sc->sc_iface == NULL || sc->sc_dying) + return (ENXIO); + + if (sc->sc_state != UTOPPY_STATE_CLOSED) { + DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: already open\n", + USBDEVNAME(sc->sc_dev))); + return (EBUSY); + } + + DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: opening...\n", + USBDEVNAME(sc->sc_dev))); + + sc->sc_refcnt++; + sc->sc_state = UTOPPY_STATE_OPENING; + sc->sc_turbo_mode = 0; + sc->sc_out_pipe = NULL; + sc->sc_in_pipe = NULL; + + if (usbd_open_pipe(sc->sc_iface, sc->sc_out, 0, &sc->sc_out_pipe)) { + DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: usbd_open_pipe(OUT) " + "failed\n", USBDEVNAME(sc->sc_dev))); + error = EIO; + goto done; + } + + if (usbd_open_pipe(sc->sc_iface, sc->sc_in, 0, &sc->sc_in_pipe)) { + DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: usbd_open_pipe(IN) " + "failed\n", USBDEVNAME(sc->sc_dev))); + error = EIO; + usbd_close_pipe(sc->sc_out_pipe); + sc->sc_out_pipe = NULL; + goto done; + } + + sc->sc_out_data = malloc(UTOPPY_BSIZE + 1, M_DEVBUF, M_WAITOK); + if (sc->sc_out_data == NULL) { + error = ENOMEM; + goto error; + } + + sc->sc_in_data = malloc(UTOPPY_BSIZE + 1, M_DEVBUF, M_WAITOK); + if (sc->sc_in_data == NULL) { + free(sc->sc_out_data, M_DEVBUF); + sc->sc_out_data = NULL; + error = ENOMEM; + goto error; + } + + if ((error = utoppy_cancel(sc)) != 0) + goto error; + + if ((error = utoppy_check_ready(sc)) != 0) { + DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: utoppy_check_ready()" + " returned %d\n", USBDEVNAME(sc->sc_dev), error)); + error: + usbd_abort_pipe(sc->sc_out_pipe); + usbd_close_pipe(sc->sc_out_pipe); + sc->sc_out_pipe = NULL; + usbd_abort_pipe(sc->sc_in_pipe); + usbd_close_pipe(sc->sc_in_pipe); + sc->sc_in_pipe = NULL; + } + + done: + sc->sc_state = error ? UTOPPY_STATE_CLOSED : UTOPPY_STATE_IDLE; + + DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: done. error %d, new state " + "'%s'\n", USBDEVNAME(sc->sc_dev), error, + utoppy_state_string(sc->sc_state))); + + if (--sc->sc_refcnt < 0) + usb_detach_wakeup(USBDEV(sc->sc_dev)); + + return (error); +} + +#if defined(__NetBSD__) || defined(__OpenBSD__) +int +utoppyclose(dev_t dev, int flag, int mode, + struct lwp *l) +#elif defined(__FreeBSD__) +int +utoppyclose(struct cdev *dev, int flag, int mode, usb_proc_ptr l) +#endif +{ + struct utoppy_softc *sc; + usbd_status err; + + USB_GET_SC(utoppy, UTOPPYUNIT(dev), sc); + + DPRINTF(UTOPPY_DBG_CLOSE, ("%s: utoppyclose: closing...\n", + USBDEVNAME(sc->sc_dev))); + + if (sc->sc_state < UTOPPY_STATE_IDLE) { + /* We are being forced to close before the open completed. */ + DPRINTF(UTOPPY_DBG_CLOSE, ("%s: utoppyclose: not properly open:" + " %s\n", USBDEVNAME(sc->sc_dev), + utoppy_state_string(sc->sc_state))); + return (0); + } + + if (sc->sc_out_data) + (void) utoppy_cancel(sc); + + if (sc->sc_out_pipe != NULL) { + if ((err = usbd_abort_pipe(sc->sc_out_pipe)) != 0) + printf("usbd_abort_pipe(OUT) returned %d\n", err); + if ((err = usbd_close_pipe(sc->sc_out_pipe)) != 0) + printf("usbd_close_pipe(OUT) returned %d\n", err); + sc->sc_out_pipe = NULL; + } + + if (sc->sc_in_pipe != NULL) { + if ((err = usbd_abort_pipe(sc->sc_in_pipe)) != 0) + printf("usbd_abort_pipe(IN) returned %d\n", err); + if ((err = usbd_close_pipe(sc->sc_in_pipe)) != 0) + printf("usbd_close_pipe(IN) returned %d\n", err); + sc->sc_in_pipe = NULL; + } + + if (sc->sc_out_data) { + free(sc->sc_out_data, M_DEVBUF); + sc->sc_out_data = NULL; + } + + if (sc->sc_in_data) { + free(sc->sc_in_data, M_DEVBUF); + sc->sc_in_data = NULL; + } + + sc->sc_state = UTOPPY_STATE_CLOSED; + + DPRINTF(UTOPPY_DBG_CLOSE, ("%s: utoppyclose: done.\n", + USBDEVNAME(sc->sc_dev))); + + return (0); +} + +#if defined(__NetBSD__) || defined(__OpenBSD__) +int +utoppyread(dev_t dev, struct uio *uio, int flags) +#elif defined(__FreeBSD__) +int +utoppyread(struct cdev *dev, struct uio *uio, int flags) +#endif +{ + struct utoppy_softc *sc; + struct utoppy_dirent ud; + size_t len; + int err; + + USB_GET_SC(utoppy, UTOPPYUNIT(dev), sc); + + if (sc->sc_dying) + return (EIO); + + sc->sc_refcnt++; + + DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: reading: state '%s'\n", + USBDEVNAME(sc->sc_dev), utoppy_state_string(sc->sc_state))); + + switch (sc->sc_state) { + case UTOPPY_STATE_READDIR: + err = 0; + while (err == 0 && uio->uio_resid >= sizeof(ud) && + sc->sc_state != UTOPPY_STATE_IDLE) { + if (utoppy_readdir_decode(sc, &ud) == 0) + err = utoppy_readdir_next(sc); + else + if ((err = uiomove(&ud, sizeof(ud), uio)) != 0) + utoppy_cancel(sc); + } + break; + + case UTOPPY_STATE_READFILE: + err = 0; + while (err == 0 && uio->uio_resid > 0 && + sc->sc_state != UTOPPY_STATE_IDLE) { + DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: READFILE: " + "resid %ld, bytes_left %ld\n", + USBDEVNAME(sc->sc_dev), (u_long)uio->uio_resid, + (u_long)sc->sc_in_len)); + + if (sc->sc_in_len == 0 && + (err = utoppy_readfile_next(sc)) != 0) { + DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: " + "READFILE: utoppy_readfile_next returned " + "%d\n", USBDEVNAME(sc->sc_dev), err)); + break; + } + + len = min(uio->uio_resid, sc->sc_in_len); + if (len) { + err = uiomove(UTOPPY_IN_DATA(sc), len, uio); + if (err == 0) { + sc->sc_in_offset += len; + sc->sc_in_len -= len; + } + } + } + break; + + case UTOPPY_STATE_IDLE: + err = 0; + break; + + case UTOPPY_STATE_WRITEFILE: + err = EBUSY; + break; + + default: + err = EIO; + break; + } + + DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: done. err %d, state '%s'\n", + USBDEVNAME(sc->sc_dev), err, utoppy_state_string(sc->sc_state))); + + if (--sc->sc_refcnt < 0) + usb_detach_wakeup(USBDEV(sc->sc_dev)); + + return (err); +} + +#if defined(__NetBSD__) || defined(__OpenBSD__) +int +utoppywrite(dev_t dev, struct uio *uio, int flags) +#elif defined(__FreeBSD__) +int +utoppywrite(struct cdev *dev, struct uio *uio, int flags) +#endif +{ + struct utoppy_softc *sc; + uint16_t resp; + size_t len; + int err; + + USB_GET_SC(utoppy, UTOPPYUNIT(dev), sc); + + if (sc->sc_dying) + return (EIO); + + switch(sc->sc_state) { + case UTOPPY_STATE_WRITEFILE: + break; + + case UTOPPY_STATE_IDLE: + return (0); + + default: + return (EIO); + } + + sc->sc_refcnt++; + err = 0; + + DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: PRE-WRITEFILE: resid %ld, " + "wr_size %lld, wr_offset %lld\n", USBDEVNAME(sc->sc_dev), + (u_long)uio->uio_resid, sc->sc_wr_size, sc->sc_wr_offset)); + + while (sc->sc_state == UTOPPY_STATE_WRITEFILE && + (len = min(uio->uio_resid, sc->sc_wr_size)) != 0) { + + len = min(len, UTOPPY_BSIZE - (UTOPPY_HEADER_SIZE + + sizeof(uint64_t) + 3)); + + DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: uiomove(%ld)\n", + USBDEVNAME(sc->sc_dev), (u_long)len)); + + UTOPPY_OUT_INIT(sc); + utoppy_add_64(sc, sc->sc_wr_offset); + + err = uiomove(utoppy_current_ptr(sc->sc_out_data), len, uio); + if (err) { + DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: uiomove() " + "returned %d\n", USBDEVNAME(sc->sc_dev), err)); + break; + } + + utoppy_advance_ptr(sc->sc_out_data, len); + + err = utoppy_command(sc, UTOPPY_RESP_FILE_DATA, + UTOPPY_LONG_TIMEOUT, &resp); + if (err) { + DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: " + "utoppy_command(UTOPPY_RESP_FILE_DATA) " + "returned %d\n", USBDEVNAME(sc->sc_dev), err)); + break; + } + if (resp != UTOPPY_RESP_SUCCESS) { + DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: " + "utoppy_command(UTOPPY_RESP_FILE_DATA) returned " + "bad response 0x%x\n", USBDEVNAME(sc->sc_dev), + resp)); + utoppy_cancel(sc); + err = EIO; + break; + } + + sc->sc_wr_offset += len; + sc->sc_wr_size -= len; + } + + DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: POST-WRITEFILE: resid %ld," + " wr_size %lld, wr_offset %lld, err %d\n", USBDEVNAME(sc->sc_dev), + (u_long)uio->uio_resid, sc->sc_wr_size, sc->sc_wr_offset, err)); + + if (err == 0 && sc->sc_wr_size == 0) { + DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: sending " + "FILE_END...\n", USBDEVNAME(sc->sc_dev))); + UTOPPY_OUT_INIT(sc); + err = utoppy_command(sc, UTOPPY_RESP_FILE_END, + UTOPPY_LONG_TIMEOUT, &resp); + if (err) { + DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: " + "utoppy_command(UTOPPY_RESP_FILE_END) returned " + "%d\n", USBDEVNAME(sc->sc_dev), err)); + + utoppy_cancel(sc); + } + + sc->sc_state = UTOPPY_STATE_IDLE; + DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: state %s\n", + USBDEVNAME(sc->sc_dev), utoppy_state_string(sc->sc_state))); + } + + if (--sc->sc_refcnt < 0) + usb_detach_wakeup(USBDEV(sc->sc_dev)); + + return (err); +} + +#if defined(__NetBSD__) || defined(__OpenBSD__) +int +utoppyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, + struct lwp *l) +#elif defined(__FreeBSD__) +int +utoppyioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, + usb_proc_ptr l) +#endif +{ + struct utoppy_softc *sc; + struct utoppy_rename *ur; + struct utoppy_readfile *urf; + struct utoppy_writefile *uw; + char uwf[UTOPPY_MAX_FILENAME_LEN + 1], *uwfp; + uint16_t resp; + int err; + + USB_GET_SC(utoppy, UTOPPYUNIT(dev), sc); + + if (sc->sc_dying) + return (EIO); + + DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: cmd 0x%08lx, state '%s'\n", + USBDEVNAME(sc->sc_dev), cmd, utoppy_state_string(sc->sc_state))); + + if (sc->sc_state != UTOPPY_STATE_IDLE && cmd != UTOPPYIOCANCEL) { + DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: still busy.\n", + USBDEVNAME(sc->sc_dev))); + return (EBUSY); + } + + sc->sc_refcnt++; + + switch (cmd) { + case UTOPPYIOTURBO: + err = 0; + sc->sc_turbo_mode = *((int *)data) ? 1 : 0; + DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOTURBO: " + "%s\n", USBDEVNAME(sc->sc_dev), sc->sc_turbo_mode ? "On" : + "Off")); + break; + + case UTOPPYIOCANCEL: + DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOCANCEL\n", + USBDEVNAME(sc->sc_dev))); + err = utoppy_cancel(sc); + break; + + case UTOPPYIOREBOOT: + DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOREBOOT\n", + USBDEVNAME(sc->sc_dev))); + UTOPPY_OUT_INIT(sc); + err = utoppy_command(sc, UTOPPY_CMD_RESET, UTOPPY_LONG_TIMEOUT, + &resp); + if (err) + break; + + if (resp != UTOPPY_RESP_SUCCESS) + err = EIO; + break; + + case UTOPPYIOSTATS: + DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOSTATS\n", + USBDEVNAME(sc->sc_dev))); + err = utoppy_stats(sc, (struct utoppy_stats *)data); + break; + + case UTOPPYIORENAME: + DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIORENAME\n", + USBDEVNAME(sc->sc_dev))); + ur = (struct utoppy_rename *)data; + UTOPPY_OUT_INIT(sc); + + if ((err = utoppy_add_path(sc, ur->ur_old_path, 1)) != 0) + break; + if ((err = utoppy_add_path(sc, ur->ur_new_path, 1)) != 0) + break; + + err = utoppy_command(sc, UTOPPY_CMD_RENAME, UTOPPY_LONG_TIMEOUT, + &resp); + if (err) + break; + + if (resp != UTOPPY_RESP_SUCCESS) + err = EIO; + break; + + case UTOPPYIOMKDIR: + DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOMKDIR\n", + USBDEVNAME(sc->sc_dev))); + UTOPPY_OUT_INIT(sc); + err = utoppy_add_path(sc, *((const char **)data), 1); + if (err) + break; + + err = utoppy_command(sc, UTOPPY_CMD_MKDIR, UTOPPY_LONG_TIMEOUT, + &resp); + if (err) + break; + + if (resp != UTOPPY_RESP_SUCCESS) + err = EIO; + break; + + case UTOPPYIODELETE: + DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIODELETE\n", + USBDEVNAME(sc->sc_dev))); + UTOPPY_OUT_INIT(sc); + err = utoppy_add_path(sc, *((const char **)data), 0); + if (err) + break; + + err = utoppy_command(sc, UTOPPY_CMD_DELETE, UTOPPY_LONG_TIMEOUT, + &resp); + if (err) + break; + + if (resp != UTOPPY_RESP_SUCCESS) + err = EIO; + break; + + case UTOPPYIOREADDIR: + DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOREADDIR\n", + USBDEVNAME(sc->sc_dev))); + UTOPPY_OUT_INIT(sc); + err = utoppy_add_path(sc, *((const char **)data), 0); + if (err) { + DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppyioctl: " + "utoppy_add_path() returned %d\n", + USBDEVNAME(sc->sc_dev), err)); + break; + } + + err = utoppy_send_packet(sc, UTOPPY_CMD_READDIR, + UTOPPY_LONG_TIMEOUT); + if (err != 0) { + DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppyioctl: " + "UTOPPY_CMD_READDIR returned %d\n", + USBDEVNAME(sc->sc_dev), err)); + break; + } + + err = utoppy_readdir_next(sc); + if (err) { + DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppyioctl: " + "utoppy_readdir_next() returned %d\n", + USBDEVNAME(sc->sc_dev), err)); + } + break; + + case UTOPPYIOREADFILE: + urf = (struct utoppy_readfile *)data; + + DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: UTOPPYIOREADFILE " + "%s, offset %lld\n", USBDEVNAME(sc->sc_dev), urf->ur_path, + urf->ur_offset)); + + if ((err = utoppy_turbo_mode(sc, sc->sc_turbo_mode)) != 0) + break; + + UTOPPY_OUT_INIT(sc); + utoppy_add_8(sc, UTOPPY_FILE_READ); + + if ((err = utoppy_add_path(sc, urf->ur_path, 1)) != 0) + break; + + utoppy_add_64(sc, urf->ur_offset); + + sc->sc_state = UTOPPY_STATE_READFILE; + sc->sc_in_offset = 0; + + err = utoppy_send_packet(sc, UTOPPY_CMD_FILE, + UTOPPY_LONG_TIMEOUT); + if (err == 0) + err = utoppy_readfile_next(sc); + break; + + case UTOPPYIOWRITEFILE: + uw = (struct utoppy_writefile *)data; + + DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: UTOPPYIOWRITEFILE " + "%s, size %lld, offset %lld\n", USBDEVNAME(sc->sc_dev), + uw->uw_path, uw->uw_size, uw->uw_offset)); + + if ((err = utoppy_turbo_mode(sc, sc->sc_turbo_mode)) != 0) + break; + + UTOPPY_OUT_INIT(sc); + utoppy_add_8(sc, UTOPPY_FILE_WRITE); + uwfp = utoppy_current_ptr(sc->sc_out_data); + + if ((err = utoppy_add_path(sc, uw->uw_path, 1)) != 0) { + DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: add_path() " + "returned %d\n", USBDEVNAME(sc->sc_dev), err)); + break; + } + + strncpy(uwf, &uwfp[2], sizeof(uwf)); + utoppy_add_64(sc, uw->uw_offset); + + err = utoppy_command(sc, UTOPPY_CMD_FILE, UTOPPY_LONG_TIMEOUT, + &resp); + if (err) { + DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: " + "utoppy_command(UTOPPY_CMD_FILE) returned " + "%d\n", USBDEVNAME(sc->sc_dev), err)); + break; + } + if (resp != UTOPPY_RESP_SUCCESS) { + DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: " + "utoppy_command(UTOPPY_CMD_FILE) returned " + "bad response 0x%x\n", USBDEVNAME(sc->sc_dev), + resp)); + err = EIO; + break; + } + + UTOPPY_OUT_INIT(sc); + utoppy_timestamp_encode(sc, uw->uw_mtime); + utoppy_add_8(sc, UTOPPY_FTYPE_FILE); + utoppy_add_64(sc, uw->uw_size); + utoppy_add_string(sc, uwf, sizeof(uwf)); + utoppy_add_32(sc, 0); + + err = utoppy_command(sc, UTOPPY_RESP_FILE_HEADER, + UTOPPY_LONG_TIMEOUT, &resp); + if (err) { + DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: " + "utoppy_command(UTOPPY_RESP_FILE_HEADER) " + "returned %d\n", USBDEVNAME(sc->sc_dev), err)); + break; + } + if (resp != UTOPPY_RESP_SUCCESS) { + DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: " + "utoppy_command(UTOPPY_RESP_FILE_HEADER) " + "returned bad response 0x%x\n", + USBDEVNAME(sc->sc_dev), resp)); + err = EIO; + break; + } + + sc->sc_wr_offset = uw->uw_offset; + sc->sc_wr_size = uw->uw_size; + sc->sc_state = UTOPPY_STATE_WRITEFILE; + + DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: Changing state to " + "%s. wr_offset %lld, wr_size %lld\n", + USBDEVNAME(sc->sc_dev), utoppy_state_string(sc->sc_state), + sc->sc_wr_offset, sc->sc_wr_size)); + break; + + default: + DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: Invalid cmd\n", + USBDEVNAME(sc->sc_dev))); + err = ENODEV; + break; + } + + DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: done. err %d, state '%s'\n", + USBDEVNAME(sc->sc_dev), err, utoppy_state_string(sc->sc_state))); + + if (err) + utoppy_cancel(sc); + + if (--sc->sc_refcnt < 0) + usb_detach_wakeup(USBDEV(sc->sc_dev)); + + return (err); +} + +#if defined(__FreeBSD__) +DRIVER_MODULE(utoppy, uhub, utoppy_driver, utoppy_devclass, usbd_driver_load, 0); +#endif diff -Nru /usr/local/cvsup-stable/src/sys/dev/usb/utoppy.h /usr/src/sys/dev/usb/utoppy.h --- /usr/local/cvsup-stable/src/sys/dev/usb/utoppy.h Thu Jan 1 01:00:00 1970 +++ /usr/src/sys/dev/usb/utoppy.h Mon Apr 3 08:15:00 2006 @@ -0,0 +1,106 @@ +/* $NetBSD: utoppy.h,v 1.1 2006/04/03 08:15:48 scw Exp $ */ + +/*- + * Copyright (c) 2006 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Steve C. Woodford. + * + * 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 the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _DEV_USB_UTOPPY_H_ +#define _DEV_USB_UTOPPY_H_ + +#include + +#define UTOPPY_MAX_FILENAME_LEN 95 +#define UTOPPY_MAX_PATHNAME_LEN ((UTOPPY_MAX_FILENAME_LEN + 1) * 6) + +/* Set/clear turbo mode */ +#define UTOPPYIOTURBO _IOW('t', 1, int) + +/* Cancel previous op */ +#define UTOPPYIOCANCEL _IO('t', 2) + +/* Reboot the toppy */ +#define UTOPPYIOREBOOT _IO('t', 3) + +/* Get status of Toppy's hard disk drive */ +#define UTOPPYIOSTATS _IOR('t', 4, struct utoppy_stats) +struct utoppy_stats { + uint64_t us_hdd_size; + uint64_t us_hdd_free; +}; + +/* Rename a file/directory */ +#define UTOPPYIORENAME _IOW('t', 5, struct utoppy_rename) +struct utoppy_rename { + char *ur_old_path; + char *ur_new_path; +}; + +/* Create a directory */ +#define UTOPPYIOMKDIR _IOW('t', 6, char *) + +/* Delete a file/directory */ +#define UTOPPYIODELETE _IOW('t', 7, char *) + +/* Initiate reading of the contents of a directory */ +#define UTOPPYIOREADDIR _IOW('t', 8, char *) +struct utoppy_dirent { + char ud_path[UTOPPY_MAX_FILENAME_LEN + 1]; + enum { + UTOPPY_DIRENT_UNKNOWN, + UTOPPY_DIRENT_DIRECTORY, + UTOPPY_DIRENT_FILE + } ud_type; + off_t ud_size; + time_t ud_mtime; + uint32_t ud_attributes; +}; + +/* Initiate reading from a specific file */ +#define UTOPPYIOREADFILE _IOW('t', 9, struct utoppy_readfile) +struct utoppy_readfile { + char *ur_path; + off_t ur_offset; +}; + +/* Initiate writing to a new file */ +#define UTOPPYIOWRITEFILE _IOW('t', 10, struct utoppy_writefile) +struct utoppy_writefile { + char *uw_path; + off_t uw_offset; + off_t uw_size; + time_t uw_mtime; +}; + +#endif /* _DEV_USB_UTOPPY_H_ */ diff -Nru /usr/local/cvsup-stable/src/sys/modules/Makefile /usr/src/sys/modules/Makefile --- /usr/local/cvsup-stable/src/sys/modules/Makefile Sat Dec 30 17:55:15 2006 +++ /usr/src/sys/modules/Makefile Sun Dec 31 16:40:18 2006 @@ -274,6 +274,7 @@ usb \ uscanner \ utopia \ + utoppy \ uvisor \ uvscom \ ${_vesa} \ diff -Nru /usr/local/cvsup-stable/src/sys/modules/utoppy/Makefile /usr/src/sys/modules/utoppy/Makefile --- /usr/local/cvsup-stable/src/sys/modules/utoppy/Makefile Thu Jan 1 01:00:00 1970 +++ /usr/src/sys/modules/utoppy/Makefile Sun Dec 31 16:39:59 2006 @@ -0,0 +1,8 @@ +# $FreeBSD: $ + +.PATH: ${.CURDIR}/../../dev/usb + +KMOD= utoppy +SRCS= bus_if.h device_if.h opt_usb.h utoppy.c utoppy.h usbdevs.h + +.include --- /usr/local/cvsup-stable/src/sys/conf/NOTES Sat Dec 30 17:55:15 2006 +++ /usr/src/sys/conf/NOTES Mon Jan 1 04:15:33 2007 @@ -2352,6 +2352,8 @@ device urio # USB scanners device uscanner +# USB support for the Topfield TF5000PVR digital video recorder +device utoppy # # USB serial support device ucom >Release-Note: >Audit-Trail: >Unformatted: From owner-freebsd-usb@FreeBSD.ORG Mon Jan 1 11:09:03 2007 Return-Path: X-Original-To: freebsd-usb@FreeBSD.org Delivered-To: freebsd-usb@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 9A57416A6A7 for ; Mon, 1 Jan 2007 11:09:03 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id 84B1C13C471 for ; Mon, 1 Jan 2007 11:09:03 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (linimon@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l01B93Wa049049 for ; Mon, 1 Jan 2007 11:09:03 GMT (envelope-from owner-bugmaster@FreeBSD.org) Received: (from linimon@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l01B928K049045 for freebsd-usb@FreeBSD.org; Mon, 1 Jan 2007 11:09:02 GMT (envelope-from owner-bugmaster@FreeBSD.org) Date: Mon, 1 Jan 2007 11:09:02 GMT Message-Id: <200701011109.l01B928K049045@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: linimon set sender to owner-bugmaster@FreeBSD.org using -f From: FreeBSD bugmaster To: freebsd-usb@FreeBSD.org Cc: Subject: Current problem reports assigned to you X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Jan 2007 11:09:03 -0000 Current FreeBSD problem reports Critical problems S Tracker Resp. Description -------------------------------------------------------------------------------- o usb/84750 usb [hang] 6-BETA2 reboot/shutdown with root_fs on externa o usb/91629 usb usbd_abort_pipe() may result in infinite loop 2 problems total. Serious problems S Tracker Resp. Description -------------------------------------------------------------------------------- o usb/40792 usb signals lead to data loss on device ugen o usb/46176 usb [panic] umass causes kernel panic if device removed be o i386/46371 usb USB controller cannot be initialized on IBM Netfinity f usb/55555 usb [ums] system freezes with access to /dev/ums0 o bin/57255 usb usbd and multi-function devices o usb/62088 usb [usb] Logitech Cordless/Optical Mouse not working o usb/62309 usb [ugen] [panic] panic: ugen(4) driver o usb/63621 usb [usb] USB MemoryStick Reader stalls/crashes system o usb/69006 usb [patch] Apple Cinema Display hangs USB ports o usb/71155 usb [usb] misbehaving usb-printer hangs processes, causes o usb/73307 usb [panic] Kernel panics on USB disconnect o usb/74771 usb [umass] mounting write-protected umass device as read/ o usb/75705 usb [panic] da0 attach / Optio S4 (with backtrace) o usb/75797 usb 5.3-STABLE(2005 1/4) detect USB headset, But can not f f usb/76204 usb panic while using usb attached modem o usb/76395 usb USB printer does not work, usbdevs says "addr 0 should f usb/76684 usb [hang] Toshiba PDR-M4 camera connected via USB hangs s o usb/77184 usb kernel panic on USB device disconnect o usb/77294 usb ucom + ulpcom panic o usb/77940 usb [patch] [panic] insertion of usb keyboard panics syste f i386/78218 usb [kue] kue not detected on Sony PCG-F370 VAIO o usb/78989 usb please add USB keyboard support to install CD's o usb/79140 usb WD Firewire/USB Combo hangs under load on USB interfac o usb/79269 usb USB ohci da0 plug/unplug causes crashes and lockups. o usb/79287 usb UHCI hang after interrupt transfer o usb/79524 usb printing to Minolta PagePro 1[23]xxW via USB fails wit f usb/79656 usb [usb] RHSC interrupts lost o usb/79722 usb [usb] wrong alignments in ehci.h o usb/80040 usb [hang] Use of sound mixer causes system freeze with ua f usb/80260 usb Travan USB tape drive fails to write o usb/80361 usb mounting of usb-stick fails o usb/80373 usb usb keyboard does not respond o usb/80829 usb possible panic when loading USB-modules o usb/80862 usb [patch] USB locking issues: missing some Giant calls o usb/81308 usb [ugen] [patch] polling a ugen(4) control endpoint caus f usb/82198 usb Panic on attaching of ONKI N-338 USB MP3 player f usb/82272 usb Can not recognize Casio camera EX-Z40 as a umass devic o usb/82350 usb [usb] null pointer dereference in USB stack o usb/82520 usb Reboot when USL101 connected o usb/82569 usb [usb] USB mass storage plug/unplug causes system panic o usb/82660 usb EHCI: I/O stuck in state 'physrd'/panic o usb/83504 usb [usb] SpeedTouch USB stop working on recent current (a o usb/83563 usb [panic] Page Fault while detaching Mpman Usb device o usb/83677 usb [usb] usb controller often not detected (Sun W2100z) o usb/83756 usb Microsoft Intellimouse Explorer 4.0A doesn't work. o usb/83977 usb [ucom] [panic] ucom1: open bulk out error (addr 2): IN o usb/84326 usb [umass] Panic trying to connect SCSI tape drive via US o usb/84336 usb [usb] [reboot] instant system reboot when unmounting a o usb/84936 usb install - usb keyboard not recognized o usb/86031 usb need support usb nic rt2500 in my 5.4 STABLE o usb/86767 usb [usb] bogus "slice starts beyond end of the disk:..." o usb/87099 usb panic: ohci_add_done: addr 0x000d1bf0 not found o usb/87565 usb [PATCH] Support for Vodaphone 3G/UMTS cards o usb/88743 usb [hang] USB makes kernel hang at boot (regression in 6. o usb/88966 usb kldunload ucom.ko returns "Device busy" error. o usb/89003 usb LaCie Firewire drive not properly supported under 6.0 o usb/89218 usb flash disk o usb/89954 usb [usb] USB Disk driver race condition? f usb/89997 usb [umass] [panic] panic on iPod mini detach o usb/90162 usb [usb] [patch] Add support for the MS Wireless USB Mous o usb/90700 usb Kernel panic on connect/mount/use umass device o usb/91238 usb USB tape unit fails to write a second tape file to the o usb/91263 usb [patch] USB quirk needed for Logitec USB Hard disk LHD o usb/91283 usb booting very slow with usb devices connection (regress o usb/91538 usb Unable to print to EPSON CX3500 o usb/91906 usb FreeBSD hangs while booting with USB legacy support on o usb/92052 usb usbd causes defunct process with busy file-handle o usb/92142 usb SET_ADDR_FAILED and SHORT_XFER errors from usb drivers o usb/92171 usb [panic] panic unplugging Vodafone Mobile Connect (UMTS o usb/93155 usb /dev/ulpt0: device busy USB printer does not work o usb/93408 usb hw.acpi.cpu.cx_lowest=C3 on AMD Turion causes choppy m f usb/93496 usb USB2.0 umass stalls on VIA o usb/93640 usb device ehci causes interrupt storm on this MSI amd64 m o usb/93828 usb ohci causes panic on boot (HP Pavillion d4100e) o usb/93949 usb ugen(4)-related repeatable kernel panic in 6.1-PRERELE o usb/94166 usb btx halted with a flashcard plugged o usb/94384 usb kernel panic with usb2 hardware o usb/94717 usb Reading from /dev/ulpt can break work of a UHCI hub o usb/94742 usb [umass] [patch] umass driver does not recognise YANO e o usb/94813 usb mounting write-protected umass device freezes computer o usb/94897 usb Kernel Panic when cleanly unmounting USB disk o usb/95131 usb Boot/setup process does not accept key strokes o usb/95348 usb USB keyboard unplug causes noise on screen o usb/95562 usb Write Stress in USB Mass drive cause: [vinvalbuf: dir o usb/95636 usb [boot] 5 minute delay at boot when using VT6205 based o usb/96120 usb USB mouse not always detected o usb/96224 usb [usb] mount_msdosfs cause page fault in syncer process o usb/96457 usb fatback on umass = reboot o usb/97286 usb MS Wireless Intellimouse Explorer 2.0 doesn't work o usb/99431 usb FreeBSD on MSI 6566E (Intel 845E motherboards) doesn't o usb/101096 usb USB WLAN occasionally causes kernel-panics during larg o usb/101752 usb [panic] 6.1-RELEASE kernel panic on usb device inserti o usb/102066 usb [ukbd] usb keyboard and multimedia keys don't work o usb/102096 usb /usr/sbin/usbd does not handle multiple devices in one o i386/103025 usb [USB] the wrong in USB device for freeBSD 6.1 and AMD o usb/104292 usb system lockup on forced umount of usb-storage device o usb/104810 usb [usb] panic: ohci_add_done: addr 0x3fef1ba0 not found o usb/104830 usb system crashes when copying data to umass devices o usb/105186 usb USB 2.0/ehci on FreeBSD 6.2-PRE/AMD64 crashes box o usb/106615 usb uftdi module does not automatically load with the FTDI o usb/106648 usb USB Floppy on D1950 10 min Hang on Insert w/o Floppy D o usb/106832 usb USB HP printer is not detected by kernel when ACPI ena o usb/107101 usb [umass] [patch] Quirk for Denver MP3 player o usb/107116 usb [usb] panic while accessing usb msdos pccard o usb/107128 usb [usb] panic while accessing usb msdos flashkey o usb/107248 usb [PATCH] scsi_da.c quirk for Cowon iAUDIO X5 MP3 player 106 problems total. Non-critical problems S Tracker Resp. Description -------------------------------------------------------------------------------- o conf/30929 usb [usb] [patch] use usbd to initialize USB ADSL modem s usb/32653 usb Added patches to improve USB scanner supportOB o usb/40948 usb [usb] USB HP CDW8200 does not work f usb/41415 usb [usb] [patch] Some USB scanners cannot talk to uscanne o usb/48342 usb [PATCH] usbd dynamic device list. o kern/51958 usb [usb] [patch] update for urio driver o kern/52026 usb [usb] feature request: umass driver support for InSyst o usb/53025 usb [ugen] [patch] ugen does not allow O_NONBLOCK for inte o usb/56095 usb [usb] [patch] QUIRK: Apacer Pen Drive fails to work o kern/59698 usb [kbd] [patch] Rework of ukbd HID to AT code translatio f usb/60248 usb [patch] Problem with USB printer HP LaserJet 1300 o usb/61234 usb [usb] [patch] usbhidaction(1) doesn't support using an o usb/63837 usb [uhid] [patch] USB: hid_is_collection() only looks for o kern/65769 usb [usb] Call to tcflush(x, TCIFLUSH) stops input on usb- o kern/66547 usb [usb] Palm Tungsten T USB does not initialize correctl o usb/68232 usb [ugen] [patch] ugen(4) isochronous handling correction o usb/68412 usb [usb] [patch] QUIRK: Philips KEY013 USB MP3 player o usb/70523 usb [usb] [patch] umct sending/receiving wrong characters o usb/70942 usb [usb] Genius Wireless USB mouse: moused doesn't work c o usb/71416 usb [usb] Cryptoflex e-gate USB token (ugen0) detach is no o usb/71417 usb [usb] Cryptoflex e-gate USB token (ugen0) communicatio o usb/71455 usb [usb] Slow USB umass performance of 5.3 o usb/71605 usb [umass] [patch] umass doesn't recognize multiple slots o usb/72380 usb [usb] USB does not work [dual Celeron Abit] o usb/72732 usb [patch] Kyocera 7135 quirk. o usb/72733 usb Kyocera 7135 Palm OS connection problem. o usb/73056 usb [usb] Sun Microsystems Type 6 USB mouse not working in f usb/73553 usb [usb] Microsoft USB Internet Keyboard not recongized o usb/74211 usb USB flash drive causes CAM status 0x4 on 4.10Release f usb/74358 usb [umass] unplugging at boot time an umass device crashe o usb/74453 usb Q-lity CD-RW USB ECW-043 (ScanLogic SL11R chipset) doe o usb/74557 usb imation 500mb usb key can only be written halfway on f o usb/74609 usb [usb] [patch] allowing cdma modems to work at full spe o usb/74849 usb [usb] [patch] Samsung SPH-i500 does not attach properl o usb/74880 usb [usb] [patch] Samsung N400 cellphone/acm fails to atac o usb/75800 usb ucom1: init failed STALLED error in time of sync with o usb/75928 usb Cytronix SmartMedia card (SMC) reader has problems whe o usb/76461 usb [umass] disklabel of umass(4)-CAM(4)-da(4) not used by o usb/76732 usb Mouse problems with USB KVM Switch f usb/78371 usb Philips Wearable Audio Player (128) fails to attach f usb/78984 usb Creative MUVO umass failure o usb/79723 usb [usb] prepare for high speed isochronous transfers o usb/79725 usb [usb] [patch] USB device speed is not double-checked o usb/79893 usb [umass] [patch] new usbdevs/umass quirks derived from o usb/80010 usb [aue] [patch] add support for the AEI USB to LAN adapt f usb/80420 usb atapicam stops iPod functionality f usb/80773 usb "usbd_get_string()" could have taken a length paramete o usb/80774 usb have "usbd_find_desc" in line with the other "usbd_fin o usb/80776 usb [udav] UDAV device driver shouldn't use usb_add_task o usb/80777 usb usb_rem_task() should wait for callback to complete? o usb/80854 usb suggestion for new iface-no-probe mechanism o usb/80935 usb uvisor.c is not work with CLIE TH55. o usb/81191 usb Support for Curitel HX-550C USB modem to 5.4 RELEASE. f usb/81621 usb external hd hangs under load on ehci o usb/82436 usb [patch] USL101 Host-to-Host bridge support on FreeBSD o usb/83022 usb ALI USB 2.0 EHCI Controller is not detected o usb/83863 usb Communication problem between opensc/openct via USB wi o usb/85067 usb Cannot attach ScanJet 4300C to usb device o usb/85992 usb [uhid] [patch] USB stops working when trying to read f o usb/86195 usb [patch] allow USB Ethernet Adaptor "ELECOM LD-USB20" t o usb/86298 usb Known good USB mouse won't work with correct settings o usb/86438 usb Fix for non-working iPod over USB is in NetBSD CVS o usb/87224 usb Cannot mount USB Zip750 o usb/87648 usb [mouse] Logitech USB-optical mouse problem. o usb/88408 usb axe0 read PHY failed o usb/88939 usb Fix cheapy Myson USB-IDE adapter f usb/89087 usb usb external harddrive hangs with BBB reset failed, TI f usb/91191 usb HP LaserJet 1020 (USB printer) not recognized f usb/91516 usb [umass] umass0 problems, with Freecom Classic SL Hard o usb/91546 usb [umodem] [patch] Nokia 6630 mobile phone does not work o usb/91811 usb Compact Flash in HP Photosmart 2610 return " Medium n o usb/91896 usb Serial Number of USB Memory Sticks is not passed throu o usb/92306 usb [quirk] [patch] Support for iRiver U10 USB media playe o usb/92403 usb [uplcom] uplcom.c needs new entry for 4.00 revision of o usb/92852 usb Vertical scroll not working properly on A4Tech WOP-49 f usb/93011 usb HP ScanJet 6200C & uscanner problem o usb/93389 usb Digital Camera Pentax S60 don't work o usb/93872 usb [patch] SCSI quirk required for ELTA 8061 OL USB memor o usb/94132 usb USB QUIRK for CENTURY EX35QUAT disk enclosure f usb/94147 usb doesn't recognise my USB keyboard o usb/94148 usb Make if_cdce work with ARM linux handhelds o usb/94311 usb [ugen][PATCH] allow interrupt IN transactions to be af o usb/94439 usb [patch] Add support for JNC MP3 Player o usb/94946 usb [uhub][patch] code dynamic status size for status chan o usb/95037 usb USB disk didnt recognized on hot-plug. o usb/95173 usb [usb] cannot mount external usb harddisk VIA Technolog o usb/95241 usb Patch to add USB ID for OEM Pharos 360 GPS o usb/95803 usb Add support for AnyData ADU-E100H o usb/95805 usb Add Support for Siemens ES75 modem o usb/96381 usb [patch] add a quirk table entry for a flash ram usb st o usb/96546 usb [usb] [patch] Add support (quirk) for EasyMP3 EM732X U o usb/96714 usb Update uvisor to support the Fossil Abacus Wrist PDA o usb/97175 usb USB cardreader hangs system o usb/97472 usb [patch] add support for Olympus C150,D390 o usb/98343 usb BBB reset failed errors with Creative Muvo MP3 player; o usb/99419 usb external usb harddrive slow to accept f usb/99538 usb [kbd] while using USB keyboard default params of atkbd o usb/100746 usb [kbd] system does not boot due to USB keyboard problem o usb/101757 usb [patch] uhid.4: correct structure field names to match o usb/101761 usb [patch] usb.h: increase maximal size of report descrip o usb/101775 usb [libusbhid] [patch] possible error in report descripto o usb/102976 usb Casio Exilim Digital Camera cause panic o usb/103046 usb [patch] ulpt event driven I/O with select(2) and nonbl o usb/103289 usb USB 2.0 problems on AMD LX-800 CPU and CS-5536 chipset o usb/103418 usb [usb] [patch] usbhidctl: add ability to write output a o usb/103917 usb USB driver reports "Addr 0 should never happen" o usb/104290 usb QUIRK: TOSHIBA DVD-RAM drive (libretto DVD Dock) o usb/104352 usb [ural] ural driver doesnt work o usb/104645 usb QUIRK: Rave C-201 MP3 player o usb/105065 usb SATA - USB Bridge o usb/105361 usb Kernel panic during unmounting mass storage (Creative o usb/105518 usb epson perfection 3490 usb scanner def o kern/106033 usb [usb] [patch] support for 3G/WCDMA cards Option Globet o usb/106041 usb FreeBSD does not recognise Mustek BearPaw 2400TA usb s o usb/106070 usb devd recognizes ucom, but ttyU is the device actually o usb/106462 usb Motorola U6 PEBL not recognized by system via USB [pat o usb/106538 usb [patch] Can not burn DVD on Sony DRX-820UL external US o usb/106621 usb [usb] DLINK DUB-E100 support broken o usb/106861 usb [PATCH]: usbdevs update: Add product ACER Zeevo BT-500 o usb/107243 usb [patch] Apacer USB Flash Drive quirk o usb/107388 usb [PATCH] Add utoppy device from NetBSD 121 problems total. From owner-freebsd-usb@FreeBSD.ORG Mon Jan 1 16:19:36 2007 Return-Path: X-Original-To: freebsd-usb@freebsd.org Delivered-To: freebsd-usb@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 70C4516A412 for ; Mon, 1 Jan 2007 16:19:36 +0000 (UTC) (envelope-from cyborg_sa@hotmail.com) Received: from bay0-omc3-s37.bay0.hotmail.com (bay0-omc3-s37.bay0.hotmail.com [65.54.246.237]) by mx1.freebsd.org (Postfix) with ESMTP id 622E813C45E for ; Mon, 1 Jan 2007 16:19:36 +0000 (UTC) (envelope-from cyborg_sa@hotmail.com) Received: from BAY124-W48 ([207.46.11.211]) by bay0-omc3-s37.bay0.hotmail.com with Microsoft SMTPSVC(6.0.3790.2668); Mon, 1 Jan 2007 08:07:36 -0800 X-Originating-IP: [202.125.143.67] X-Originating-Email: [cyborg_sa@hotmail.com] Message-ID: From: Saad Ali To: Date: Mon, 1 Jan 2007 16:07:36 +0000 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginalArrivalTime: 01 Jan 2007 16:07:36.0609 (UTC) FILETIME=[F41F8110:01C72DBE] X-Mailman-Approved-At: Mon, 01 Jan 2007 17:59:13 +0000 Subject: Wireless Modem X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Jan 2007 16:19:36 -0000 I have a CDMA connection with a Huawei wireless ETS2551 phone set that conn= ects to my PC using a TUSB3410 cable (UART to USB). It gets detected as "TU= SB3410 Boot Device" under the device node ugen0 which is a generic device n= ode. My question is that how can I use this modem builtin to the phone set = in FreeBSD. I was advised to recompile the kernel but I cant find my device= name under the FreeBSd 6.1 hardware list. _________________________________________________________________ Type your favorite song.=A0 Get a customized station.=A0 Try MSN Radio powe= red by Pandora. http://radio.msn.com= From owner-freebsd-usb@FreeBSD.ORG Mon Jan 1 18:36:53 2007 Return-Path: X-Original-To: freebsd-usb@freebsd.org Delivered-To: freebsd-usb@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 19A9E16A403 for ; Mon, 1 Jan 2007 18:36:53 +0000 (UTC) (envelope-from imp@bsdimp.com) Received: from harmony.bsdimp.com (vc4-2-0-87.dsl.netrack.net [199.45.160.85]) by mx1.freebsd.org (Postfix) with ESMTP id D020F13C457 for ; Mon, 1 Jan 2007 18:36:52 +0000 (UTC) (envelope-from imp@bsdimp.com) Received: from localhost (localhost [127.0.0.1]) by harmony.bsdimp.com (8.13.4/8.13.4) with ESMTP id l01IZawZ080540; Mon, 1 Jan 2007 11:35:36 -0700 (MST) (envelope-from imp@bsdimp.com) Date: Mon, 01 Jan 2007 11:35:47 -0700 (MST) Message-Id: <20070101.113547.-691883467.imp@bsdimp.com> To: cyborg_sa@hotmail.com From: "M. Warner Losh" In-Reply-To: References: X-Mailer: Mew version 4.2 on Emacs 21.3 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-2.0 (harmony.bsdimp.com [127.0.0.1]); Mon, 01 Jan 2007 11:35:36 -0700 (MST) Cc: freebsd-usb@freebsd.org Subject: Re: Wireless Modem X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Jan 2007 18:36:53 -0000 In message: Saad Ali writes: : I have a CDMA connection with a Huawei wireless ETS2551 phone set : that connects to my PC using a TUSB3410 cable (UART to USB). It gets : detected as "TUSB3410 Boot Device" under the device node ugen0 which : is a generic device node. My question is that how can I use this : modem builtin to the phone set in FreeBSD. I was advised to : recompile the kernel but I cant find my device name under the : FreeBSd 6.1 hardware list. Most cellphone modems aren't in the hardware list because they change more often than we can document them... Try building a kernel with the following devices: device ucom device umodem device umct device uark device ubsa device ubser device uftdi device uplcom device uvisor device uvscom Maybe we should start putting them in GENERIC, because I've answered this question a dozen times in the past few months. Warner From owner-freebsd-usb@FreeBSD.ORG Mon Jan 1 18:51:04 2007 Return-Path: X-Original-To: freebsd-usb@freebsd.org Delivered-To: freebsd-usb@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 5253716A415 for ; Mon, 1 Jan 2007 18:51:04 +0000 (UTC) (envelope-from ticso@cicely12.cicely.de) Received: from raven.bwct.de (raven.bwct.de [85.159.14.73]) by mx1.freebsd.org (Postfix) with ESMTP id CF0E413C441 for ; Mon, 1 Jan 2007 18:51:03 +0000 (UTC) (envelope-from ticso@cicely12.cicely.de) Received: from cicely5.cicely.de ([10.1.1.7]) by raven.bwct.de (8.13.4/8.13.4) with ESMTP id l01Ip1Sv092806; Mon, 1 Jan 2007 19:51:02 +0100 (CET) (envelope-from ticso@cicely12.cicely.de) Received: from cicely12.cicely.de (cicely12.cicely.de [10.1.1.14]) by cicely5.cicely.de (8.13.4/8.13.4) with ESMTP id l01IoswI052655 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 1 Jan 2007 19:50:54 +0100 (CET) (envelope-from ticso@cicely12.cicely.de) Received: from cicely12.cicely.de (localhost [127.0.0.1]) by cicely12.cicely.de (8.13.4/8.13.3) with ESMTP id l01IorKR053675; Mon, 1 Jan 2007 19:50:53 +0100 (CET) (envelope-from ticso@cicely12.cicely.de) Received: (from ticso@localhost) by cicely12.cicely.de (8.13.4/8.13.3/Submit) id l01IoqTX053674; Mon, 1 Jan 2007 19:50:52 +0100 (CET) (envelope-from ticso) Date: Mon, 1 Jan 2007 19:50:52 +0100 From: Bernd Walter To: Saad Ali Message-ID: <20070101185051.GE50150@cicely12.cicely.de> References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Operating-System: FreeBSD cicely12.cicely.de 5.4-STABLE alpha User-Agent: Mutt/1.5.9i X-Spam-Status: No, score=-4.4 required=5.0 tests=ALL_TRUSTED=-1.8, BAYES_00=-2.599 autolearn=ham version=3.1.7 X-Spam-Checker-Version: SpamAssassin 3.1.7 (2006-10-05) on cicely12.cicely.de Cc: freebsd-usb@freebsd.org Subject: Re: Wireless Modem X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: ticso@cicely.de List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Jan 2007 18:51:04 -0000 On Mon, Jan 01, 2007 at 04:07:36PM +0000, Saad Ali wrote: > > I have a CDMA connection with a Huawei wireless ETS2551 phone set that connects to my PC using a TUSB3410 cable (UART to USB). It gets detected as "TUSB3410 Boot Device" under the device node ugen0 which is a generic device node. My question is that how can I use this modem builtin to the phone set in FreeBSD. I was advised to recompile the kernel but I cant find my device name under the FreeBSd 6.1 hardware list. The TUSB3410 is a generic 8051 microcontroller with USB, which can be used as an USB UART, but is freely programmable. It has a simple internal ROM to upload firmware into it's code RAM from external memory or via USB. Since it presents you with the boot code it has no firmware loaded yet and you are expected to upload it first. You might want to check comms/uticom in ports. -- B.Walter http://www.bwct.de http://www.fizon.de bernd@bwct.de info@bwct.de support@fizon.de From owner-freebsd-usb@FreeBSD.ORG Wed Jan 3 06:28:08 2007 Return-Path: X-Original-To: freebsd-usb@hub.freebsd.org Delivered-To: freebsd-usb@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id A36E716A407; Wed, 3 Jan 2007 06:28:08 +0000 (UTC) (envelope-from remko@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id 7E00713C4A9; Wed, 3 Jan 2007 06:28:08 +0000 (UTC) (envelope-from remko@FreeBSD.org) Received: from freefall.freebsd.org (remko@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l036S8q6023753; Wed, 3 Jan 2007 06:28:08 GMT (envelope-from remko@freefall.freebsd.org) Received: (from remko@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l036S8sV023749; Wed, 3 Jan 2007 06:28:08 GMT (envelope-from remko) Date: Wed, 3 Jan 2007 06:28:08 GMT From: Remko Lodder Message-Id: <200701030628.l036S8sV023749@freefall.freebsd.org> To: remko@FreeBSD.org, freebsd-bugs@FreeBSD.org, freebsd-usb@FreeBSD.org Cc: Subject: Re: usb/107446: umass problems (usb and fw disks) X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Jan 2007 06:28:08 -0000 Synopsis: umass problems (usb and fw disks) Responsible-Changed-From-To: freebsd-bugs->freebsd-usb Responsible-Changed-By: remko Responsible-Changed-When: Wed Jan 3 06:27:41 UTC 2007 Responsible-Changed-Why: This might be USB related, can the USB team look at this first? http://www.freebsd.org/cgi/query-pr.cgi?pr=107446 From owner-freebsd-usb@FreeBSD.ORG Wed Jan 3 09:40:23 2007 Return-Path: X-Original-To: freebsd-usb@hub.freebsd.org Delivered-To: freebsd-usb@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 1662116A416 for ; Wed, 3 Jan 2007 09:40:23 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id A2F8F13C457 for ; Wed, 3 Jan 2007 09:40:22 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l039eMpq043180 for ; Wed, 3 Jan 2007 09:40:22 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l039eMM3043179; Wed, 3 Jan 2007 09:40:22 GMT (envelope-from gnats) Date: Wed, 3 Jan 2007 09:40:22 GMT Message-Id: <200701030940.l039eMM3043179@freefall.freebsd.org> To: freebsd-usb@FreeBSD.org From: Simon Barner Cc: Subject: Re: usb/82272: Can not recognize Casio camera EX-Z40 as a umass device (regression) X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Simon Barner List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Jan 2007 09:40:23 -0000 The following reply was made to PR usb/82272; it has been noted by GNATS. From: Simon Barner To: "mailto:bug-followup"@FreeBSD.org, ld@ldconfig.com Cc: Subject: Re: usb/82272: Can not recognize Casio camera EX-Z40 as a umass device (regression) Date: Wed, 3 Jan 2007 10:06:49 +0100 Hi, this seems to work just fine again on: 6.1-STABLE FreeBSD 6.1-STABLE #0: Sun Jun 11 14:52:26 CEST 2006 -- Best regards / Viele Grüße, barner@FreeBSD.org Simon Barner barner@gmx.de From owner-freebsd-usb@FreeBSD.ORG Thu Jan 4 16:40:25 2007 Return-Path: X-Original-To: freebsd-usb@hub.freebsd.org Delivered-To: freebsd-usb@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 6946916A415 for ; Thu, 4 Jan 2007 16:40:25 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id 4ADD413C46A for ; Thu, 4 Jan 2007 16:40:25 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l04GePYK043429 for ; Thu, 4 Jan 2007 16:40:25 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l04GeP0s043428; Thu, 4 Jan 2007 16:40:25 GMT (envelope-from gnats) Resent-Date: Thu, 4 Jan 2007 16:40:25 GMT Resent-Message-Id: <200701041640.l04GeP0s043428@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-usb@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, John Wilson Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 9F7F916A407 for ; Thu, 4 Jan 2007 16:38:19 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [69.147.83.33]) by mx1.freebsd.org (Postfix) with ESMTP id 90CFF13C43E for ; Thu, 4 Jan 2007 16:38:19 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.13.1/8.13.1) with ESMTP id l04GcJnA077413 for ; Thu, 4 Jan 2007 16:38:19 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.13.1/8.13.1/Submit) id l04GcJqL077412; Thu, 4 Jan 2007 16:38:19 GMT (envelope-from nobody) Message-Id: <200701041638.l04GcJqL077412@www.freebsd.org> Date: Thu, 4 Jan 2007 16:38:19 GMT From: John Wilson To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.0 Cc: Subject: usb/107526: Patch to support the Crystalfontz CFA-635 20x4 USB LCD X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Jan 2007 16:40:25 -0000 >Number: 107526 >Category: usb >Synopsis: Patch to support the Crystalfontz CFA-635 20x4 USB LCD >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-usb >State: open >Quarter: >Keywords: >Date-Required: >Class: update >Submitter-Id: current-users >Arrival-Date: Thu Jan 04 16:40:24 GMT 2007 >Closed-Date: >Last-Modified: >Originator: John Wilson >Release: 6-stable >Organization: >Environment: FreeBSD asus.nyc.rr.com 6.2-PRERELEASE FreeBSD 6.2-PRERELEASE #2: Thu Jan 4 11:19:44 EST 2007 jmw-ny@asus.nyc.rr.com:/usr/obj/usr/src/sys/GEN i386 >Description: A patch to /usr/src/sys/dev/usb/usbdevs and /usr/src/sys/dev/usb/uftdi.c to add support for the Crystalfontz CFA-635 USB 20x4 USB LCD. >How-To-Repeat: Apply supplied patch. >Fix: Apply supplied patch. Patch attached with submission follows: --- usbdevs.orig Thu Jan 4 11:00:31 2007 +++ usbdevs Thu Jan 4 10:50:24 2007 @@ -790,6 +790,7 @@ product FTDI CFA_632 0xfc08 Crystalfontz CFA-632 USB LCD product FTDI CFA_633 0xfc0b Crystalfontz CFA-633 USB LCD product FTDI CFA_634 0xfc09 Crystalfontz CFA-634 USB LCD +product FTDI CFA_635 0xfc0d Crystalfontz CFA-635 USB LCD product FTDI SEMC_DSS20 0xfc82 SEMC DSS-20 SyncStation /* Cambridge Silicon Radio Ltd. products */ --- uftdi.c.orig Thu Jan 4 11:00:45 2007 +++ uftdi.c Thu Jan 4 10:49:26 2007 @@ -163,6 +163,7 @@ uaa->product == USB_PRODUCT_FTDI_CFA_632 || uaa->product == USB_PRODUCT_FTDI_CFA_633 || uaa->product == USB_PRODUCT_FTDI_CFA_634 || + uaa->product == USB_PRODUCT_FTDI_CFA_635 || uaa->product == USB_PRODUCT_FTDI_USBSERIAL || uaa->product == USB_PRODUCT_FTDI_MX2_3 || uaa->product == USB_PRODUCT_FTDI_MX4_5 || @@ -242,6 +243,7 @@ case USB_PRODUCT_FTDI_CFA_632: case USB_PRODUCT_FTDI_CFA_633: case USB_PRODUCT_FTDI_CFA_634: + case USB_PRODUCT_FTDI_CFA_635: case USB_PRODUCT_FTDI_USBSERIAL: case USB_PRODUCT_FTDI_MX2_3: case USB_PRODUCT_FTDI_MX4_5: >Release-Note: >Audit-Trail: >Unformatted: From owner-freebsd-usb@FreeBSD.ORG Thu Jan 4 17:45:00 2007 Return-Path: X-Original-To: freebsd-usb@hub.freebsd.org Delivered-To: freebsd-usb@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 97ED216A403; Thu, 4 Jan 2007 17:45:00 +0000 (UTC) (envelope-from linimon@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id 701AE13C461; Thu, 4 Jan 2007 17:45:00 +0000 (UTC) (envelope-from linimon@FreeBSD.org) Received: from freefall.freebsd.org (linimon@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l04Hiwlp050982; Thu, 4 Jan 2007 17:44:58 GMT (envelope-from linimon@freefall.freebsd.org) Received: (from linimon@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l04HiwJf050978; Thu, 4 Jan 2007 17:44:58 GMT (envelope-from linimon) Date: Thu, 4 Jan 2007 17:44:58 GMT From: Mark Linimon Message-Id: <200701041744.l04HiwJf050978@freefall.freebsd.org> To: linimon@FreeBSD.org, freebsd-bugs@FreeBSD.org, freebsd-usb@FreeBSD.org Cc: Subject: Re: usb/107496: USB device problem on RELENG_6_2 (SHORT_XFER) (regression) X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Jan 2007 17:45:00 -0000 Old Synopsis: USB device problem on RELENG_6_2 (SHORT_XFER) New Synopsis: USB device problem on RELENG_6_2 (SHORT_XFER) (regression) Responsible-Changed-From-To: freebsd-bugs->freebsd-usb Responsible-Changed-By: linimon Responsible-Changed-When: Thu Jan 4 17:44:13 UTC 2007 Responsible-Changed-Why: Over to maintainer(s). http://www.freebsd.org/cgi/query-pr.cgi?pr=107496 From owner-freebsd-usb@FreeBSD.ORG Fri Jan 5 17:20:17 2007 Return-Path: X-Original-To: freebsd-usb@hub.freebsd.org Delivered-To: freebsd-usb@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 4646D16A407 for ; Fri, 5 Jan 2007 17:20:17 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id 2182713C45D for ; Fri, 5 Jan 2007 17:20:17 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l05HKHYU008211 for ; Fri, 5 Jan 2007 17:20:17 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l05HKGPD008210; Fri, 5 Jan 2007 17:20:17 GMT (envelope-from gnats) Resent-Date: Fri, 5 Jan 2007 17:20:17 GMT Resent-Message-Id: <200701051720.l05HKGPD008210@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-usb@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Andreas Burghardt Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 20B6B16A407 for ; Fri, 5 Jan 2007 17:16:48 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [69.147.83.33]) by mx1.freebsd.org (Postfix) with ESMTP id 0EA7213C465 for ; Fri, 5 Jan 2007 17:16:48 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.13.1/8.13.1) with ESMTP id l05HGlAb029759 for ; Fri, 5 Jan 2007 17:16:47 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.13.1/8.13.1/Submit) id l05HGlNp029758; Fri, 5 Jan 2007 17:16:47 GMT (envelope-from nobody) Message-Id: <200701051716.l05HGlNp029758@www.freebsd.org> Date: Fri, 5 Jan 2007 17:16:47 GMT From: Andreas Burghardt To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.0 Cc: Subject: usb/107572: Immidiate System Reboot after removing an active usb-stick X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Jan 2007 17:20:17 -0000 >Number: 107572 >Category: usb >Synopsis: Immidiate System Reboot after removing an active usb-stick >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-usb >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Jan 05 17:20:16 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Andreas Burghardt >Release: FreeBSD 7.0-Current >Organization: none >Environment: FreeBSD iwix 7.0-CURRENT FreeBSD 7.0-CURRENT #0: Fri Jan 5 13:57:31 CET 2007 root@iwix:/usr/obj/usr/src/sys/BODOH i386 >Description: I removed a Job-it (2.0 USB, 1GB) USB-Stick from its slot while a file copy to this stick was still in progress. The result was an immidiate reboot of FreeBSD without syncing or unmounting any logal file systems. /var/log/message Jan 5 17:41:18 iwix syslogd: kernel boot file is /boot/kernel/kernel Jan 5 17:41:18 iwix kernel: Copyright (c) 1992-2007 The FreeBSD Project. Jan 5 17:41:18 iwix kernel: Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 Jan 5 17:41:18 iwix kernel: The Regents of the University of California. All rights reserved. Jan 5 17:41:18 iwix kernel: FreeBSD is a registered trademark of The FreeBSD Foundation. Jan 5 17:41:18 iwix kernel: FreeBSD 7.0-CURRENT #0: Fri Jan 5 13:57:31 CET 2007 Jan 5 17:41:18 iwix kernel: root@iwix:/usr/obj/usr/src/sys/BODOH Jan 5 17:41:18 iwix kernel: Timecounter "i8254" frequency 1193182 Hz quality 0 Jan 5 17:41:18 iwix kernel: CPU: Intel(R) Pentium(R) M processor 1.73GHz (1729.01-MHz 686-class CPU) Jan 5 17:41:18 iwix kernel: Origin = "GenuineIntel" Id = 0x6d8 Stepping = 8 Jan 5 17:41:18 iwix kernel: Features=0xafe9f9ff Jan 5 17:41:18 iwix kernel: Features2=0x180 Jan 5 17:41:18 iwix kernel: real memory = 536735744 (511 MB) Jan 5 17:41:18 iwix kernel: avail memory = 515735552 (491 MB) Jan 5 17:41:18 iwix kernel: kbd1 at kbdmux0 Jan 5 17:41:18 iwix kernel: acpi0: on motherboard Jan 5 17:41:18 iwix kernel: acpi_bus_number: can't get _ADR Jan 5 17:41:18 iwix kernel: acpi_bus_number: can't get _ADR Jan 5 17:41:18 iwix kernel: acpi0: Power Button (fixed) Jan 5 17:41:18 iwix kernel: acpi_bus_number: can't get _ADR Jan 5 17:41:18 iwix kernel: acpi_bus_number: can't get _ADR Jan 5 17:41:18 iwix kernel: Timecounter "ACPI-fast" frequency 3579545 Hz quality 1000 Jan 5 17:41:18 iwix kernel: acpi_timer0: <24-bit timer at 3.579545MHz> port 0x1008-0x100b on acpi0 Jan 5 17:41:18 iwix kernel: acpi_ec0: port 0x62,0x66 on acpi0 Jan 5 17:41:18 iwix kernel: cpu0: on acpi0 Jan 5 17:41:18 iwix kernel: acpi_perf0: on cpu0 Jan 5 17:41:18 iwix kernel: acpi_perf0: failed in PERF_STATUS attach Jan 5 17:41:18 iwix kernel: device_attach: acpi_perf0 attach returned 6 Jan 5 17:41:18 iwix kernel: acpi_perf0: on cpu0 Jan 5 17:41:18 iwix kernel: acpi_perf0: failed in PERF_STATUS attach Jan 5 17:41:18 iwix kernel: device_attach: acpi_perf0 attach returned 6 Jan 5 17:41:18 iwix kernel: est0: on cpu0 Jan 5 17:41:18 iwix kernel: est: CPU supports Enhanced Speedstep, but is not recognized. Jan 5 17:41:18 iwix kernel: est: cpu_vendor GenuineIntel, msr 6120d2606000d26 Jan 5 17:41:18 iwix kernel: device_attach: est0 attach returned 6 Jan 5 17:41:18 iwix kernel: p4tcc0: on cpu0 Jan 5 17:41:18 iwix kernel: acpi_acad0: on acpi0 Jan 5 17:41:18 iwix kernel: battery0: on acpi0 Jan 5 17:41:18 iwix kernel: acpi_button0: on acpi0 Jan 5 17:41:18 iwix kernel: acpi_lid0: on acpi0 Jan 5 17:41:18 iwix kernel: acpi_button1: on acpi0 Jan 5 17:41:18 iwix kernel: pcib0: port 0xcf8-0xcff on acpi0 Jan 5 17:41:18 iwix kernel: pci_link7: BIOS IRQ 11 for 0.29.INTA is invalid Jan 5 17:41:18 iwix kernel: pci_link3: BIOS IRQ 11 for 0.29.INTB is invalid Jan 5 17:41:18 iwix kernel: pci_link4: BIOS IRQ 5 for 0.30.INTB is invalid Jan 5 17:41:18 iwix kernel: pci0: on pcib0 Jan 5 17:41:18 iwix kernel: pcib1: irq 11 at device 1.0 on pci0 Jan 5 17:41:18 iwix kernel: pci1: on pcib1 Jan 5 17:41:18 iwix kernel: vgapci0: port 0xc000-0xc0ff mem 0x90000000-0x97 ffffff,0xc0000000-0xc000ffff at device 0.0 on pci1 Jan 5 17:41:18 iwix kernel: drm0: on vgapci0 Jan 5 17:41:18 iwix kernel: info: [drm] Initialized radeon 1.25.0 20060524 Jan 5 17:41:18 iwix kernel: uhci0: port 0x1200 -0x121f irq 10 at device 29.0 on pci0 Jan 5 17:41:18 iwix kernel: uhci0: [GIANT-LOCKED] Jan 5 17:41:18 iwix kernel: usb0: on uhci0 Jan 5 17:41:18 iwix kernel: usb0: USB revision 1.0 Jan 5 17:41:18 iwix kernel: uhub0: on usb0 Jan 5 17:41:18 iwix kernel: uhub0: 2 ports with 2 removable, self powered Jan 5 17:41:18 iwix kernel: uhci1: port 0x1220 -0x123f irq 9 at device 29.1 on pci0 Jan 5 17:41:18 iwix kernel: uhci1: [GIANT-LOCKED] Jan 5 17:41:18 iwix kernel: usb1: on uhci1 Jan 5 17:41:18 iwix kernel: usb1: USB revision 1.0 Jan 5 17:41:18 iwix kernel: uhub1: on usb1 Jan 5 17:41:18 iwix kernel: uhub1: 2 ports with 2 removable, self powered Jan 5 17:41:18 iwix kernel: ehci0: mem 0xf4000000-0xf40003 ff irq 10 at device 29.7 on pci0 Jan 5 17:41:18 iwix kernel: ehci0: [GIANT-LOCKED] Jan 5 17:41:18 iwix kernel: usb2: EHCI version 1.0 Jan 5 17:41:18 iwix kernel: usb2: wrong number of companions (4 != 2) Jan 5 17:41:18 iwix kernel: usb2: companion controllers, 2 ports each: usb0 usb1 Jan 5 17:41:18 iwix kernel: usb2: on ehci0 Jan 5 17:41:18 iwix kernel: usb2: USB revision 2.0 Jan 5 17:41:18 iwix kernel: uhub2: on usb2 Jan 5 17:41:18 iwix kernel: uhub2: 8 ports with 8 removable, self powered Jan 5 17:41:18 iwix kernel: pcib2: at device 30.0 on pci0 Jan 5 17:41:18 iwix kernel: pci_link7: BIOS IRQ 11 for 6.7.INTA is invalid Jan 5 17:41:18 iwix kernel: pci_link6: BIOS IRQ 11 for 6.10.INTA is invalid Jan 5 17:41:18 iwix kernel: pci6: on pcib2 Jan 5 17:41:18 iwix kernel: iwi0: mem 0xb0009000-0xb0009fff irq 11 at device 4.0 on pci6 Jan 5 17:41:18 iwix kernel: iwi0: using obsoleted if_watchdog interface Jan 5 17:41:18 iwix kernel: iwi0: Ethernet address: 00:15:00:20:6e:4d Jan 5 17:41:18 iwix kernel: cbb0: at device 6.0 on pci6 Jan 5 17:41:18 iwix kernel: cardbus0: on cbb0 Jan 5 17:41:18 iwix kernel: pccard0: <16-bit PCCard bus> on cbb0 Jan 5 17:41:18 iwix kernel: pci6: at device 6.1 (no driver attached) Jan 5 17:41:18 iwix kernel: pci6: at device 6.2 (no driver attached) Jan 5 17:41:18 iwix kernel: rl0: port 0xa000-0xa0ff mem 0xb0008000-0xb00 080ff irq 10 at device 7.0 on pci6 Jan 5 17:41:18 iwix kernel: miibus0: on rl0 Jan 5 17:41:18 iwix kernel: rlphy0: on miibus0 Jan 5 17:41:18 iwix kernel: rlphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto Jan 5 17:41:18 iwix kernel: rl0: Ethernet address: 00:03:9d:75:b0:07 Jan 5 17:41:18 iwix kernel: fwohci0: mem 0xb0000000-0xb00007 ff,0xb0004000-0xb0007fff irq 9 at device 10.0 on pci6 Jan 5 17:41:18 iwix kernel: fwohci0: OHCI version 1.10 (ROM=0) Jan 5 17:41:18 iwix kernel: fwohci0: No. of Isochronous channels is 4. Jan 5 17:41:18 iwix kernel: fwohci0: EUI64 00:08:0d:03:9d:75:b0:07 Jan 5 17:41:18 iwix kernel: fwohci0: Phy 1394a available S400, 1 ports. Jan 5 17:41:18 iwix kernel: fwohci0: Link S400, max_rec 2048 bytes. Jan 5 17:41:18 iwix kernel: firewire0: on fwohci0 Jan 5 17:41:18 iwix kernel: fwe0: on firewire0 Jan 5 17:41:18 iwix kernel: if_fwe0: Fake Ethernet address: 02:08:0d:75:b0:07 Jan 5 17:41:18 iwix kernel: fwe0: Ethernet address: 02:08:0d:75:b0:07 Jan 5 17:41:18 iwix kernel: fwe0: if_start running deferred for Giant Jan 5 17:41:18 iwix kernel: sbp0: on firewire0 Jan 5 17:41:18 iwix kernel: fwohci0: Initiate bus reset Jan 5 17:41:18 iwix kernel: fwohci0: node_id=0xc000ffc0, gen=1, CYCLEMASTER mode Jan 5 17:41:18 iwix kernel: firewire0: 1 nodes, maxhop <= 0, cable IRM = 0 (me) Jan 5 17:41:18 iwix kernel: firewire0: bus manager 0 (me) Jan 5 17:41:18 iwix kernel: pcm0: port 0xe000-0xe0ff,0xe100-0xe13f mem 0xd000 0000-0xd00001ff,0xd0000200-0xd00002ff irq 10 at device 30.2 on pci0 Jan 5 17:41:18 iwix kernel: pcm0: Jan 5 17:41:18 iwix kernel: pci0: at device 30.3 (no driver attached) Jan 5 17:41:18 iwix kernel: isab0: at device 31.0 on pci0 Jan 5 17:41:18 iwix kernel: isa0: on isab0 Jan 5 17:41:18 iwix kernel: atapci0: port 0x1f0-0x1f7,0x3f6,0x170-0 x177,0x376,0x1100-0x110f at device 31.2 on pci0 Jan 5 17:41:18 iwix kernel: ata0: on atapci0 Jan 5 17:41:18 iwix kernel: ata1: on atapci0 Jan 5 17:41:18 iwix kernel: acpi_tz0: on acpi0 Jan 5 17:41:18 iwix kernel: acpi_tz1: on acpi0 Jan 5 17:41:18 iwix kernel: atkbdc0: port 0x60,0x64 irq 1 on acpi0 Jan 5 17:41:18 iwix kernel: atkbd0: irq 1 on atkbdc0 Jan 5 17:41:18 iwix kernel: kbd0 at atkbd0 Jan 5 17:41:18 iwix kernel: atkbd0: [GIANT-LOCKED] Jan 5 17:41:18 iwix kernel: psm0: irq 12 on atkbdc0 Jan 5 17:41:18 iwix kernel: psm0: [GIANT-LOCKED] Jan 5 17:41:18 iwix kernel: psm0: model Generic PS/2 mouse, device ID 0 Jan 5 17:41:18 iwix kernel: pmtimer0 on isa0 Jan 5 17:41:18 iwix kernel: orm0: at iomem 0xc0000-0xcffff,0xe0000-0xe1fff,0xe5000 -0xe5fff,0xeb000-0xeffff pnpid ORM0000 on isa0 Jan 5 17:41:18 iwix kernel: ppc0: parallel port not found. Jan 5 17:41:18 iwix kernel: sc0: at flags 0x100 on isa0 Jan 5 17:41:18 iwix kernel: sc0: VGA <16 virtual consoles, flags=0x300> Jan 5 17:41:18 iwix kernel: sio0: configured irq 4 not in bitmap of probed irqs 0 Jan 5 17:41:18 iwix kernel: sio0: port may not be enabled Jan 5 17:41:18 iwix kernel: sio0: configured irq 4 not in bitmap of probed irqs 0 Jan 5 17:41:18 iwix kernel: sio0: port may not be enabled Jan 5 17:41:18 iwix kernel: sio0 at port 0x3f8-0x3ff irq 4 flags 0x10 on isa0 Jan 5 17:41:18 iwix kernel: sio0: type 8250 or not responding Jan 5 17:41:18 iwix kernel: sio0: [FAST] Jan 5 17:41:18 iwix kernel: sio1: configured irq 3 not in bitmap of probed irqs 0 Jan 5 17:41:18 iwix kernel: sio1: port may not be enabled Jan 5 17:41:18 iwix kernel: vga0: at port 0x3c0-0x3df iomem 0xa0000-0xbffff on isa 0 Jan 5 17:41:18 iwix kernel: ums0: on uhub1 Jan 5 17:41:18 iwix kernel: ums0: 3 buttons and Z dir. Jan 5 17:41:18 iwix kernel: Timecounter "TSC" frequency 1729010984 Hz quality 800 Jan 5 17:41:18 iwix kernel: Timecounters tick every 1.000 msec Jan 5 17:41:18 iwix kernel: ad0: 57231MB at ata0-master SATA150 Jan 5 17:41:18 iwix kernel: acd0: DVDR at ata1-master UDMA33 Jan 5 17:41:18 iwix kernel: umass0: on uhub2 Jan 5 17:41:18 iwix kernel: Trying to mount root from ufs:/dev/ad0s1a Jan 5 17:41:18 iwix kernel: (probe0:umass-sim0:0:0:0): Uninitialized Transport 5:1? Jan 5 17:41:18 iwix kernel: da0 at umass-sim0 bus 0 target 0 lun 0 Jan 5 17:41:18 iwix kernel: da0: Removable Direct Access SCSI-2 device Jan 5 17:41:18 iwix kernel: da0: 40.000MB/s transfers Jan 5 17:41:18 iwix kernel: da0: 997MB (2042880 512 byte sectors: 64H 32S/T 997C) Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): SYNCHRONIZE CACHE. CDB: 35 0 0 0 0 0 0 0 0 0 Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): NOT READY asc:3a,0 Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): Medium not present Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): SYNCHRONIZE CACHE. CDB: 35 0 0 0 0 0 0 0 0 0 Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): NOT READY asc:3a,0 Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): Medium not present Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): SYNCHRONIZE CACHE. CDB: 35 0 0 0 0 0 0 0 0 0 Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): NOT READY asc:3a,0 Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): Medium not present Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): SYNCHRONIZE CACHE. CDB: 35 0 0 0 0 0 0 0 0 0 Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): NOT READY asc:3a,0 Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): Medium not present Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): SYNCHRONIZE CACHE. CDB: 35 0 0 0 0 0 0 0 0 0 Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): NOT READY asc:3a,0 Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): Medium not present Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): SYNCHRONIZE CACHE. CDB: 35 0 0 0 0 0 0 0 0 0 Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): NOT READY asc:3a,0 Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): Medium not present Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): SYNCHRONIZE CACHE. CDB: 35 0 0 0 0 0 0 0 0 0 Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): NOT READY asc:3a,0 Jan 5 17:41:18 iwix kernel: (da0:umass-sim0:0:0:0): Medium not present Jan 5 17:41:18 iwix savecore: no dumps found Jan 5 17:41:25 iwix login: ROOT LOGIN (root) ON ttyv0 Jan 5 17:41:32 iwix kernel: : mount pending error: blocks -1 files -1 Jan 5 17:44:40 iwix syslogd: kernel boot file is /boot/kernel/kernel There is no further entry that the machine immidiate reboot without any request! >How-To-Repeat: Try it (I wont try it any more ... I dont have a test machine) >Fix: >Release-Note: >Audit-Trail: >Unformatted: From owner-freebsd-usb@FreeBSD.ORG Sat Jan 6 22:00:28 2007 Return-Path: X-Original-To: freebsd-usb@hub.freebsd.org Delivered-To: freebsd-usb@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 47FF516A416 for ; Sat, 6 Jan 2007 22:00:28 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id 2189013C457 for ; Sat, 6 Jan 2007 22:00:28 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l06M0Rgw077710 for ; Sat, 6 Jan 2007 22:00:27 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l06M0RQ0077709; Sat, 6 Jan 2007 22:00:27 GMT (envelope-from gnats) Resent-Date: Sat, 6 Jan 2007 22:00:27 GMT Resent-Message-Id: <200701062200.l06M0RQ0077709@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-usb@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, "Valery V.Chikalov" Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 0EF1116A40F for ; Sat, 6 Jan 2007 21:53:00 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [69.147.83.33]) by mx1.freebsd.org (Postfix) with ESMTP id F1A5613C448 for ; Sat, 6 Jan 2007 21:52:59 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.13.1/8.13.1) with ESMTP id l06LqxNQ084847 for ; Sat, 6 Jan 2007 21:52:59 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.13.1/8.13.1/Submit) id l06LqxXW084846; Sat, 6 Jan 2007 21:52:59 GMT (envelope-from nobody) Message-Id: <200701062152.l06LqxXW084846@www.freebsd.org> Date: Sat, 6 Jan 2007 21:52:59 GMT From: "Valery V.Chikalov" To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.0 Cc: Subject: usb/107642: [patch]Ralink Technology RT2501USB/RT2601USB chipset driver X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 Jan 2007 22:00:28 -0000 >Number: 107642 >Category: usb >Synopsis: [patch]Ralink Technology RT2501USB/RT2601USB chipset driver >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-usb >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sat Jan 06 22:00:27 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Valery V.Chikalov >Release: 6.2-PRERELEASE >Organization: >Environment: FreeBSD hobbit.novakom.dp.ua 6.2-PRERELEASE FreeBSD 6.2-PRERELEASE #6: Sat Jan 6 20:38:38 EET 2007 root@hobbit.novakom.dp.ua:/usr/obj/usr/src/sys/HOBBIT i386 >Description: FreeBSD has no support for USB WiFi dongle with RT2501USB/RT2601USB chipset >How-To-Repeat: insert D-Link DWL-G122 H/W Ver.:C1 in computer with installed FreeBSD 6.2-PRERELEASE >Fix: make catalog /sys/modules/rt2573 make catalog /sys/modules/rum apply attached patch to run make(1) in /sys/modules/rt2573 you will need binary firmware data, I have gotten it from OpenBSD distribution ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/dev/microcode/rum/rum-rt2573 or from MSWindows driver which was included with device cd /sys/modules/rt2573 run make && make install cd /sys/modules/rum run make && make install && kldunload if_rum line for rc.conf: ifconfig_rum0="DHCP ssid YOURSSID bssid XX:XX:XX:XX:XX:XX authmode wpa" create wpa_supplicant.conf as: -----------cut here-------------- # allow frontend (e.g., wpa_cli) to be used by all users in 'wheel' group ctrl_interface=/var/run/wpa_supplicant ctrl_interface_group=wheel ap_scan=1 # # home network; allow all valid ciphers network={ ssid="YOURSSID" bssid=XX:XX:XX:XX:XX:XX scan_ssid=1 psk="YOURPASSWORD" } -----------cut here-------------- enjoy Patch attached with submission follows: Index: sys/dev/usb/if_rum.c =================================================================== *** /dev/null Sat Jan 6 21:44:00 2007 --- sys/dev/usb/if_rum.c Sat Jan 6 14:57:40 2007 *************** *** 0 **** --- 1,2301 ---- + /* $OpenBSD: if_rum.c,v 1.40 2006/09/18 16:20:20 damien Exp $ */ + /* $NetBSD: if_rum.c,v 1.2 2006/11/01 08:39:25 xtraeme Exp $ */ + + /*- + * Copyright (c) 2005, 2006 Damien Bergamini + * Copyright (c) 2006 Niall O'Higgins + * Copyright (c) 2006, 2007 Valery V.Chikalov + * + * 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. + */ + + /*- + * Ralink Technology RT2501USB/RT2601USB chipset driver + * http://www.ralinktech.com/ + */ + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + + #include + #include + + #include + #include + #include + #include + #include + + #include + #include + #include + #include "usbdevs.h" + + #include + #include + + #ifdef USB_DEBUG + #define RUM_DEBUG + #endif + + #ifdef RUM_DEBUG + #define DPRINTF(x) do { if (rum_debug) logprintf x; } while (0) + #define DPRINTFN(n, x) do { if (rum_debug >= (n)) logprintf x; } while (0) + int rum_debug = 0; + #else + #define DPRINTF(x) + #define DPRINTFN(n, x) + #endif + + /* various supported device vendors/products */ + static const struct usb_devno rum_devs[] = { + { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573 }, + { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573 }, + { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050A }, + { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D9050V3 }, + { USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB54GC }, + { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_C54RU2 }, + { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CWD854F }, + { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_RT2573 }, + { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWLG122C1 }, + { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA1340 }, + { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB01GS }, + { USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT2573 }, + { USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_RT2573 }, + { USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_RT2573 }, + { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573 }, + { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_2 }, + { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_3 }, + { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMM }, + { USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573 }, + { USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573_2 }, + { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573 }, + { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2671 }, + { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113R2 }, + { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL172 }, + { USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2573 } + }; + + MODULE_DEPEND(rum, wlan, 1, 1, 1); + MODULE_DEPEND(rum, firmware, 1, 1, 1); + + Static void rum_attachhook(void *); + + Static void rum_start(struct ifnet *); + Static void rum_watchdog(struct ifnet *); + + Static int rum_ioctl(struct ifnet *, u_long, caddr_t); + + Static int rum_alloc_tx_list(struct rum_softc *); + Static void rum_free_tx_list(struct rum_softc *); + Static int rum_alloc_rx_list(struct rum_softc *); + Static void rum_free_rx_list(struct rum_softc *); + + Static void rum_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); + Static void rum_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); + + Static int rum_media_change(struct ifnet *); + Static void rum_task(void *); + Static void rum_next_scan(void *); + Static int rum_newstate(struct ieee80211com *, enum ieee80211_state, int); + Static uint8_t rum_rxrate(struct rum_rx_desc *); + Static int rum_ack_rate(struct ieee80211com *, int); + Static uint16_t rum_txtime(int, int, uint32_t); + Static uint8_t rum_plcp_signal(int); + Static void rum_setup_tx_desc(struct rum_softc *, struct rum_tx_desc *, uint32_t, uint16_t, int, int); + Static int rum_tx_mgt(struct rum_softc *, struct mbuf *, struct ieee80211_node *); + Static int rum_tx_data(struct rum_softc *, struct mbuf *, struct ieee80211_node *); + + Static void rum_read_eeprom(struct rum_softc *); + Static void rum_eeprom_read(struct rum_softc *, uint16_t, void *, int); + Static uint32_t rum_read(struct rum_softc *, uint16_t); + Static void rum_read_multi(struct rum_softc *, uint16_t, void *, int); + Static void rum_write(struct rum_softc *, uint16_t, uint32_t); + Static void rum_write_multi(struct rum_softc *, uint16_t, void *, size_t); + + Static int rum_bbp_init(struct rum_softc *); + Static void rum_bbp_write(struct rum_softc *, uint8_t, uint8_t); + Static uint8_t rum_bbp_read(struct rum_softc *, uint8_t); + + Static const char *rum_get_rf(int); + Static void rum_rf_write(struct rum_softc *, uint8_t, uint32_t); + Static void rum_select_antenna(struct rum_softc *); + Static void rum_enable_mrr(struct rum_softc *); + Static void rum_set_txpreamble(struct rum_softc *); + Static void rum_set_basicrates(struct rum_softc *); + Static void rum_select_band(struct rum_softc *, struct ieee80211_channel *); + Static void rum_set_chan(struct rum_softc *, struct ieee80211_channel *); + Static void rum_enable_tsf_sync(struct rum_softc *); + Static void rum_update_slot(struct rum_softc *); + Static void rum_set_bssid(struct rum_softc *, const uint8_t *); + Static void rum_set_macaddr(struct rum_softc *, const uint8_t *); + Static void rum_update_promisc(struct rum_softc *); + + Static void rum_init(void *); + Static void rum_stop(struct ifnet *); + Static int rum_load_microcode(struct rum_softc *, const u_char *, size_t); + Static int rum_prepare_beacon(struct rum_softc *); + + Static void rum_amrr_start(struct rum_softc *, struct ieee80211_node *); + Static void rum_amrr_timeout(void *); + Static void rum_amrr_update(usbd_xfer_handle, usbd_private_handle, usbd_status status); + Static void rum_ratectl(struct rum_amrr *, struct ieee80211_node *); + + /* + * Supported rates for 802.11a/b/g modes (in 500Kbps unit). + */ + static const struct ieee80211_rateset rum_rateset_11a = + { 8, { 12, 18, 24, 36, 48, 72, 96, 108 } }; + + static const struct ieee80211_rateset rum_rateset_11b = + { 4, { 2, 4, 11, 22 } }; + + static const struct ieee80211_rateset rum_rateset_11g = + { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } }; + + static const struct { + uint32_t reg; + uint32_t val; + } rum_def_mac[] = { + RT2573_DEF_MAC + }; + + static const struct { + uint8_t reg; + uint8_t val; + } rum_def_bbp[] = { + RT2573_DEF_BBP + }; + + static const struct rfprog { + uint8_t chan; + uint32_t r1, r2, r3, r4; + } rum_rf5226[] = { + RT2573_RF5226 + }, rum_rf5225[] = { + RT2573_RF5225 + }; + + USB_DECLARE_DRIVER(rum); + + USB_MATCH(rum) + { + USB_MATCH_START(rum, uaa); + + if (uaa->iface != NULL) + return UMATCH_NONE; + + return (usb_lookup(rum_devs, uaa->vendor, uaa->product) != NULL) ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; + } + + Static void + rum_attachhook(void *xsc) + { + struct rum_softc *sc = xsc; + const char *name = "rt2573"; + struct firmware *fp; + + fp = firmware_get(name); + + if (fp == NULL || fp->datasize == 0) { + printf("%s: failed loadfirmware of file %s\n", + USBDEVNAME(sc->sc_dev), name); + return; + } else { + //MYDEBUG + printf("%s: firmware loaded: name: %s, size:%d\n", USBDEVNAME(sc->sc_dev), fp->name, fp->datasize); + } + + if (rum_load_microcode(sc, fp->data, fp->datasize) != 0) { + printf("%s: could not load 8051 microcode\n", + USBDEVNAME(sc->sc_dev)); + } + + } + + USB_ATTACH(rum) + { + USB_ATTACH_START(rum, sc, uaa); + struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = NULL; + usb_interface_descriptor_t *id; + usb_endpoint_descriptor_t *ed; + usbd_status error; + char devinfo[1024]; + int i, ntries; + uint32_t tmp; + + sc->sc_udev = uaa->device; + sc->sc_flags = 0; + + usbd_devinfo(sc->sc_udev, 0, devinfo); + USB_ATTACH_SETUP; + printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo); + + if (usbd_set_config_no(sc->sc_udev, RT2573_CONFIG_NO, 0) != 0) { + printf("%s: could not set configuration no\n", + USBDEVNAME(sc->sc_dev)); + USB_ATTACH_ERROR_RETURN; + } + + /* get the first interface handle */ + error = usbd_device2interface_handle(sc->sc_udev, RT2573_IFACE_INDEX, + &sc->sc_iface); + if (error != 0) { + printf("%s: could not get interface handle\n", + USBDEVNAME(sc->sc_dev)); + USB_ATTACH_ERROR_RETURN; + } + + /* + * Find endpoints. + */ + id = usbd_get_interface_descriptor(sc->sc_iface); + + sc->sc_rx_no = sc->sc_tx_no = -1; + for (i = 0; i < id->bNumEndpoints; i++) { + ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); + if (ed == NULL) { + printf("%s: no endpoint descriptor for iface %d\n", + USBDEVNAME(sc->sc_dev), i); + USB_ATTACH_ERROR_RETURN; + } + + if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) + sc->sc_rx_no = ed->bEndpointAddress; + else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) + sc->sc_tx_no = ed->bEndpointAddress; + } + if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) { + printf("%s: missing endpoint\n", USBDEVNAME(sc->sc_dev)); + USB_ATTACH_ERROR_RETURN; + } + + usb_init_task(&sc->sc_task, rum_task, sc); + callout_init(&sc->scan_ch, debug_mpsafenet ? CALLOUT_MPSAFE : 0); + callout_init(&sc->amrr_ch, 0); + + /* retrieve RT2573 rev. no */ + for (ntries = 0; ntries < 1000; ntries++) { + if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0) + break; + DELAY(1000); + } + if (ntries == 1000) { + printf("%s: timeout waiting for chip to settle\n", + USBDEVNAME(sc->sc_dev)); + USB_ATTACH_ERROR_RETURN; + } + + /* retrieve MAC address and various other things from EEPROM */ + rum_read_eeprom(sc); + + printf("%s: MAC/BBP RT%04x (rev 0x%05x), RF %s, address %s\n", + USBDEVNAME(sc->sc_dev), sc->macbbp_rev, tmp, + rum_get_rf(sc->rf_rev), ether_sprintf(ic->ic_myaddr)); + + ifp = sc->sc_ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) { + printf("%s: can not if_alloc()\n", USBDEVNAME(sc->sc_dev)); + USB_ATTACH_ERROR_RETURN; + } + + #if 1 + rum_attachhook(sc); + #endif + + ic->ic_ifp = ifp; + ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ + ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ + ic->ic_state = IEEE80211_S_INIT; + + /* set device capabilities */ + ic->ic_caps = + IEEE80211_C_IBSS | /* IBSS mode supported */ + IEEE80211_C_MONITOR | /* monitor mode supported */ + IEEE80211_C_HOSTAP | /* HostAp mode supported */ + IEEE80211_C_TXPMGT | /* tx power management */ + IEEE80211_C_SHPREAMBLE | /* short preamble supported */ + IEEE80211_C_SHSLOT | /* short slot time supported */ + IEEE80211_C_WPA; /* 802.11i */ + + if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226) { + /* set supported .11a rates */ + ic->ic_sup_rates[IEEE80211_MODE_11A] = rum_rateset_11a; + + /* set supported .11a channels */ + for (i = 34; i <= 46; i += 4) { + ic->ic_channels[i].ic_freq = + ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); + ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A; + } + for (i = 36; i <= 64; i += 4) { + ic->ic_channels[i].ic_freq = + ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); + ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A; + } + for (i = 100; i <= 140; i += 4) { + ic->ic_channels[i].ic_freq = + ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); + ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A; + } + for (i = 149; i <= 165; i += 4) { + ic->ic_channels[i].ic_freq = + ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); + ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A; + } + } + + /* set supported .11b and .11g rates */ + ic->ic_sup_rates[IEEE80211_MODE_11B] = rum_rateset_11b; + ic->ic_sup_rates[IEEE80211_MODE_11G] = rum_rateset_11g; + + /* set supported .11b and .11g channels (1 through 14) */ + for (i = 1; i <= 14; i++) { + ic->ic_channels[i].ic_freq = + ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); + ic->ic_channels[i].ic_flags = + IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | + IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; + } + + ifp->if_softc = sc; + if_initname(ifp, "rum", USBDEVUNIT(sc->sc_dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_init = rum_init; + ifp->if_ioctl = rum_ioctl; + ifp->if_start = rum_start; + ifp->if_watchdog = rum_watchdog; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); + + // if_attach(ifp); + ieee80211_ifattach(ic); + + /* override state transition machine */ + sc->sc_newstate = ic->ic_newstate; + ic->ic_newstate = rum_newstate; + ieee80211_media_init(ic, rum_media_change, ieee80211_media_status); + + #if NBPFILTER > 0 + bpfattach2(ifp, DLT_IEEE802_11_RADIO, + sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, &sc->sc_drvbpf); + + sc->sc_rxtap_len = sizeof sc->sc_rxtapu; + sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); + sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT); + + sc->sc_txtap_len = sizeof sc->sc_txtapu; + sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); + sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT); + #endif + + ieee80211_announce(ic); + + usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, + USBDEV(sc->sc_dev)); + + USB_ATTACH_SUCCESS_RETURN; + } + + USB_DETACH(rum) + { + USB_DETACH_START(rum, sc); + struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + int s; + + s = splusb(); + + rum_stop(ifp); + usb_rem_task(sc->sc_udev, &sc->sc_task); + callout_stop(&sc->scan_ch); + callout_stop(&sc->amrr_ch); + + if (sc->amrr_xfer != NULL) { + usbd_free_xfer(sc->amrr_xfer); + sc->amrr_xfer = NULL; + } + + if (sc->sc_rx_pipeh != NULL) { + usbd_abort_pipe(sc->sc_rx_pipeh); + usbd_close_pipe(sc->sc_rx_pipeh); + } + + if (sc->sc_tx_pipeh != NULL) { + usbd_abort_pipe(sc->sc_tx_pipeh); + usbd_close_pipe(sc->sc_tx_pipeh); + } + + rum_free_rx_list(sc); + rum_free_tx_list(sc); + + #if NBPFILTER > 0 + bpfdetach(ifp); + #endif + ieee80211_ifdetach(ic); /* free all nodes */ + if_detach(ifp); + + splx(s); + + usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, + USBDEV(sc->sc_dev)); + + return 0; + } + + Static int + rum_alloc_tx_list(struct rum_softc *sc) + { + struct rum_tx_data *data; + int i, error; + + sc->tx_queued = 0; + + for (i = 0; i < RT2573_TX_LIST_COUNT; i++) { + data = &sc->tx_data[i]; + + data->sc = sc; + + data->xfer = usbd_alloc_xfer(sc->sc_udev); + if (data->xfer == NULL) { + printf("%s: could not allocate tx xfer\n", + USBDEVNAME(sc->sc_dev)); + error = ENOMEM; + goto fail; + } + + data->buf = usbd_alloc_buffer(data->xfer, + RT2573_TX_DESC_SIZE + MCLBYTES); + if (data->buf == NULL) { + printf("%s: could not allocate tx buffer\n", + USBDEVNAME(sc->sc_dev)); + error = ENOMEM; + goto fail; + } + + /* clean Tx descriptor */ + bzero(data->buf, RT2573_TX_DESC_SIZE); + } + + return 0; + + fail: rum_free_tx_list(sc); + return error; + } + + Static void + rum_free_tx_list(struct rum_softc *sc) + { + struct rum_tx_data *data; + int i; + + for (i = 0; i < RT2573_TX_LIST_COUNT; i++) { + data = &sc->tx_data[i]; + + if (data->xfer != NULL) { + usbd_free_xfer(data->xfer); + data->xfer = NULL; + } + + if (data->ni != NULL) { + ieee80211_free_node(data->ni); + data->ni = NULL; + } + } + } + + Static int + rum_alloc_rx_list(struct rum_softc *sc) + { + struct rum_rx_data *data; + int i, error; + + for (i = 0; i < RT2573_RX_LIST_COUNT; i++) { + data = &sc->rx_data[i]; + + data->sc = sc; + + data->xfer = usbd_alloc_xfer(sc->sc_udev); + if (data->xfer == NULL) { + printf("%s: could not allocate rx xfer\n", + USBDEVNAME(sc->sc_dev)); + error = ENOMEM; + goto fail; + } + + if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) { + printf("%s: could not allocate rx buffer\n", + USBDEVNAME(sc->sc_dev)); + error = ENOMEM; + goto fail; + } + + MGETHDR(data->m, M_DONTWAIT, MT_DATA); + if (data->m == NULL) { + printf("%s: could not allocate rx mbuf\n", + USBDEVNAME(sc->sc_dev)); + error = ENOMEM; + goto fail; + } + + MCLGET(data->m, M_DONTWAIT); + if (!(data->m->m_flags & M_EXT)) { + printf("%s: could not allocate rx mbuf cluster\n", + USBDEVNAME(sc->sc_dev)); + error = ENOMEM; + goto fail; + } + + data->buf = mtod(data->m, uint8_t *); + } + + return 0; + + fail: rum_free_tx_list(sc); + return error; + } + + Static void + rum_free_rx_list(struct rum_softc *sc) + { + struct rum_rx_data *data; + int i; + + for (i = 0; i < RT2573_RX_LIST_COUNT; i++) { + data = &sc->rx_data[i]; + + if (data->xfer != NULL) { + usbd_free_xfer(data->xfer); + data->xfer = NULL; + } + + if (data->m != NULL) { + m_freem(data->m); + data->m = NULL; + } + } + } + + Static int + rum_media_change(struct ifnet *ifp) + { + struct rum_softc *sc = ifp->if_softc; + int error; + + error = ieee80211_media_change(ifp); + if (error != ENETRESET) + return error; + + if ((ifp->if_flags & IFF_UP) && + (ifp->if_drv_flags & IFF_DRV_RUNNING)) + rum_init(sc); + + return 0; + } + + /* + * This function is called periodically (every 200ms) during scanning to + * switch from one channel to another. + */ + Static void + rum_next_scan(void *arg) + { + struct rum_softc *sc = arg; + struct ieee80211com *ic = &sc->sc_ic; + + if (ic->ic_state == IEEE80211_S_SCAN) + ieee80211_next_scan(ic); + } + + Static void + rum_task(void *arg) + { + struct rum_softc *sc = arg; + struct ieee80211com *ic = &sc->sc_ic; + enum ieee80211_state ostate; + struct ieee80211_node *ni; + uint32_t tmp; + + ostate = ic->ic_state; + + switch (sc->sc_state) { + case IEEE80211_S_INIT: + if (ostate == IEEE80211_S_RUN) { + /* abort TSF synchronization */ + tmp = rum_read(sc, RT2573_TXRX_CSR9); + rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); + } + break; + + case IEEE80211_S_SCAN: + rum_set_chan(sc, ic->ic_curchan); + callout_reset(&sc->scan_ch, hz / 5, rum_next_scan, sc); + break; + + case IEEE80211_S_AUTH: + rum_set_chan(sc, ic->ic_curchan); + break; + + case IEEE80211_S_ASSOC: + rum_set_chan(sc, ic->ic_curchan); + break; + + case IEEE80211_S_RUN: + rum_set_chan(sc, ic->ic_curchan); + + ni = ic->ic_bss; + + if (ic->ic_opmode != IEEE80211_M_MONITOR) { + rum_update_slot(sc); + rum_enable_mrr(sc); + rum_set_txpreamble(sc); + rum_set_basicrates(sc); + rum_set_bssid(sc, ni->ni_bssid); + } + + if (ic->ic_opmode == IEEE80211_M_HOSTAP || + ic->ic_opmode == IEEE80211_M_IBSS) + rum_prepare_beacon(sc); + + if (ic->ic_opmode != IEEE80211_M_MONITOR) + rum_enable_tsf_sync(sc); + + /* enable automatic rate adaptation in STA mode */ + if (ic->ic_opmode == IEEE80211_M_STA && + ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) + rum_amrr_start(sc, ni); + + break; + } + + sc->sc_newstate(ic, sc->sc_state, -1); + } + + Static int + rum_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) + { + struct rum_softc *sc = ic->ic_ifp->if_softc; + + usb_rem_task(sc->sc_udev, &sc->sc_task); + callout_stop(&sc->scan_ch); + callout_stop(&sc->amrr_ch); + + /* do it in a process context */ + sc->sc_state = nstate; + usb_add_task(sc->sc_udev, &sc->sc_task); + + return 0; + } + + /* quickly determine if a given rate is CCK or OFDM */ + #define RUM_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22) + + #define RUM_ACK_SIZE 14 /* 10 + 4(FCS) */ + #define RUM_CTS_SIZE 14 /* 10 + 4(FCS) */ + + Static void + rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) + { + struct rum_tx_data *data = priv; + struct rum_softc *sc = data->sc; + struct ifnet *ifp = sc->sc_ifp; + int s; + + if (status != USBD_NORMAL_COMPLETION) { + if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) + return; + + printf("%s: could not transmit buffer: %s\n", + USBDEVNAME(sc->sc_dev), usbd_errstr(status)); + + if (status == USBD_STALLED) + usbd_clear_endpoint_stall_async(sc->sc_tx_pipeh); + + ifp->if_oerrors++; + return; + } + + s = splnet(); + + m_freem(data->m); + data->m = NULL; + ieee80211_free_node(data->ni); + data->ni = NULL; + + sc->tx_queued--; + ifp->if_opackets++; + + DPRINTFN(10, ("tx done\n")); + + sc->sc_tx_timer = 0; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + rum_start(ifp); + + splx(s); + } + + Static void + rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) + { + struct rum_rx_data *data = priv; + struct rum_softc *sc = data->sc; + struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct rum_rx_desc *desc; + struct ieee80211_frame *wh; + struct ieee80211_node *ni; + struct mbuf *mnew, *m; + int s, len; + + if (status != USBD_NORMAL_COMPLETION) { + if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) + return; + + if (status == USBD_STALLED) + usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh); + goto skip; + } + + usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); + + if (len < RT2573_RX_DESC_SIZE + sizeof (struct ieee80211_frame_min)) { + DPRINTF(("%s: xfer too short %d\n", USBDEVNAME(sc->sc_dev), + len)); + ifp->if_ierrors++; + goto skip; + } + + desc = (struct rum_rx_desc *)data->buf; + + if (le32toh(desc->flags) & RT2573_RX_CRC_ERROR) { + /* + * This should not happen since we did not request to receive + * those frames when we filled RT2573_TXRX_CSR0. + */ + DPRINTFN(5, ("CRC error\n")); + ifp->if_ierrors++; + goto skip; + } + + MGETHDR(mnew, M_DONTWAIT, MT_DATA); + if (mnew == NULL) { + printf("%s: could not allocate rx mbuf\n", + USBDEVNAME(sc->sc_dev)); + ifp->if_ierrors++; + goto skip; + } + + MCLGET(mnew, M_DONTWAIT); + if (!(mnew->m_flags & M_EXT)) { + printf("%s: could not allocate rx mbuf cluster\n", + USBDEVNAME(sc->sc_dev)); + m_freem(mnew); + ifp->if_ierrors++; + goto skip; + } + + m = data->m; + data->m = mnew; + data->buf = mtod(data->m, uint8_t *); + + /* finalize mbuf */ + m->m_pkthdr.rcvif = ifp; + m->m_data = (caddr_t)(desc + 1); + m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff; + + s = splnet(); + + if (sc->sc_drvbpf != NULL) { + struct rum_rx_radiotap_header *tap = &sc->sc_rxtap; + + tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; + tap->wr_rate = rum_rxrate(desc); + tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); + tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); + tap->wr_antenna = sc->rx_ant; + tap->wr_antsignal = desc->rssi; + + bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m); + } + + wh = mtod(m, struct ieee80211_frame *); + ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); + + /* send the frame to the 802.11 layer */ + ieee80211_input(ic, m, ni, desc->rssi, 0); + + /* node is no longer needed */ + ieee80211_free_node(ni); + + splx(s); + + DPRINTFN(15, ("rx done\n")); + + skip: /* setup a new transfer */ + usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data, data->buf, MCLBYTES, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof); + usbd_transfer(xfer); + } + + /* + * This function is only used by the Rx radiotap code. It returns the rate at + * which a given frame was received. + */ + Static uint8_t + rum_rxrate(struct rum_rx_desc *desc) + { + if (le32toh(desc->flags) & RT2573_RX_OFDM) { + /* reverse function of rum_plcp_signal */ + switch (desc->rate) { + case 0xb: return 12; + case 0xf: return 18; + case 0xa: return 24; + case 0xe: return 36; + case 0x9: return 48; + case 0xd: return 72; + case 0x8: return 96; + case 0xc: return 108; + } + } else { + if (desc->rate == 10) + return 2; + if (desc->rate == 20) + return 4; + if (desc->rate == 55) + return 11; + if (desc->rate == 110) + return 22; + } + return 2; /* should not get there */ + } + + /* + * Return the expected ack rate for a frame transmitted at rate `rate'. + * XXX: this should depend on the destination node basic rate set. + */ + Static int + rum_ack_rate(struct ieee80211com *ic, int rate) + { + switch (rate) { + /* CCK rates */ + case 2: + return 2; + case 4: + case 11: + case 22: + return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate; + + /* OFDM rates */ + case 12: + case 18: + return 12; + case 24: + case 36: + return 24; + case 48: + case 72: + case 96: + case 108: + return 48; + } + + /* default to 1Mbps */ + return 2; + } + + /* + * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'. + * The function automatically determines the operating mode depending on the + * given rate. `flags' indicates whether short preamble is in use or not. + */ + Static uint16_t + rum_txtime(int len, int rate, uint32_t flags) + { + uint16_t txtime; + + if (RUM_RATE_IS_OFDM(rate)) { + /* IEEE Std 802.11a-1999, pp. 37 */ + txtime = (8 + 4 * len + 3 + rate - 1) / rate; + txtime = 16 + 4 + 4 * txtime + 6; + } else { + /* IEEE Std 802.11b-1999, pp. 28 */ + txtime = (16 * len + rate - 1) / rate; + if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) + txtime += 72 + 24; + else + txtime += 144 + 48; + } + return txtime; + } + + Static uint8_t + rum_plcp_signal(int rate) + { + switch (rate) { + /* CCK rates (returned values are device-dependent) */ + case 2: return 0x0; + case 4: return 0x1; + case 11: return 0x2; + case 22: return 0x3; + + /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ + case 12: return 0xb; + case 18: return 0xf; + case 24: return 0xa; + case 36: return 0xe; + case 48: return 0x9; + case 72: return 0xd; + case 96: return 0x8; + case 108: return 0xc; + + /* unsupported rates (should not get there) */ + default: return 0xff; + } + } + + Static void + rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, + uint32_t flags, uint16_t xflags, int len, int rate) + { + struct ieee80211com *ic = &sc->sc_ic; + uint16_t plcp_length; + int remainder; + + desc->flags = htole32(flags); + desc->flags |= htole32(RT2573_TX_VALID); + desc->flags |= htole32(len << 16); + + desc->xflags = htole16(xflags); + + desc->wme = htole16( + RT2573_QID(0) | + RT2573_AIFSN(2) | + RT2573_LOGCWMIN(4) | + RT2573_LOGCWMAX(10)); + + /* setup PLCP fields */ + desc->plcp_signal = rum_plcp_signal(rate); + desc->plcp_service = 4; + + len += IEEE80211_CRC_LEN; + if (RUM_RATE_IS_OFDM(rate)) { + desc->flags |= htole32(RT2573_TX_OFDM); + + plcp_length = len & 0xfff; + desc->plcp_length_hi = plcp_length >> 6; + desc->plcp_length_lo = plcp_length & 0x3f; + } else { + plcp_length = (16 * len + rate - 1) / rate; + if (rate == 22) { + remainder = (16 * len) % 22; + if (remainder != 0 && remainder < 7) + desc->plcp_service |= RT2573_PLCP_LENGEXT; + } + desc->plcp_length_hi = plcp_length >> 8; + desc->plcp_length_lo = plcp_length & 0xff; + + if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) + desc->plcp_signal |= 0x08; + } + } + + #define RUM_TX_TIMEOUT 5000 + + Static int + rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) + { + struct ieee80211com *ic = &sc->sc_ic; + struct rum_tx_desc *desc; + struct rum_tx_data *data; + struct ieee80211_frame *wh; + uint32_t flags = 0; + uint16_t dur; + usbd_status error; + int xferlen, rate; + + data = &sc->tx_data[0]; + desc = (struct rum_tx_desc *)data->buf; + + rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; + + data->m = m0; + data->ni = ni; + + wh = mtod(m0, struct ieee80211_frame *); + + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { + flags |= RT2573_TX_ACK; + + dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate), + ic->ic_flags) + sc->sifs; + *(uint16_t *)wh->i_dur = htole16(dur); + + /* tell hardware to set timestamp in probe responses */ + if ((wh->i_fc[0] & + (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == + (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)) + flags |= RT2573_TX_TIMESTAMP; + } + + #if NBPFILTER > 0 + if (sc->sc_drvbpf != NULL) { + struct rum_tx_radiotap_header *tap = &sc->sc_txtap; + + tap->wt_flags = 0; + tap->wt_rate = rate; + tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); + tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); + tap->wt_antenna = sc->tx_ant; + + bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + } + #endif + + m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE); + rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate); + + /* align end on a 4-bytes boundary */ + xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3; + + /* + * No space left in the last URB to store the extra 4 bytes, force + * sending of another URB. + */ + if ((xferlen % 64) == 0) + xferlen += 4; + + DPRINTFN(10, ("sending msg frame len=%u rate=%u xfer len=%u\n", + m0->m_pkthdr.len + RT2573_TX_DESC_SIZE, rate, xferlen)); + + usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen, + USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof); + + error = usbd_transfer(data->xfer); + if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { + m_freem(m0); + return error; + } + + sc->tx_queued++; + + return 0; + } + + Static int + rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) + { + struct ieee80211com *ic = &sc->sc_ic; + struct rum_tx_desc *desc; + struct rum_tx_data *data; + struct ieee80211_frame *wh; + struct ieee80211_key *k; + uint32_t flags = 0; + uint16_t dur; + usbd_status error; + int xferlen, rate; + + wh = mtod(m0, struct ieee80211_frame *); + + if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) + rate = ic->ic_bss->ni_rates.rs_rates[ic->ic_fixed_rate]; + else + rate = ni->ni_rates.rs_rates[ni->ni_txrate]; + rate &= IEEE80211_RATE_VAL; + + if (wh->i_fc[1] & IEEE80211_FC1_WEP) { + k = ieee80211_crypto_encap(ic, ni, m0); + if (k == NULL) { + m_freem(m0); + return ENOBUFS; + } + + /* packet header may have moved, reset our local pointer */ + wh = mtod(m0, struct ieee80211_frame *); + } + + data = &sc->tx_data[0]; + desc = (struct rum_tx_desc *)data->buf; + + data->m = m0; + data->ni = ni; + + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { + flags |= RT2573_TX_ACK; + + dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate), + ic->ic_flags) + sc->sifs; + *(uint16_t *)wh->i_dur = htole16(dur); + } + + #if NBPFILTER > 0 + if (sc->sc_drvbpf != NULL) { + struct rum_tx_radiotap_header *tap = &sc->sc_txtap; + + tap->wt_flags = 0; + tap->wt_rate = rate; + tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); + tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); + tap->wt_antenna = sc->tx_ant; + + bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + } + #endif + + m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE); + rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate); + + /* align end on a 4-bytes boundary */ + xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3; + + /* + * No space left in the last URB to store the extra 4 bytes, force + * sending of another URB. + */ + if ((xferlen % 64) == 0) + xferlen += 4; + + DPRINTFN(10, ("sending data frame len=%u rate=%u xfer len=%u\n", + m0->m_pkthdr.len + RT2573_TX_DESC_SIZE, rate, xferlen)); + + usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen, + USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof); + + error = usbd_transfer(data->xfer); + if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { + m_freem(m0); + return error; + } + + sc->tx_queued++; + + return 0; + } + + Static void + rum_start(struct ifnet *ifp) + { + struct rum_softc *sc = ifp->if_softc; + struct ieee80211com *ic = &sc->sc_ic; + struct mbuf *m0; + struct ether_header *eh; + struct ieee80211_node *ni; + + for (;;) { + IF_POLL(&ic->ic_mgtq, m0); + if (m0 != NULL) { + if (sc->tx_queued >= RT2573_TX_LIST_COUNT) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + IF_DEQUEUE(&ic->ic_mgtq, m0); + + ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif; + m0->m_pkthdr.rcvif = NULL; + + if (ic->ic_rawbpf != NULL) + bpf_mtap(ic->ic_rawbpf, m0); + + if (rum_tx_mgt(sc, m0, ni) != 0) + break; + + } else { + if (ic->ic_state != IEEE80211_S_RUN) + break; + IFQ_POLL(&ifp->if_snd, m0); + if (m0 == NULL) + break; + if (sc->tx_queued >= RT2573_TX_LIST_COUNT) { + //FIXME + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + IFQ_DEQUEUE(&ifp->if_snd, m0); + if (m0->m_len < sizeof(struct ether_header) && + !(m0 = m_pullup(m0, sizeof(struct ether_header)))) + continue; + + eh = mtod(m0, struct ether_header *); + ni = ieee80211_find_txnode(ic, eh->ether_dhost); + if (ni == NULL) { + m_freem(m0); + continue; + } + if (ifp->if_bpf != NULL) + bpf_mtap(ifp->if_bpf, m0); + m0 = ieee80211_encap(ic, m0, ni); + if (m0 == NULL) { + ieee80211_free_node(ni); + continue; + } + + if (ic->ic_rawbpf != NULL) + bpf_mtap(ic->ic_rawbpf, m0); + + if (rum_tx_data(sc, m0, ni) != 0) { + ieee80211_free_node(ni); + ifp->if_oerrors++; + break; + } + } + + sc->sc_tx_timer = 5; + ifp->if_timer = 1; + } + } + + Static void + rum_watchdog(struct ifnet *ifp) + { + struct rum_softc *sc = ifp->if_softc; + struct ieee80211com *ic = &sc->sc_ic; + + ifp->if_timer = 0; + + if (sc->sc_tx_timer > 0) { + if (--sc->sc_tx_timer == 0) { + printf("%s: device timeout\n", USBDEVNAME(sc->sc_dev)); + /*rum_init(ifp); XXX needs a process context! */ + ifp->if_oerrors++; + return; + } + ifp->if_timer = 1; + } + + ieee80211_watchdog(ic); + } + + Static int + rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) + { + struct rum_softc *sc = ifp->if_softc; + struct ieee80211com *ic = &sc->sc_ic; + int s, error = 0; + + s = splnet(); + + switch (cmd) { + case SIOCSIFFLAGS: + if (ifp->if_flags & IFF_UP) { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + rum_update_promisc(sc); + else + rum_init(sc); + } else { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + rum_stop(ifp); + } + break; + + default: + error = ieee80211_ioctl(ic, cmd, data); + } + + if (error == ENETRESET) { + if ((ifp->if_flags & IFF_UP) && + (ifp->if_drv_flags & IFF_DRV_RUNNING)) + rum_init(sc); + error = 0; + } + + splx(s); + + return error; + } + + Static void + rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len) + { + usb_device_request_t req; + usbd_status error; + + req.bmRequestType = UT_READ_VENDOR_DEVICE; + req.bRequest = RT2573_READ_EEPROM; + USETW(req.wValue, 0); + USETW(req.wIndex, addr); + USETW(req.wLength, len); + + error = usbd_do_request(sc->sc_udev, &req, buf); + if (error != 0) { + printf("%s: could not read EEPROM: %s\n", + USBDEVNAME(sc->sc_dev), usbd_errstr(error)); + } + } + + Static uint32_t + rum_read(struct rum_softc *sc, uint16_t reg) + { + uint32_t val; + + rum_read_multi(sc, reg, &val, sizeof val); + + return le32toh(val); + } + + Static void + rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len) + { + usb_device_request_t req; + usbd_status error; + + req.bmRequestType = UT_READ_VENDOR_DEVICE; + req.bRequest = RT2573_READ_MULTI_MAC; + USETW(req.wValue, 0); + USETW(req.wIndex, reg); + USETW(req.wLength, len); + + error = usbd_do_request(sc->sc_udev, &req, buf); + if (error != 0) { + printf("%s: could not multi read MAC register: %s\n", + USBDEVNAME(sc->sc_dev), usbd_errstr(error)); + } + } + + Static void + rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val) + { + uint32_t tmp = htole32(val); + + rum_write_multi(sc, reg, &tmp, sizeof tmp); + } + + Static void + rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len) + { + usb_device_request_t req; + usbd_status error; + + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = RT2573_WRITE_MULTI_MAC; + USETW(req.wValue, 0); + USETW(req.wIndex, reg); + USETW(req.wLength, len); + + error = usbd_do_request(sc->sc_udev, &req, buf); + if (error != 0) { + printf("%s: could not multi write MAC register: %s\n", + USBDEVNAME(sc->sc_dev), usbd_errstr(error)); + } + } + + Static void + rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val) + { + uint32_t tmp; + int ntries; + + for (ntries = 0; ntries < 5; ntries++) { + if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY)) + break; + } + if (ntries == 5) { + printf("%s: could not write to BBP\n", USBDEVNAME(sc->sc_dev)); + return; + } + + tmp = RT2573_BBP_BUSY | (reg & 0x7f) << 8 | val; + rum_write(sc, RT2573_PHY_CSR3, tmp); + } + + Static uint8_t + rum_bbp_read(struct rum_softc *sc, uint8_t reg) + { + uint32_t val; + int ntries; + + for (ntries = 0; ntries < 5; ntries++) { + if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY)) + break; + } + if (ntries == 5) { + printf("%s: could not read BBP\n", USBDEVNAME(sc->sc_dev)); + return 0; + } + + val = RT2573_BBP_BUSY | RT2573_BBP_READ | reg << 8; + rum_write(sc, RT2573_PHY_CSR3, val); + + for (ntries = 0; ntries < 100; ntries++) { + val = rum_read(sc, RT2573_PHY_CSR3); + if (!(val & RT2573_BBP_BUSY)) + return val & 0xff; + DELAY(1); + } + + printf("%s: could not read BBP\n", USBDEVNAME(sc->sc_dev)); + return 0; + } + + Static void + rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val) + { + uint32_t tmp; + int ntries; + + for (ntries = 0; ntries < 5; ntries++) { + if (!(rum_read(sc, RT2573_PHY_CSR4) & RT2573_RF_BUSY)) + break; + } + if (ntries == 5) { + printf("%s: could not write to RF\n", USBDEVNAME(sc->sc_dev)); + return; + } + + tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | (val & 0xfffff) << 2 | + (reg & 3); + rum_write(sc, RT2573_PHY_CSR4, tmp); + + /* remember last written value in sc */ + sc->rf_regs[reg] = val; + + DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff)); + } + + Static void + rum_select_antenna(struct rum_softc *sc) + { + uint8_t bbp4, bbp77; + uint32_t tmp; + + bbp4 = rum_bbp_read(sc, 4); + bbp77 = rum_bbp_read(sc, 77); + + /* TBD */ + + /* make sure Rx is disabled before switching antenna */ + tmp = rum_read(sc, RT2573_TXRX_CSR0); + rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX); + + rum_bbp_write(sc, 4, bbp4); + rum_bbp_write(sc, 77, bbp77); + + rum_write(sc, RT2573_TXRX_CSR0, tmp); + } + + /* + * Enable multi-rate retries for frames sent at OFDM rates. + * In 802.11b/g mode, allow fallback to CCK rates. + */ + Static void + rum_enable_mrr(struct rum_softc *sc) + { + struct ieee80211com *ic = &sc->sc_ic; + uint32_t tmp; + + tmp = rum_read(sc, RT2573_TXRX_CSR4); + + tmp &= ~RT2573_MRR_CCK_FALLBACK; + if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) + tmp |= RT2573_MRR_CCK_FALLBACK; + tmp |= RT2573_MRR_ENABLED; + + rum_write(sc, RT2573_TXRX_CSR4, tmp); + } + + Static void + rum_set_txpreamble(struct rum_softc *sc) + { + uint32_t tmp; + + tmp = rum_read(sc, RT2573_TXRX_CSR4); + + tmp &= ~RT2573_SHORT_PREAMBLE; + if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE) + tmp |= RT2573_SHORT_PREAMBLE; + + rum_write(sc, RT2573_TXRX_CSR4, tmp); + } + + Static void + rum_set_basicrates(struct rum_softc *sc) + { + struct ieee80211com *ic = &sc->sc_ic; + + /* update basic rate set */ + if (ic->ic_curmode == IEEE80211_MODE_11B) { + /* 11b basic rates: 1, 2Mbps */ + rum_write(sc, RT2573_TXRX_CSR5, 0x3); + } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan)) { + /* 11a basic rates: 6, 12, 24Mbps */ + rum_write(sc, RT2573_TXRX_CSR5, 0x150); + } else { + /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */ + rum_write(sc, RT2573_TXRX_CSR5, 0x15f); + } + } + + /* + * Reprogram MAC/BBP to switch to a new band. Values taken from the reference + * driver. + */ + Static void + rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c) + { + uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104; + uint32_t tmp; + + /* update all BBP registers that depend on the band */ + bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c; + bbp35 = 0x50; bbp97 = 0x48; bbp98 = 0x48; + if (IEEE80211_IS_CHAN_5GHZ(c)) { + bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c; + bbp35 += 0x10; bbp97 += 0x10; bbp98 += 0x10; + } + if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) || + (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) { + bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10; + } + + sc->bbp17 = bbp17; + rum_bbp_write(sc, 17, bbp17); + rum_bbp_write(sc, 96, bbp96); + rum_bbp_write(sc, 104, bbp104); + + if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) || + (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) { + rum_bbp_write(sc, 75, 0x80); + rum_bbp_write(sc, 86, 0x80); + rum_bbp_write(sc, 88, 0x80); + } + + rum_bbp_write(sc, 35, bbp35); + rum_bbp_write(sc, 97, bbp97); + rum_bbp_write(sc, 98, bbp98); + + tmp = rum_read(sc, RT2573_PHY_CSR0); + tmp &= ~(RT2573_PA_PE_2GHZ | RT2573_PA_PE_5GHZ); + if (IEEE80211_IS_CHAN_2GHZ(c)) + tmp |= RT2573_PA_PE_2GHZ; + else + tmp |= RT2573_PA_PE_5GHZ; + rum_write(sc, RT2573_PHY_CSR0, tmp); + + /* 802.11a uses a 16 microseconds short interframe space */ + sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10; + } + + Static void + rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c) + { + struct ieee80211com *ic = &sc->sc_ic; + const struct rfprog *rfprog; + uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT; + int8_t power; + u_int i, chan; + + chan = ieee80211_chan2ieee(ic, c); + if (chan == 0 || chan == IEEE80211_CHAN_ANY) + return; + + /* select the appropriate RF settings based on what EEPROM says */ + rfprog = (sc->rf_rev == RT2573_RF_5225 || + sc->rf_rev == RT2573_RF_2527) ? rum_rf5225 : rum_rf5226; + + /* find the settings for this channel (we know it exists) */ + for (i = 0; rfprog[i].chan != chan; i++); + + power = sc->txpow[i]; + if (power < 0) { + bbp94 += power; + power = 0; + } else if (power > 31) { + bbp94 += power - 31; + power = 31; + } + + /* + * If we are switching from the 2GHz band to the 5GHz band or + * vice-versa, BBP registers need to be reprogrammed. + */ + if (c->ic_flags != ic->ic_curchan->ic_flags) { + rum_select_band(sc, c); + rum_select_antenna(sc); + } + ic->ic_curchan = c; + + rum_rf_write(sc, RT2573_RF1, rfprog[i].r1); + rum_rf_write(sc, RT2573_RF2, rfprog[i].r2); + rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7); + rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10); + + rum_rf_write(sc, RT2573_RF1, rfprog[i].r1); + rum_rf_write(sc, RT2573_RF2, rfprog[i].r2); + rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7 | 1); + rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10); + + rum_rf_write(sc, RT2573_RF1, rfprog[i].r1); + rum_rf_write(sc, RT2573_RF2, rfprog[i].r2); + rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7); + rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10); + + DELAY(10); + + /* enable smart mode for MIMO-capable RFs */ + bbp3 = rum_bbp_read(sc, 3); + + bbp3 &= ~RT2573_SMART_MODE; + if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_2527) + bbp3 |= RT2573_SMART_MODE; + + rum_bbp_write(sc, 3, bbp3); + + if (bbp94 != RT2573_BBPR94_DEFAULT) + rum_bbp_write(sc, 94, bbp94); + } + + /* + * Enable TSF synchronization and tell h/w to start sending beacons for IBSS + * and HostAP operating modes. + */ + Static void + rum_enable_tsf_sync(struct rum_softc *sc) + { + struct ieee80211com *ic = &sc->sc_ic; + uint32_t tmp; + + if (ic->ic_opmode != IEEE80211_M_STA) { + /* + * Change default 16ms TBTT adjustment to 8ms. + * Must be done before enabling beacon generation. + */ + rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8); + } + + tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000; + + /* set beacon interval (in 1/16ms unit) */ + tmp |= ic->ic_bss->ni_intval * 16; + + tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT; + if (ic->ic_opmode == IEEE80211_M_STA) + tmp |= RT2573_TSF_MODE(1); + else + tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON; + + rum_write(sc, RT2573_TXRX_CSR9, tmp); + } + + Static void + rum_update_slot(struct rum_softc *sc) + { + struct ieee80211com *ic = &sc->sc_ic; + uint8_t slottime; + uint32_t tmp; + + slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; + + tmp = rum_read(sc, RT2573_MAC_CSR9); + tmp = (tmp & ~0xff) | slottime; + rum_write(sc, RT2573_MAC_CSR9, tmp); + + DPRINTF(("setting slot time to %uus\n", slottime)); + } + + Static void + rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid) + { + uint32_t tmp; + + tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24; + rum_write(sc, RT2573_MAC_CSR4, tmp); + + tmp = bssid[4] | bssid[5] << 8 | RT2573_ONE_BSSID << 16; + rum_write(sc, RT2573_MAC_CSR5, tmp); + } + + Static void + rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr) + { + uint32_t tmp; + + tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24; + rum_write(sc, RT2573_MAC_CSR2, tmp); + + tmp = addr[4] | addr[5] << 8 | 0xff << 16; + rum_write(sc, RT2573_MAC_CSR3, tmp); + } + + Static void + rum_update_promisc(struct rum_softc *sc) + { + struct ifnet *ifp = sc->sc_ic.ic_ifp; + uint32_t tmp; + + tmp = rum_read(sc, RT2573_TXRX_CSR0); + + tmp &= ~RT2573_DROP_NOT_TO_ME; + if (!(ifp->if_flags & IFF_PROMISC)) + tmp |= RT2573_DROP_NOT_TO_ME; + + rum_write(sc, RT2573_TXRX_CSR0, tmp); + + DPRINTF(("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ? + "entering" : "leaving")); + } + + Static const char * + rum_get_rf(int rev) + { + switch (rev) { + case RT2573_RF_2527: return "RT2527 (MIMO XR)"; + case RT2573_RF_2528: return "RT2528"; + case RT2573_RF_5225: return "RT5225 (MIMO XR)"; + case RT2573_RF_5226: return "RT5226"; + default: return "unknown"; + } + } + + Static void + rum_read_eeprom(struct rum_softc *sc) + { + struct ieee80211com *ic = &sc->sc_ic; + uint16_t val; + #ifdef RUM_DEBUG + int i; + #endif + + /* read MAC/BBP type */ + rum_eeprom_read(sc, RT2573_EEPROM_MACBBP, &val, 2); + sc->macbbp_rev = le16toh(val); + + /* read MAC address */ + rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, ic->ic_myaddr, 6); + + rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2); + val = le16toh(val); + sc->rf_rev = (val >> 11) & 0x1f; + sc->hw_radio = (val >> 10) & 0x1; + sc->rx_ant = (val >> 4) & 0x3; + sc->tx_ant = (val >> 2) & 0x3; + sc->nb_ant = val & 0x3; + + DPRINTF(("RF revision=%d\n", sc->rf_rev)); + + rum_eeprom_read(sc, RT2573_EEPROM_CONFIG2, &val, 2); + val = le16toh(val); + sc->ext_5ghz_lna = (val >> 6) & 0x1; + sc->ext_2ghz_lna = (val >> 4) & 0x1; + + DPRINTF(("External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n", + sc->ext_2ghz_lna, sc->ext_5ghz_lna)); + + rum_eeprom_read(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET, &val, 2); + val = le16toh(val); + if ((val & 0xff) != 0xff) + sc->rssi_2ghz_corr = (int8_t)(val & 0xff); /* signed */ + + rum_eeprom_read(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET, &val, 2); + val = le16toh(val); + if ((val & 0xff) != 0xff) + sc->rssi_5ghz_corr = (int8_t)(val & 0xff); /* signed */ + + DPRINTF(("RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n", + sc->rssi_2ghz_corr, sc->rssi_5ghz_corr)); + + rum_eeprom_read(sc, RT2573_EEPROM_FREQ_OFFSET, &val, 2); + val = le16toh(val); + if ((val & 0xff) != 0xff) + sc->rffreq = val & 0xff; + + DPRINTF(("RF freq=%d\n", sc->rffreq)); + + /* read Tx power for all a/b/g channels */ + rum_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->txpow, 14); + /* XXX default Tx power for 802.11a channels */ + memset(sc->txpow + 14, 24, sizeof (sc->txpow) - 14); + #ifdef RUM_DEBUG + for (i = 0; i < 14; i++) + DPRINTF(("Channel=%d Tx power=%d\n", i + 1, sc->txpow[i])); + #endif + + /* read default values for BBP registers */ + rum_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16); + #ifdef RUM_DEBUG + for (i = 0; i < 14; i++) { + if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff) + continue; + DPRINTF(("BBP R%d=%02x\n", sc->bbp_prom[i].reg, + sc->bbp_prom[i].val)); + } + #endif + } + + Static int + rum_bbp_init(struct rum_softc *sc) + { + #define N(a) (sizeof (a) / sizeof ((a)[0])) + int i, ntries; + uint8_t val; + + /* wait for BBP to be ready */ + for (ntries = 0; ntries < 100; ntries++) { + val = rum_bbp_read(sc, 0); + if (val != 0 && val != 0xff) + break; + DELAY(1000); + } + if (ntries == 100) { + printf("%s: timeout waiting for BBP\n", + USBDEVNAME(sc->sc_dev)); + return EIO; + } + + /* initialize BBP registers to default values */ + for (i = 0; i < N(rum_def_bbp); i++) + rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val); + + /* write vendor-specific BBP values (from EEPROM) */ + for (i = 0; i < 16; i++) { + if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff) + continue; + rum_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val); + } + + return 0; + #undef N + } + + Static void + rum_init(void *priv) + { + #define N(a) (sizeof (a) / sizeof ((a)[0])) + struct rum_softc *sc = priv; + struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = ic->ic_ifp; + struct rum_rx_data *data; + uint32_t tmp; + usbd_status error = 0; + int i, ntries; + + // if ((sc->sc_flags & RT2573_FWLOADED) == 0) { + // rum_attachhook(sc); + // } + + rum_stop(ifp); + + /* initialize MAC registers to default values */ + for (i = 0; i < N(rum_def_mac); i++) + rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val); + + /* set host ready */ + rum_write(sc, RT2573_MAC_CSR1, 3); + rum_write(sc, RT2573_MAC_CSR1, 0); + + /* wait for BBP/RF to wakeup */ + for (ntries = 0; ntries < 1000; ntries++) { + if (rum_read(sc, RT2573_MAC_CSR12) & 8) + break; + rum_write(sc, RT2573_MAC_CSR12, 4); /* force wakeup */ + DELAY(1000); + } + if (ntries == 1000) { + printf("%s: timeout waiting for BBP/RF to wakeup\n", + USBDEVNAME(sc->sc_dev)); + goto fail; + } + + if ((error = rum_bbp_init(sc)) != 0) + goto fail; + + /* select default channel */ + rum_select_band(sc, ic->ic_curchan); + rum_select_antenna(sc); + rum_set_chan(sc, ic->ic_curchan); + + /* clear STA registers */ + rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta); + + IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); + rum_set_macaddr(sc, ic->ic_myaddr); + + /* initialize ASIC */ + rum_write(sc, RT2573_MAC_CSR1, 4); + + /* + * Allocate xfer for AMRR statistics requests. + */ + sc->amrr_xfer = usbd_alloc_xfer(sc->sc_udev); + if (sc->amrr_xfer == NULL) { + printf("%s: could not allocate AMRR xfer\n", + USBDEVNAME(sc->sc_dev)); + goto fail; + } + + /* + * Open Tx and Rx USB bulk pipes. + */ + error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE, + &sc->sc_tx_pipeh); + if (error != 0) { + printf("%s: could not open Tx pipe: %s\n", + USBDEVNAME(sc->sc_dev), usbd_errstr(error)); + goto fail; + } + + error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE, + &sc->sc_rx_pipeh); + if (error != 0) { + printf("%s: could not open Rx pipe: %s\n", + USBDEVNAME(sc->sc_dev), usbd_errstr(error)); + goto fail; + } + + /* + * Allocate Tx and Rx xfer queues. + */ + error = rum_alloc_tx_list(sc); + if (error != 0) { + printf("%s: could not allocate Tx list\n", + USBDEVNAME(sc->sc_dev)); + goto fail; + } + + error = rum_alloc_rx_list(sc); + if (error != 0) { + printf("%s: could not allocate Rx list\n", + USBDEVNAME(sc->sc_dev)); + goto fail; + } + + /* + * Start up the receive pipe. + */ + for (i = 0; i < RT2573_RX_LIST_COUNT; i++) { + data = &sc->rx_data[i]; + + usbd_setup_xfer(data->xfer, sc->sc_rx_pipeh, data, data->buf, + MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof); + usbd_transfer(data->xfer); + } + + /* update Rx filter */ + tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff; + + tmp |= RT2573_DROP_PHY_ERROR | RT2573_DROP_CRC_ERROR; + if (ic->ic_opmode != IEEE80211_M_MONITOR) { + tmp |= RT2573_DROP_CTL | RT2573_DROP_VER_ERROR | + RT2573_DROP_ACKCTS; + if (ic->ic_opmode != IEEE80211_M_HOSTAP) + tmp |= RT2573_DROP_TODS; + if (!(ifp->if_flags & IFF_PROMISC)) + tmp |= RT2573_DROP_NOT_TO_ME; + } + rum_write(sc, RT2573_TXRX_CSR0, tmp); + + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + ifp->if_drv_flags |= IFF_DRV_RUNNING; + + if (ic->ic_opmode == IEEE80211_M_MONITOR) + ieee80211_new_state(ic, IEEE80211_S_RUN, -1); + else + ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); + + return; + + fail: rum_stop(ifp); + return; + #undef N + } + + Static void + rum_stop(struct ifnet *ifp) + { + struct rum_softc *sc = ifp->if_softc; + struct ieee80211com *ic = &sc->sc_ic; + uint32_t tmp; + + ieee80211_new_state(ic, IEEE80211_S_INIT, -1); /* free all nodes */ + + sc->sc_tx_timer = 0; + ifp->if_timer = 0; + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + + /* disable Rx */ + tmp = rum_read(sc, RT2573_TXRX_CSR0); + rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX); + + /* reset ASIC */ + rum_write(sc, RT2573_MAC_CSR1, 3); + rum_write(sc, RT2573_MAC_CSR1, 0); + + if (sc->sc_rx_pipeh != NULL) { + usbd_abort_pipe(sc->sc_rx_pipeh); + usbd_close_pipe(sc->sc_rx_pipeh); + sc->sc_rx_pipeh = NULL; + } + + if (sc->sc_tx_pipeh != NULL) { + usbd_abort_pipe(sc->sc_tx_pipeh); + usbd_close_pipe(sc->sc_tx_pipeh); + sc->sc_tx_pipeh = NULL; + } + + rum_free_rx_list(sc); + rum_free_tx_list(sc); + } + + Static int + rum_load_microcode(struct rum_softc *sc, const u_char *ucode, size_t size) + { + usb_device_request_t req; + uint16_t reg = RT2573_MCU_CODE_BASE; + usbd_status error; + + /* copy firmware image into NIC */ + for (; size >= 4; reg += 4, ucode += 4, size -= 4) + rum_write(sc, reg, UGETDW(ucode)); + + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = RT2573_MCU_CNTL; + USETW(req.wValue, RT2573_MCU_RUN); + USETW(req.wIndex, 0); + USETW(req.wLength, 0); + + error = usbd_do_request(sc->sc_udev, &req, NULL); + if (error != 0) { + printf("%s: could not run firmware: %s\n", + USBDEVNAME(sc->sc_dev), usbd_errstr(error)); + } + return error; + } + + Static int + rum_prepare_beacon(struct rum_softc *sc) + { + struct ieee80211com *ic = &sc->sc_ic; + struct rum_tx_desc desc; + struct mbuf *m0; + int rate; + + m0 = ieee80211_beacon_alloc(ic, ic->ic_bss, &sc->sc_bo); + if (m0 == NULL) { + printf("%s: could not allocate beacon frame\n", + USBDEVNAME(sc->sc_dev)); + return ENOBUFS; + } + + /* send beacons at the lowest available rate */ + rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; + + rum_setup_tx_desc(sc, &desc, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ, + m0->m_pkthdr.len, rate); + + /* copy the first 24 bytes of Tx descriptor into NIC memory */ + rum_write_multi(sc, RT2573_HW_BEACON_BASE0, (uint8_t *)&desc, 24); + + /* copy beacon header and payload into NIC memory */ + rum_write_multi(sc, RT2573_HW_BEACON_BASE0 + 24, mtod(m0, uint8_t *), + m0->m_pkthdr.len); + + m_freem(m0); + + return 0; + } + + #define RUM_AMRR_MIN_SUCCESS_THRESHOLD 1 + #define RUM_AMRR_MAX_SUCCESS_THRESHOLD 10 + + Static void + rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni) + { + struct rum_amrr *amrr = &sc->amrr; + int i; + + /* clear statistic registers (STA_CSR0 to STA_CSR5) */ + rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta); + + amrr->success = 0; + amrr->recovery = 0; + amrr->txcnt = amrr->retrycnt = 0; + amrr->success_threshold = RUM_AMRR_MIN_SUCCESS_THRESHOLD; + + // ieee80211_amrr_node_init(&sc->amrr, &sc->amn); + + /* set rate to some reasonable initial value */ + for (i = ni->ni_rates.rs_nrates - 1; + i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72; + i--); + ni->ni_txrate = i; + + callout_reset(&sc->amrr_ch, hz, rum_amrr_timeout, sc); + } + + Static void + rum_amrr_timeout(void *arg) + { + struct rum_softc *sc = arg; + usb_device_request_t req; + int s; + + s = splusb(); + + /* + * Asynchronously read statistic registers (cleared by read). + */ + req.bmRequestType = UT_READ_VENDOR_DEVICE; + req.bRequest = RT2573_READ_MULTI_MAC; + USETW(req.wValue, 0); + USETW(req.wIndex, RT2573_STA_CSR0); + USETW(req.wLength, sizeof sc->sta); + + usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, sc, + USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof sc->sta, 0, + rum_amrr_update); + (void)usbd_transfer(sc->amrr_xfer); + + splx(s); + } + + Static void + rum_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv, + usbd_status status) + { + struct rum_softc *sc = (struct rum_softc *)priv; + struct rum_amrr *amrr = &sc->amrr; + struct ifnet *ifp = sc->sc_ifp; //FIXME1 + + if (status != USBD_NORMAL_COMPLETION) { + device_printf(sc->sc_dev, "could not retrieve Tx statistics - " + "cancelling automatic rate control\n"); + return; + } + + /* count TX retry-fail as Tx errors */ + ifp->if_oerrors += le32toh(sc->sta[5]) >> 16; + + amrr->retrycnt = + (le32toh(sc->sta[4]) >> 16) + /* TX one-retry ok count */ + (le32toh(sc->sta[5]) & 0xffff) + /* TX more-retry ok count */ + (le32toh(sc->sta[5]) >> 16); /* TX retry-fail count */ + + amrr->txcnt = + amrr->retrycnt + + (le32toh(sc->sta[4]) & 0xffff); /* TX no-retry ok count */ + + rum_ratectl(amrr, sc->sc_ic.ic_bss); + + callout_reset(&sc->amrr_ch, hz, rum_amrr_timeout, sc); + } + + /*- + * Naive implementation of the Adaptive Multi Rate Retry algorithm: + * "IEEE 802.11 Rate Adaptation: A Practical Approach" + * Mathieu Lacage, Hossein Manshaei, Thierry Turletti + * INRIA Sophia - Projet Planete + * http://www-sop.inria.fr/rapports/sophia/RR-5208.html + * + * This algorithm is particularly well suited for rum since it does not + * require per-frame retry statistics. Note however that since h/w does + * not provide per-frame stats, we can't do per-node rate adaptation and + * thus automatic rate adaptation is only enabled in STA operating mode. + */ + #define is_success(amrr) \ + ((amrr)->retrycnt < (amrr)->txcnt / 10) + #define is_failure(amrr) \ + ((amrr)->retrycnt > (amrr)->txcnt / 3) + #define is_enough(amrr) \ + ((amrr)->txcnt > 10) + #define is_min_rate(ni) \ + ((ni)->ni_txrate == 0) + #define is_max_rate(ni) \ + ((ni)->ni_txrate == (ni)->ni_rates.rs_nrates - 1) + #define increase_rate(ni) \ + ((ni)->ni_txrate++) + #define decrease_rate(ni) \ + ((ni)->ni_txrate--) + #define reset_cnt(amrr) \ + do { (amrr)->txcnt = (amrr)->retrycnt = 0; } while (0) + Static void + rum_ratectl(struct rum_amrr *amrr, struct ieee80211_node *ni) + { + int need_change = 0; + + if (is_success(amrr) && is_enough(amrr)) { + amrr->success++; + if (amrr->success >= amrr->success_threshold && + !is_max_rate(ni)) { + amrr->recovery = 1; + amrr->success = 0; + increase_rate(ni); + need_change = 1; + } else { + amrr->recovery = 0; + } + } else if (is_failure(amrr)) { + amrr->success = 0; + if (!is_min_rate(ni)) { + if (amrr->recovery) { + amrr->success_threshold *= 2; + if (amrr->success_threshold > + RUM_AMRR_MAX_SUCCESS_THRESHOLD) + amrr->success_threshold = + RUM_AMRR_MAX_SUCCESS_THRESHOLD; + } else { + amrr->success_threshold = + RUM_AMRR_MIN_SUCCESS_THRESHOLD; + } + decrease_rate(ni); + need_change = 1; + } + amrr->recovery = 0; /* original paper was incorrect */ + } + + if (is_enough(amrr) || need_change) + reset_cnt(amrr); + } + + + /* + int + rum_activate(device_ptr_t self, enum devact act) + { + switch (act) { + case DVACT_ACTIVATE: + return EOPNOTSUPP; + + case DVACT_DEACTIVATE: + //if_deactivate(&sc->sc_ic.ic_if); + break; + } + + return 0; + } + */ + + DRIVER_MODULE(rum, uhub, rum_driver, rum_devclass, usbd_driver_load, 0); --- /dev/null Sat Jan 6 22:22:01 2007 +++ sys/dev/usb/if_rumreg.h Sat Jan 6 14:57:53 2007 @@ -0,0 +1,390 @@ +/* $OpenBSD: if_rumreg.h,v 1.12 2006/08/09 08:21:08 damien Exp $ */ + +/*- + * Copyright (c) 2005, 2006 Damien Bergamini + * Copyright (c) 2006 Niall O'Higgins + * + * 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. + */ + +#define RT2573_TX_DESC_SIZE (sizeof (struct rum_tx_desc)) +#define RT2573_RX_DESC_SIZE (sizeof (struct rum_rx_desc)) + +#define RT2573_CONFIG_NO 1 +#define RT2573_IFACE_INDEX 0 + +#define RT2573_MCU_CNTL 0x01 +#define RT2573_WRITE_MAC 0x02 +#define RT2573_READ_MAC 0x03 +#define RT2573_WRITE_MULTI_MAC 0x06 +#define RT2573_READ_MULTI_MAC 0x07 +#define RT2573_READ_EEPROM 0x09 +#define RT2573_WRITE_LED 0x0a + +/* + * Control and status registers. + */ +#define RT2573_AIFSN_CSR 0x0400 +#define RT2573_CWMIN_CSR 0x0404 +#define RT2573_CWMAX_CSR 0x0408 +#define RT2573_MCU_CODE_BASE 0x0800 +#define RT2573_HW_BEACON_BASE0 0x2400 +#define RT2573_MAC_CSR0 0x3000 +#define RT2573_MAC_CSR1 0x3004 +#define RT2573_MAC_CSR2 0x3008 +#define RT2573_MAC_CSR3 0x300c +#define RT2573_MAC_CSR4 0x3010 +#define RT2573_MAC_CSR5 0x3014 +#define RT2573_MAC_CSR6 0x3018 +#define RT2573_MAC_CSR7 0x301c +#define RT2573_MAC_CSR8 0x3020 +#define RT2573_MAC_CSR9 0x3024 +#define RT2573_MAC_CSR10 0x3028 +#define RT2573_MAC_CSR11 0x302c +#define RT2573_MAC_CSR12 0x3030 +#define RT2573_MAC_CSR13 0x3034 +#define RT2573_MAC_CSR14 0x3038 +#define RT2573_MAC_CSR15 0x303c +#define RT2573_TXRX_CSR0 0x3040 +#define RT2573_TXRX_CSR1 0x3044 +#define RT2573_TXRX_CSR2 0x3048 +#define RT2573_TXRX_CSR3 0x304c +#define RT2573_TXRX_CSR4 0x3050 +#define RT2573_TXRX_CSR5 0x3054 +#define RT2573_TXRX_CSR6 0x3058 +#define RT2573_TXRX_CSR7 0x305c +#define RT2573_TXRX_CSR8 0x3060 +#define RT2573_TXRX_CSR9 0x3064 +#define RT2573_TXRX_CSR10 0x3068 +#define RT2573_TXRX_CSR11 0x306c +#define RT2573_TXRX_CSR12 0x3070 +#define RT2573_TXRX_CSR13 0x3074 +#define RT2573_TXRX_CSR14 0x3078 +#define RT2573_TXRX_CSR15 0x307c +#define RT2573_PHY_CSR0 0x3080 +#define RT2573_PHY_CSR1 0x3084 +#define RT2573_PHY_CSR2 0x3088 +#define RT2573_PHY_CSR3 0x308c +#define RT2573_PHY_CSR4 0x3090 +#define RT2573_PHY_CSR5 0x3094 +#define RT2573_PHY_CSR6 0x3098 +#define RT2573_PHY_CSR7 0x309c +#define RT2573_SEC_CSR0 0x30a0 +#define RT2573_SEC_CSR1 0x30a4 +#define RT2573_SEC_CSR2 0x30a8 +#define RT2573_SEC_CSR3 0x30ac +#define RT2573_SEC_CSR4 0x30b0 +#define RT2573_SEC_CSR5 0x30b4 +#define RT2573_STA_CSR0 0x30c0 +#define RT2573_STA_CSR1 0x30c4 +#define RT2573_STA_CSR2 0x30c8 +#define RT2573_STA_CSR3 0x30cc +#define RT2573_STA_CSR4 0x30d0 +#define RT2573_STA_CSR5 0x30d4 + + +/* possible flags for register RT2573_MAC_CSR1 */ +#define RT2573_RESET_ASIC (1 << 0) +#define RT2573_RESET_BBP (1 << 1) +#define RT2573_HOST_READY (1 << 2) + +/* possible flags for register MAC_CSR5 */ +#define RT2573_ONE_BSSID 3 + +/* possible flags for register TXRX_CSR0 */ +/* Tx filter flags are in the low 16 bits */ +#define RT2573_AUTO_TX_SEQ (1 << 15) +/* Rx filter flags are in the high 16 bits */ +#define RT2573_DISABLE_RX (1 << 16) +#define RT2573_DROP_CRC_ERROR (1 << 17) +#define RT2573_DROP_PHY_ERROR (1 << 18) +#define RT2573_DROP_CTL (1 << 19) +#define RT2573_DROP_NOT_TO_ME (1 << 20) +#define RT2573_DROP_TODS (1 << 21) +#define RT2573_DROP_VER_ERROR (1 << 22) +#define RT2573_DROP_MULTICAST (1 << 23) +#define RT2573_DROP_BROADCAST (1 << 24) +#define RT2573_DROP_ACKCTS (1 << 25) + +/* possible flags for register TXRX_CSR4 */ +#define RT2573_SHORT_PREAMBLE (1 << 18) +#define RT2573_MRR_ENABLED (1 << 19) +#define RT2573_MRR_CCK_FALLBACK (1 << 22) + +/* possible flags for register TXRX_CSR9 */ +#define RT2573_TSF_TICKING (1 << 16) +#define RT2573_TSF_MODE(x) (((x) & 0x3) << 17) +/* TBTT stands for Target Beacon Transmission Time */ +#define RT2573_ENABLE_TBTT (1 << 19) +#define RT2573_GENERATE_BEACON (1 << 20) + +/* possible flags for register PHY_CSR0 */ +#define RT2573_PA_PE_2GHZ (1 << 16) +#define RT2573_PA_PE_5GHZ (1 << 17) + +/* possible flags for register PHY_CSR3 */ +#define RT2573_BBP_READ (1 << 15) +#define RT2573_BBP_BUSY (1 << 16) +/* possible flags for register PHY_CSR4 */ +#define RT2573_RF_20BIT (20 << 24) +#define RT2573_RF_BUSY (1 << 31) + +/* LED values */ +#define RT2573_LED_RADIO (1 << 8) +#define RT2573_LED_G (1 << 9) +#define RT2573_LED_A (1 << 10) +#define RT2573_LED_ON 0x1e1e +#define RT2573_LED_OFF 0x0 + +#define RT2573_MCU_RUN (1 << 3) + +#define RT2573_SMART_MODE (1 << 0) + +#define RT2573_BBPR94_DEFAULT 6 + +#define RT2573_BBP_WRITE (1 << 15) + +/* dual-band RF */ +#define RT2573_RF_5226 1 +#define RT2573_RF_5225 3 +/* single-band RF */ +#define RT2573_RF_2528 2 +#define RT2573_RF_2527 4 + +#define RT2573_BBP_VERSION 0 + +struct rum_tx_desc { + uint32_t flags; +#define RT2573_TX_BURST (1 << 0) +#define RT2573_TX_VALID (1 << 1) +#define RT2573_TX_MORE_FRAG (1 << 2) +#define RT2573_TX_ACK (1 << 3) +#define RT2573_TX_TIMESTAMP (1 << 4) +#define RT2573_TX_OFDM (1 << 5) +#define RT2573_TX_IFS_SIFS (1 << 6) +#define RT2573_TX_LONG_RETRY (1 << 7) + + uint16_t wme; +#define RT2573_QID(v) (v) +#define RT2573_AIFSN(v) ((v) << 4) +#define RT2573_LOGCWMIN(v) ((v) << 8) +#define RT2573_LOGCWMAX(v) ((v) << 12) + + uint16_t xflags; +#define RT2573_TX_HWSEQ (1 << 12) + + uint8_t plcp_signal; + uint8_t plcp_service; +#define RT2573_PLCP_LENGEXT 0x80 + + uint8_t plcp_length_lo; + uint8_t plcp_length_hi; + + uint32_t iv; + uint32_t eiv; + + uint8_t offset; + uint8_t qid; + uint8_t txpower; +#define RT2573_DEFAULT_TXPOWER 0 + + uint8_t reserved; +} __packed; + +struct rum_rx_desc { + uint32_t flags; +#define RT2573_RX_BUSY (1 << 0) +#define RT2573_RX_DROP (1 << 1) +#define RT2573_RX_CRC_ERROR (1 << 6) +#define RT2573_RX_OFDM (1 << 7) + + uint8_t rate; + uint8_t rssi; + uint8_t reserved1; + uint8_t offset; + uint32_t iv; + uint32_t eiv; + uint32_t reserved2[2]; +} __packed; + +#define RT2573_RF1 0 +#define RT2573_RF2 2 +#define RT2573_RF3 1 +#define RT2573_RF4 3 + +#define RT2573_EEPROM_MACBBP 0x0000 +#define RT2573_EEPROM_ADDRESS 0x0004 +#define RT2573_EEPROM_ANTENNA 0x0020 +#define RT2573_EEPROM_CONFIG2 0x0022 +#define RT2573_EEPROM_BBP_BASE 0x0026 +#define RT2573_EEPROM_TXPOWER 0x0046 +#define RT2573_EEPROM_FREQ_OFFSET 0x005e +#define RT2573_EEPROM_RSSI_2GHZ_OFFSET 0x009a +#define RT2573_EEPROM_RSSI_5GHZ_OFFSET 0x009c + +/* + * Default values for MAC registers; values taken from the reference driver. + */ +#define RT2573_DEF_MAC \ + { RT2573_TXRX_CSR0, 0x025fb032 }, \ + { RT2573_TXRX_CSR1, 0x9eaa9eaf }, \ + { RT2573_TXRX_CSR2, 0x8a8b8c8d }, \ + { RT2573_TXRX_CSR3, 0x00858687 }, \ + { RT2573_TXRX_CSR7, 0x2e31353b }, \ + { RT2573_TXRX_CSR8, 0x2a2a2a2c }, \ + { RT2573_TXRX_CSR15, 0x0000000f }, \ + { RT2573_MAC_CSR6, 0x00000fff }, \ + { RT2573_MAC_CSR8, 0x016c030a }, \ + { RT2573_MAC_CSR10, 0x00000718 }, \ + { RT2573_MAC_CSR12, 0x00000004 }, \ + { RT2573_MAC_CSR13, 0x00007f00 }, \ + { RT2573_SEC_CSR0, 0x00000000 }, \ + { RT2573_SEC_CSR1, 0x00000000 }, \ + { RT2573_SEC_CSR5, 0x00000000 }, \ + { RT2573_PHY_CSR1, 0x000023b0 }, \ + { RT2573_PHY_CSR5, 0x00040a06 }, \ + { RT2573_PHY_CSR6, 0x00080606 }, \ + { RT2573_PHY_CSR7, 0x00000408 }, \ + { RT2573_AIFSN_CSR, 0x00002273 }, \ + { RT2573_CWMIN_CSR, 0x00002344 }, \ + { RT2573_CWMAX_CSR, 0x000034aa } + +/* + * Default values for BBP registers; values taken from the reference driver. + */ +#define RT2573_DEF_BBP \ + { 3, 0x80 }, \ + { 15, 0x30 }, \ + { 17, 0x20 }, \ + { 21, 0xc8 }, \ + { 22, 0x38 }, \ + { 23, 0x06 }, \ + { 24, 0xfe }, \ + { 25, 0x0a }, \ + { 26, 0x0d }, \ + { 32, 0x0b }, \ + { 34, 0x12 }, \ + { 37, 0x07 }, \ + { 39, 0xf8 }, \ + { 41, 0x60 }, \ + { 53, 0x10 }, \ + { 54, 0x18 }, \ + { 60, 0x10 }, \ + { 61, 0x04 }, \ + { 62, 0x04 }, \ + { 75, 0xfe }, \ + { 86, 0xfe }, \ + { 88, 0xfe }, \ + { 90, 0x0f }, \ + { 99, 0x00 }, \ + { 102, 0x16 }, \ + { 107, 0x04 } + +/* + * Default settings for RF registers; values taken from the reference driver. + */ +#define RT2573_RF5226 \ + { 1, 0x00b03, 0x001e1, 0x1a014, 0x30282 }, \ + { 2, 0x00b03, 0x001e1, 0x1a014, 0x30287 }, \ + { 3, 0x00b03, 0x001e2, 0x1a014, 0x30282 }, \ + { 4, 0x00b03, 0x001e2, 0x1a014, 0x30287 }, \ + { 5, 0x00b03, 0x001e3, 0x1a014, 0x30282 }, \ + { 6, 0x00b03, 0x001e3, 0x1a014, 0x30287 }, \ + { 7, 0x00b03, 0x001e4, 0x1a014, 0x30282 }, \ + { 8, 0x00b03, 0x001e4, 0x1a014, 0x30287 }, \ + { 9, 0x00b03, 0x001e5, 0x1a014, 0x30282 }, \ + { 10, 0x00b03, 0x001e5, 0x1a014, 0x30287 }, \ + { 11, 0x00b03, 0x001e6, 0x1a014, 0x30282 }, \ + { 12, 0x00b03, 0x001e6, 0x1a014, 0x30287 }, \ + { 13, 0x00b03, 0x001e7, 0x1a014, 0x30282 }, \ + { 14, 0x00b03, 0x001e8, 0x1a014, 0x30284 }, \ + \ + { 34, 0x00b03, 0x20266, 0x36014, 0x30282 }, \ + { 38, 0x00b03, 0x20267, 0x36014, 0x30284 }, \ + { 42, 0x00b03, 0x20268, 0x36014, 0x30286 }, \ + { 46, 0x00b03, 0x20269, 0x36014, 0x30288 }, \ + \ + { 36, 0x00b03, 0x00266, 0x26014, 0x30288 }, \ + { 40, 0x00b03, 0x00268, 0x26014, 0x30280 }, \ + { 44, 0x00b03, 0x00269, 0x26014, 0x30282 }, \ + { 48, 0x00b03, 0x0026a, 0x26014, 0x30284 }, \ + { 52, 0x00b03, 0x0026b, 0x26014, 0x30286 }, \ + { 56, 0x00b03, 0x0026c, 0x26014, 0x30288 }, \ + { 60, 0x00b03, 0x0026e, 0x26014, 0x30280 }, \ + { 64, 0x00b03, 0x0026f, 0x26014, 0x30282 }, \ + \ + { 100, 0x00b03, 0x0028a, 0x2e014, 0x30280 }, \ + { 104, 0x00b03, 0x0028b, 0x2e014, 0x30282 }, \ + { 108, 0x00b03, 0x0028c, 0x2e014, 0x30284 }, \ + { 112, 0x00b03, 0x0028d, 0x2e014, 0x30286 }, \ + { 116, 0x00b03, 0x0028e, 0x2e014, 0x30288 }, \ + { 120, 0x00b03, 0x002a0, 0x2e014, 0x30280 }, \ + { 124, 0x00b03, 0x002a1, 0x2e014, 0x30282 }, \ + { 128, 0x00b03, 0x002a2, 0x2e014, 0x30284 }, \ + { 132, 0x00b03, 0x002a3, 0x2e014, 0x30286 }, \ + { 136, 0x00b03, 0x002a4, 0x2e014, 0x30288 }, \ + { 140, 0x00b03, 0x002a6, 0x2e014, 0x30280 }, \ + \ + { 149, 0x00b03, 0x002a8, 0x2e014, 0x30287 }, \ + { 153, 0x00b03, 0x002a9, 0x2e014, 0x30289 }, \ + { 157, 0x00b03, 0x002ab, 0x2e014, 0x30281 }, \ + { 161, 0x00b03, 0x002ac, 0x2e014, 0x30283 }, \ + { 165, 0x00b03, 0x002ad, 0x2e014, 0x30285 } + +#define RT2573_RF5225 \ + { 1, 0x00b33, 0x011e1, 0x1a014, 0x30282 }, \ + { 2, 0x00b33, 0x011e1, 0x1a014, 0x30287 }, \ + { 3, 0x00b33, 0x011e2, 0x1a014, 0x30282 }, \ + { 4, 0x00b33, 0x011e2, 0x1a014, 0x30287 }, \ + { 5, 0x00b33, 0x011e3, 0x1a014, 0x30282 }, \ + { 6, 0x00b33, 0x011e3, 0x1a014, 0x30287 }, \ + { 7, 0x00b33, 0x011e4, 0x1a014, 0x30282 }, \ + { 8, 0x00b33, 0x011e4, 0x1a014, 0x30287 }, \ + { 9, 0x00b33, 0x011e5, 0x1a014, 0x30282 }, \ + { 10, 0x00b33, 0x011e5, 0x1a014, 0x30287 }, \ + { 11, 0x00b33, 0x011e6, 0x1a014, 0x30282 }, \ + { 12, 0x00b33, 0x011e6, 0x1a014, 0x30287 }, \ + { 13, 0x00b33, 0x011e7, 0x1a014, 0x30282 }, \ + { 14, 0x00b33, 0x011e8, 0x1a014, 0x30284 }, \ + \ + { 34, 0x00b33, 0x01266, 0x26014, 0x30282 }, \ + { 38, 0x00b33, 0x01267, 0x26014, 0x30284 }, \ + { 42, 0x00b33, 0x01268, 0x26014, 0x30286 }, \ + { 46, 0x00b33, 0x01269, 0x26014, 0x30288 }, \ + \ + { 36, 0x00b33, 0x01266, 0x26014, 0x30288 }, \ + { 40, 0x00b33, 0x01268, 0x26014, 0x30280 }, \ + { 44, 0x00b33, 0x01269, 0x26014, 0x30282 }, \ + { 48, 0x00b33, 0x0126a, 0x26014, 0x30284 }, \ + { 52, 0x00b33, 0x0126b, 0x26014, 0x30286 }, \ + { 56, 0x00b33, 0x0126c, 0x26014, 0x30288 }, \ + { 60, 0x00b33, 0x0126e, 0x26014, 0x30280 }, \ + { 64, 0x00b33, 0x0126f, 0x26014, 0x30282 }, \ + \ + { 100, 0x00b33, 0x0128a, 0x2e014, 0x30280 }, \ + { 104, 0x00b33, 0x0128b, 0x2e014, 0x30282 }, \ + { 108, 0x00b33, 0x0128c, 0x2e014, 0x30284 }, \ + { 112, 0x00b33, 0x0128d, 0x2e014, 0x30286 }, \ + { 116, 0x00b33, 0x0128e, 0x2e014, 0x30288 }, \ + { 120, 0x00b33, 0x012a0, 0x2e014, 0x30280 }, \ + { 124, 0x00b33, 0x012a1, 0x2e014, 0x30282 }, \ + { 128, 0x00b33, 0x012a2, 0x2e014, 0x30284 }, \ + { 132, 0x00b33, 0x012a3, 0x2e014, 0x30286 }, \ + { 136, 0x00b33, 0x012a4, 0x2e014, 0x30288 }, \ + { 140, 0x00b33, 0x012a6, 0x2e014, 0x30280 }, \ + \ + { 149, 0x00b33, 0x012a8, 0x2e014, 0x30287 }, \ + { 153, 0x00b33, 0x012a9, 0x2e014, 0x30289 }, \ + { 157, 0x00b33, 0x012ab, 0x2e014, 0x30281 }, \ + { 161, 0x00b33, 0x012ac, 0x2e014, 0x30283 }, \ + { 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 } --- /dev/null Sat Jan 6 22:33:00 2007 +++ sys/dev/usb/if_rumvar.h Sat Jan 6 14:58:07 2007 @@ -0,0 +1,157 @@ +/* $OpenBSD: if_rumvar.h,v 1.6 2006/08/18 15:11:12 damien Exp $ */ + +/*- + * Copyright (c) 2005, 2006 Damien Bergamini + * Copyright (c) 2006 Niall O'Higgins + * Copyright (c) 2006, 2007 Valery V.Chikalov + * + * 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. + */ + +#define RT2573_RX_LIST_COUNT 1 +#define RT2573_TX_LIST_COUNT 1 + +struct rum_rx_radiotap_header { + struct ieee80211_radiotap_header wr_ihdr; + uint8_t wr_flags; + uint8_t wr_rate; + uint16_t wr_chan_freq; + uint16_t wr_chan_flags; + uint8_t wr_antenna; + uint8_t wr_antsignal; +} __packed; + +#define RT2573_RX_RADIOTAP_PRESENT \ + ((1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + (1 << IEEE80211_RADIOTAP_CHANNEL) | \ + (1 << IEEE80211_RADIOTAP_ANTENNA) | \ + (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)) + +struct rum_tx_radiotap_header { + struct ieee80211_radiotap_header wt_ihdr; + uint8_t wt_flags; + uint8_t wt_rate; + uint16_t wt_chan_freq; + uint16_t wt_chan_flags; + uint8_t wt_antenna; +} __packed; + +#define RT2573_TX_RADIOTAP_PRESENT \ + ((1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + (1 << IEEE80211_RADIOTAP_CHANNEL) | \ + (1 << IEEE80211_RADIOTAP_ANTENNA)) + +struct rum_softc; + +struct rum_tx_data { + struct rum_softc *sc; + usbd_xfer_handle xfer; + uint8_t *buf; + struct mbuf *m; + struct ieee80211_node *ni; +}; + +struct rum_rx_data { + struct rum_softc *sc; + usbd_xfer_handle xfer; + uint8_t *buf; + struct mbuf *m; +}; + +struct rum_amrr { + int txcnt; + int retrycnt; + int success; + int success_threshold; + int recovery; +}; + +struct rum_softc { + USBBASEDEVICE sc_dev; + struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + int (*sc_newstate)(struct ieee80211com *, + enum ieee80211_state, int); + + usbd_device_handle sc_udev; + usbd_interface_handle sc_iface; + int sc_flags; +#define RT2573_FWLOADED (1 << 0) + + struct ieee80211_channel *sc_curchan; + + int sc_rx_no; + int sc_tx_no; + + uint16_t macbbp_rev; + uint8_t rf_rev; + uint8_t rffreq; + + usbd_xfer_handle amrr_xfer; + + usbd_pipe_handle sc_rx_pipeh; + usbd_pipe_handle sc_tx_pipeh; + + enum ieee80211_state sc_state; + struct usb_task sc_task; + + struct rum_amrr amrr; + + struct rum_rx_data rx_data[RT2573_RX_LIST_COUNT]; + struct rum_tx_data tx_data[RT2573_TX_LIST_COUNT]; + int tx_queued; + + struct ieee80211_beacon_offsets sc_bo; + + struct callout scan_ch; + struct callout amrr_ch; + + int sc_tx_timer; + + uint32_t sta[6]; + uint32_t rf_regs[4]; + uint8_t txpow[44]; + + struct { + uint8_t val; + uint8_t reg; + } __packed bbp_prom[16]; + + int hw_radio; + int rx_ant; + int tx_ant; + int nb_ant; + int ext_2ghz_lna; + int ext_5ghz_lna; + int rssi_2ghz_corr; + int rssi_5ghz_corr; + int sifs; + uint8_t bbp17; + + struct bpf_if *sc_drvbpf; + + union { + struct rum_rx_radiotap_header th; + uint8_t pad[64]; + } sc_rxtapu; +#define sc_rxtap sc_rxtapu.th + int sc_rxtap_len; + + union { + struct rum_tx_radiotap_header th; + uint8_t pad[64]; + } sc_txtapu; +#define sc_txtap sc_txtapu.th + int sc_txtap_len; +}; --- /dev/null Sat Jan 6 23:00:00 2007 +++ sys/modules/rt2573/Makefile Sat Jan 6 16:34:48 2007 @@ -0,0 +1,3 @@ +KMOD= rt2573 +FIRMWS= rum-rt2573:rt2573:100 +.include --- /dev/null Sat Jan 6 22:55:00 2007 +++ sys/modules/rum/Makefile Sat Jan 6 14:41:03 2007 @@ -0,0 +1,8 @@ +# $FreeBSD: src/sys/modules/ural/Makefile,v 1.1 2005/04/18 18:47:38 damien Exp $ + +.PATH: ${.CURDIR}/../../dev/usb + +KMOD = if_rum +SRCS = if_rum.c opt_bdg.h opt_usb.h device_if.h bus_if.h usbdevs.h + +.include --- sys/dev/usb/usbdevs Sat Jan 6 21:18:43 2007 +++ sys/dev/usb/usbdevs Sat Jan 6 22:54:35 2007 @@ -1,4 +1,4 @@ -$FreeBSD: src/sys/dev/usb/usbdevs,v 1.232.2.19 2006/12/30 17:55:15 maxim Exp $ +$FreeBSD: src/sys/dev/usb/usbdevs,v 1.232.2.16 2006/08/20 05:20:07 imp Exp $ /* $NetBSD: usbdevs,v 1.392 2004/12/29 08:38:44 imp Exp $ */ /*- @@ -351,6 +351,7 @@ vendor DIGITALSTREAM 0x074e Digital Stream vendor AUREAL 0x0755 Aureal vendor MIDIMAN 0x0763 Midiman +vendor SURECOM 0x0769 Surecom Technology vendor LINKSYS2 0x077b Linksys vendor GRIFFIN 0x077d Griffin vendor SANDISK 0x0781 SanDisk @@ -379,6 +380,7 @@ vendor AVERMEDIA 0x07ca AVerMedia vendor SIIG 0x07cc SIIG vendor CASIO 0x07cf CASIO +vendor DLINK2 0x07d1 D-Link vendor APTIO 0x07d2 Aptio vendor ARASAN 0x07da Arasan vendor ALLIEDCABLE 0x07e6 Allied Cable @@ -472,18 +474,19 @@ vendor CHICONY2 0x0c45 Chicony vendor SEALEVEL 0x0c52 Sealevel vendor LUWEN 0x0c76 Luwen -vendor ZCOM 0x0cde Z-Com +vendor ZCOM 0x0cde Z-Com vendor TANGTOP 0x0d3d Tangtop -vendor SMC3 0x0d5c SMC +vendor SMC3 0x0d5c SMC vendor ADDON 0x0d7d Add-on Technology -vendor ACDC 0x0d7e ACDC -vendor ABC 0x0d8c ABC -vendor MSI 0x0db0 Micro Star International +vendor ACDC 0x0d7e ACDC +vendor ABC 0x0d8c ABC +vendor MSI 0x0db0 Micro Star International +vendor SITECOMEU 0x0df6 Sitecom Europe vendor HAWKING 0x0e66 Hawking vendor GMATE 0x0e7e G.Mate, Inc -vendor OTI 0x0ea0 Ours +vendor OTI 0x0ea0 Ours vendor PILOTECH 0x0eaf Pilotech -vendor NOVATECH 0x0eb0 NovaTech +vendor NOVATECH 0x0eb0 NovaTech vendor EGALAX 0x0eef eGalax vendor MICROTUNE 0x0f4d Microtune vendor VTECH 0x0f88 VTech @@ -507,9 +510,11 @@ vendor BELKIN2 0x1293 Belkin vendor AINCOMM 0x12fd Aincomm vendor MOBILITY 0x1342 Mobility +vendor DICKSMITH 0x1371 Dick Smith Electronics vendor LINKSYS4 0x13b1 Linksys vendor SHARK 0x13d2 Shark vendor RADIOSHACK 0x1453 Radio Shack +vendor HUAWEI3COM 0x1472 Huawei 3Com vendor SILICOM 0x1485 Silicom vendor RALINK 0x148f Ralink Technology vendor IMAGINATION 0x149a Imagination Technologies @@ -519,11 +524,15 @@ vendor SOHOWARE 0x15e8 SOHOware vendor UMAX 0x1606 UMAX vendor INSIDEOUT 0x1608 Inside Out Networks +vendor GOODWAY 0x1631 Good Way Technology vendor ENTREGA 0x1645 Entrega vendor ACTIONTEC 0x1668 Actiontec -vendor CMOTECH 0x16d8 CMOTECH CO., LTD. +vendor GIGASET 0x1690 Gigaset +vendor CMOTECH 0x16d8 CMOTECH CO., LTD. +vendor QCOM 0x18e8 Qcom vendor LINKSYS3 0x1915 Linksys vendor DLINK 0x2001 D-Link +vendor PLANEX2 0x2019 Planex Communications vendor ERICSSON 0x2282 Ericsson vendor MOTOROLA2 0x22b8 Motorola vendor TRIPPLITE 0x2478 Tripp-Lite @@ -544,7 +553,7 @@ vendor ONSPEC2 0x55aa OnSpec vendor ZINWELL 0x5a57 Zinwell vendor SITECOM 0x6189 Sitecom -vendor ARKMICRO 0x6547 Arkmicro Technologies +vendor ARKMICRO 0x6547 Arkmicro Technologies vendor INTEL 0x8086 Intel vendor HP2 0xf003 Hewlett Packard @@ -579,6 +588,7 @@ product ABOCOM XX8 0x4102 XX8 product ABOCOM XX9 0x4104 XX9 product ABOCOM XX10 0xabc1 XX10 +product ABOCOM RT2573 0xb21d RT2573 /* Accton products */ product ACCTON USB320_EC 0x1046 USB320-EC Ethernet @@ -677,7 +687,7 @@ product APPLE IPODNANO 0x120a iPod Nano /* Arkmicro Technologies */ -product ARKMICRO ARK3116 0x0232 ARK3116 Serial +product ARKMICRO ARK3116 0x0232 ARK3116 Serial /* Asahi Optical products */ product ASAHIOPTICAL OPTIO230 0x0004 Digital camera @@ -688,6 +698,7 @@ /* ASUS products */ product ASUS WL167G 0x1707 WL-167g wireless adapter +product ASUS RT2573 0x1723 RT2573 /* ATen products */ product ATEN UC1284 0x2001 Parallel printer @@ -715,9 +726,12 @@ product BELKIN F5U109 0x0109 F5U109 Serial product BELKIN F5U208 0x0208 F5U208 VideoBus II product BELKIN F5U409 0x0409 F5U409 Serial -product BELKIN F6C550AVR 0x0551 F6C550-AVR UPS +product BELKIN F6C550AVR 0x0551 F6C550-AVR UPS product BELKIN F5U120 0x1203 F5U120-PC Hub product BELKIN F5D7050 0x7050 F5D7050 wireless adapter +product BELKIN F5D7050A 0x705a F5D705A 54g USB Network Adapter +product BELKIN F5D9050V3 0x905b F5D9050 ver 3 + /* Billionton products */ product BILLIONTON USB100 0x0986 USB100N 10/100 FastEthernet @@ -767,11 +781,11 @@ product CHICONY KB8933 0x0001 KB-8933 keyboard /* CMOTECH products */ -product CMOTECH CDMAMODEM 0x5141 CMOTECH CDMA Technologies USB modem +product CMOTECH CDMAMODEM 0x5141 CMOTECH CDMA Technologies USB modem /* Compaq products */ product COMPAQ PJB100 0x504a Personal Jukebox PJB100 -product COMPAQ IPAQLINUX 0x505a iPAQ Linux +product COMPAQ IPAQLINUX 0x505a iPAQ Linux /* Connectix products */ product CONNECTIX QUICKCAM 0x0001 QuickCam @@ -798,6 +812,7 @@ /* Conceptronic products */ product CONCEPTRONIC C54U 0x3c02 C54U wireless adapter +product CONCEPTRONIC C54RU2 0x3c22 C54RU /* CTX products */ product CTX EX1300 0x9999 Ex1300 hub @@ -808,7 +823,7 @@ /* Cypress Semiconductor products */ product CYPRESS MOUSE 0x0001 mouse product CYPRESS THERMO 0x0002 thermometer -product CYPRESS WISPY 0x0bad MetaGeek Wi-Spy +product CYPRESS WISPY 0x0bad MetaGeek Wi-Spy product CYPRESS FMRADIO 0x1002 FM Radio product CYPRESS SLIM_HUB 0x6560 Slim Hub @@ -828,6 +843,10 @@ /* Diamond products */ product DIAMOND RIO500USB 0x0001 Rio 500 USB +/* Dick Smith Electronics (really C-Net) products */ +product DICKSMITH RT2573 0x9022 RT2573 +product DICKSMITH CWD854F 0x9032 C-Net CWD-854 rev F + /* Digi International products */ product DIGI ACCELEPORT2 0x0002 AccelePort USB 2 product DIGI ACCELEPORT4 0x0004 AccelePort USB 4 @@ -845,6 +864,8 @@ product DLINK DSB650TX3 0x400b 10/100 ethernet product DLINK DSB650TX2 0x4102 10/100 ethernet product DLINK DSB650 0xabc1 10/100 ethernet +product DLINK2 DWLG122C1 0x3c03 DWL-G122 rev C1 +product DLINK2 WUA1340 0x3c04 WUA-1340 /* EIZO products */ product EIZO HUB 0x0000 hub @@ -902,11 +923,11 @@ product EPSON 1670 0x011f Perfection 1670 scanner product EPSON 1270 0x0120 Perfection 1270 scanner product EPSON 2480 0x0121 Perfection 2480 scanner -product EPSON 3590 0x0122 Perfection 3590 scanner -product EPSON 4990 0x012a Perfection 4990 Photo scanner +product EPSON 3590 0x0122 Perfection 3590 scanner +product EPSON 4990 0x012a Perfection 4990 Photo scanner product EPSON 3500 0x080e CX-3500/3600/3650 MFP product EPSON RX425 0x080f Stylus Photo RX425 scanner -product EPSON 4200 0x0820 CX4200 MP scanner +product EPSON 4200 0x0820 CX4200 MP scanner /* e-TEK Labs products */ product ETEK 1COM 0x8007 Serial @@ -954,10 +975,17 @@ product GIGABYTE GNBR402W 0x8002 GN-BR402W product GIGABYTE GNWLBM101 0x8003 GN-WLBM101 product GIGABYTE GNWBKG 0x8007 GN-WBKG +product GIGABYTE GNWB01GS 0x8008 GN-WB01GS + +/* Gigaset products */ +product GIGASET RT2573 0x0722 RT2573 /* G.Mate, Inc products */ product GMATE YP3X00 0x1001 YP3X00 PDA +/* Good Way Technology products */ +product GOODWAY RT2573 0xc019 RT2573 + /* Guillemot Corporation */ product GUILLEMOT DALEADER 0xa300 DA Leader product GUILLEMOT HWGUSB254 0xe000 HWGUSB2-54 WLAN @@ -1028,6 +1056,9 @@ /* HP products */ product HP2 C500 0x6002 PhotoSmart C500 +/* HUAWEI products */ +product HUAWEI3COM RT2573 0x0009 RT2573 + /* IBM Corporation */ product IBM USBCDROMDRIVE 0x4427 USB CD-ROM Drive @@ -1168,6 +1199,7 @@ product LINKSYS4 WUSB54G 0x000d WUSB54G wireless adapter product LINKSYS4 WUSB54GP 0x0011 WUSB54GP wireless adapter product LINKSYS4 HU200TS 0x001a HU200TS wireless adapter +product LINKSYS4 WUSB54GC 0x0020 WUSB54GC /* Logitech products */ product LOGITECH M2452 0x0203 M2452 keyboard @@ -1183,11 +1215,11 @@ product LOGITECH WMMOUSE 0xc004 WingMan Gaming Mouse product LOGITECH BD58 0xc00c BD58 mouse product LOGITECH UN58A 0xc030 iFeel Mouse -product LOGITECH UN53B 0xc032 iFeel MouseMan +product LOGITECH UN53B 0xc032 iFeel MouseMan product LOGITECH WMPAD 0xc208 WingMan GamePad Extreme product LOGITECH WMRPAD 0xc20a WingMan RumblePad product LOGITECH WMJOY 0xc281 WingMan Force joystick -product LOGITECH BB13 0xc401 USB-PS/2 Trackball +product LOGITECH BB13 0xc401 USB-PS/2 Trackball product LOGITECH RK53 0xc501 Cordless mouse product LOGITECH RB6 0xc503 Cordless keyboard product LOGITECH MX700 0xc506 Cordless optical mouse @@ -1243,6 +1275,9 @@ product MSI RT2570 0x6861 RT2570 product MSI RT2570_2 0x6865 RT2570 product MSI RT2570_3 0x6869 RT2570 +product MSI RT2573 0x6877 RT2573 +product MSI RT2573_2 0xa861 RT2573 +product MSI RT2573_3 0xa874 RT2573 /* Microsoft products */ product MICROSOFT SIDEPREC 0x0008 SideWinder Precision Pro @@ -1329,7 +1364,7 @@ /* Netgear products */ product NETGEAR EA101 0x1001 Ethernet -product NETGEAR FA101 0x1020 Ethernet 10/100, USB1.1 +product NETGEAR FA101 0x1020 Ethernet 10/100, USB1.1 product NETGEAR FA120 0x1040 USB 2.0 Ethernet /* Nikon products */ @@ -1337,7 +1372,7 @@ product NIKON LS40 0x4000 CoolScan LS40 ED /* NovaTech Products */ -product NOVATECH NV902 0x9020 NovaTech NV-902W +product NOVATECH NV902 0x9020 NovaTech NV-902W /* Olympus products */ product OLYMPUS C1 0x0102 C-1 Digital Camera @@ -1364,7 +1399,7 @@ product PALM ZIRE 0x0070 Palm Zire /* Panasonic products */ -product PANASONIC KXL840AN 0x0d01 CD-R Drive KXL-840AN +product PANASONIC KXL840AN 0x0d01 CD-R Drive KXL-840AN product PANASONIC KXLRW32AN 0x0d09 CD-R Drive KXL-RW32AN product PANASONIC KXLCB20AN 0x0d0a CD-R Drive KXL-CB20AN product PANASONIC KXLCB35AN 0x0d0e DVD-ROM & CD-R/RW @@ -1392,6 +1427,10 @@ /* P.I. Engineering products */ product PIENGINEERING PS2USB 0x020b PS2 to Mac USB Adapter +/* Planex Communications products */ +product PLANEX2 GWUSMM 0xed02 GW-USMM + + /* Plextor Corp. */ product PLEXTOR 40_12_40U 0x0011 PlexWriter 40/12/40U @@ -1434,6 +1473,10 @@ /* Putercom products */ product PUTERCOM UPA100 0x047e USB-1284 BRIDGE +/* Qcom products */ +product QCOM RT2573 0x6196 RT2573 +product QCOM RT2573_2 0x6229 RT2573 + /* Qualcomm products */ product QUALCOMM CDMA_MSM 0x3196 CDMA Technologies MSM modem product QUALCOMM2 CDMA_MSM 0x6000 CDMA Technologies MSM phone @@ -1453,6 +1496,8 @@ /* Ralink Technology products */ product RALINK RT2570 0x1706 RT2500USB wireless adapter product RALINK RT2570_2 0x2570 RT2500USB wireless adapter +product RALINK RT2573 0x2573 RT2573 +product RALINK RT2671 0x2671 RT2671 /* ReakTek products */ product REALTEK USBKR100 0x8150 USBKR100 USB Ethernet (GREEN HOUSE) @@ -1524,7 +1569,7 @@ product SIIG2 US2308 0x0421 Serial /* Silicom products */ -product SILICOM GPE 0x0002 Psion Gold Port Ethernet +product SILICOM GPE 0x0002 Psion Gold Port Ethernet /* Silicon Portals Inc. */ product SILICONPORTALS YAPPH_NF 0x0200 YAP Phone (no firmware) @@ -1537,6 +1582,11 @@ product SITECOM LN029 0x182d USB 2.0 Ethernet product SITECOM SERIAL 0x2068 USB to serial cable (v2) +/* Sitecom Europe products */ +product SITECOMEU WL172 0x90ac WL-172 +product SITECOMEU WL113R2 0x9712 WL-113 rev 2 + + /* SmartBridges products */ product SMARTBRIDGES SMARTLINK 0x0001 SmartLink USB ethernet product SMARTBRIDGES SMARTNIC 0x0003 smartNIC 2 PnP ethernet @@ -1601,6 +1651,9 @@ product DIAMOND2 SUPRA2890 0x0b4a SupraMax 2890 56K Modem product DIAMOND2 RIO600USB 0x5001 Rio 600 USB product DIAMOND2 RIO800USB 0x5002 Rio 800 USB + +/* Surecom Technology products */ +product SURECOM RT2573 0x31f3 RT2573 /* System TALKS, Inc. */ product SYSTEMTALKS SGCX2UL 0x1920 SGC-X2UL >Release-Note: >Audit-Trail: >Unformatted: