summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@localhost>2011-08-26 05:24:55 +0200
committercinap_lenrek <cinap_lenrek@localhost>2011-08-26 05:24:55 +0200
commit1404cc50772688f05ab65a9eb2d5c8d4b85b0375 (patch)
tree010400734c4ba7998362bfdacc585842b8deca97
parenta6e3c9fd83e72e5c911e83f763e77ab6605a17d2 (diff)
downloadplan9front-1404cc50772688f05ab65a9eb2d5c8d4b85b0375.tar.xz
nusb: fix documentation, cleanup, remove /sys/src/cmd/usb
-rwxr-xr-xrc/bin/usbeject41
-rw-r--r--sys/man/2/nusb (renamed from sys/man/2/usb)86
-rw-r--r--sys/man/2/usbfs341
-rw-r--r--sys/man/3/audio2
-rw-r--r--sys/man/3/usb13
-rw-r--r--sys/man/4/usb516
-rw-r--r--sys/man/4/usbd245
-rw-r--r--sys/man/8/prep2
-rw-r--r--sys/src/cmd/nusb/lib/usb.h3
-rw-r--r--sys/src/cmd/usb/audio/audio.c402
-rw-r--r--sys/src/cmd/usb/audio/audio.h84
-rw-r--r--sys/src/cmd/usb/audio/audioctl.c688
-rw-r--r--sys/src/cmd/usb/audio/audioctl.h29
-rw-r--r--sys/src/cmd/usb/audio/audiofs.c939
-rw-r--r--sys/src/cmd/usb/audio/audiosub.c300
-rw-r--r--sys/src/cmd/usb/audio/mkfile31
-rw-r--r--sys/src/cmd/usb/disk/disk.c982
-rw-r--r--sys/src/cmd/usb/disk/main.c71
-rw-r--r--sys/src/cmd/usb/disk/mkfile41
-rwxr-xr-xsys/src/cmd/usb/disk/mkscsierrs32
-rw-r--r--sys/src/cmd/usb/disk/scsireq.c986
-rw-r--r--sys/src/cmd/usb/disk/scsireq.h238
-rw-r--r--sys/src/cmd/usb/disk/ums.h125
-rw-r--r--sys/src/cmd/usb/ether/asix.c484
-rw-r--r--sys/src/cmd/usb/ether/cdc.c60
-rw-r--r--sys/src/cmd/usb/ether/ether.c1185
-rw-r--r--sys/src/cmd/usb/ether/ether.h120
-rw-r--r--sys/src/cmd/usb/ether/main.c90
-rw-r--r--sys/src/cmd/usb/ether/mkfile35
-rw-r--r--sys/src/cmd/usb/kb/hid.h65
-rw-r--r--sys/src/cmd/usb/kb/kb.c610
-rw-r--r--sys/src/cmd/usb/kb/main.c67
-rw-r--r--sys/src/cmd/usb/kb/mkfile35
-rw-r--r--sys/src/cmd/usb/lib/dev.c493
-rw-r--r--sys/src/cmd/usb/lib/devs.c159
-rw-r--r--sys/src/cmd/usb/lib/dump.c176
-rw-r--r--sys/src/cmd/usb/lib/fs.c673
-rw-r--r--sys/src/cmd/usb/lib/fsdir.c420
-rw-r--r--sys/src/cmd/usb/lib/mkfile29
-rw-r--r--sys/src/cmd/usb/lib/parse.c270
-rw-r--r--sys/src/cmd/usb/lib/usb.h361
-rw-r--r--sys/src/cmd/usb/lib/usbfs.h61
-rw-r--r--sys/src/cmd/usb/mkfile38
-rw-r--r--sys/src/cmd/usb/print/main.c51
-rw-r--r--sys/src/cmd/usb/print/mkfile22
-rw-r--r--sys/src/cmd/usb/print/print.c91
-rw-r--r--sys/src/cmd/usb/probe26
-rw-r--r--sys/src/cmd/usb/serial/ftdi.c961
-rw-r--r--sys/src/cmd/usb/serial/ftdi.h632
-rw-r--r--sys/src/cmd/usb/serial/main.c75
-rw-r--r--sys/src/cmd/usb/serial/mkfile37
-rw-r--r--sys/src/cmd/usb/serial/prolific.c438
-rw-r--r--sys/src/cmd/usb/serial/prolific.h178
-rw-r--r--sys/src/cmd/usb/serial/serial.c890
-rw-r--r--sys/src/cmd/usb/serial/serial.h126
-rw-r--r--sys/src/cmd/usb/serial/ucons.c47
-rw-r--r--sys/src/cmd/usb/serial/ucons.h9
-rw-r--r--sys/src/cmd/usb/usbd/dev.c283
-rwxr-xr-xsys/src/cmd/usb/usbd/mkdev115
-rw-r--r--sys/src/cmd/usb/usbd/mkfile39
-rw-r--r--sys/src/cmd/usb/usbd/usbd.c875
-rw-r--r--sys/src/cmd/usb/usbd/usbd.h134
-rw-r--r--sys/src/cmd/usb/usbd/usbdb11
63 files changed, 14 insertions, 16654 deletions
diff --git a/rc/bin/usbeject b/rc/bin/usbeject
deleted file mode 100755
index cae9d0394..000000000
--- a/rc/bin/usbeject
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/rc
-# usbeject - unmount usb disks given as arguments
-# unmount all of them if no arguments given
-rfork e
-disk = ()
-mtpt = /n/usb
-
-test -e /dev/fs/ctl || bind -b '#k' /dev >[2]/dev/null
-
-test -e /dev/usb || bind -a '#u' /dev || {
- echo $0: no '#u/usb' >[1=2]
- exit nousb
-}
-test -e /dev/usbdctl || mount -a /srv/usb /dev || {
- echo $0: cannot mount /srv/usb >[1=2]
- exit nousbd
-}
-
-disks=()
-mtpt=()
-switch ($#*) {
-case 0
- disks=`{ls -pd /n/sdU*}
-case *
- disks=()
- for (a) {
- if(~ $a sd??)
- disk=`{ls -pd /n/^$*^*}
- if not
- disk=$a
- disks=($disks $disk)
- }
-}
-if (~ $disks '''sdU*''')
- exit ''
-for (disk in $disks) {
- unmount /n/$disk >[2]/dev/null && echo $disk unmounted
- if (test -e /dev/fs/ctl)
- echo del $disk^parts/^'*' >/dev/fs/ctl >[2]/dev/null
-}
-exit ''
diff --git a/sys/man/2/usb b/sys/man/2/nusb
index d6f949f98..e771cb56f 100644
--- a/sys/man/2/usb
+++ b/sys/man/2/nusb
@@ -1,17 +1,15 @@
-.TH USB 2
+.TH NUSB 2
.SH NAME
usbcmd,
classname,
closedev,
configdev,
devctl,
-finddevs,
+getdev,
loaddevstr,
-matchdevcsp,
opendev,
opendevdata,
openep,
-startdevs,
unstall,
class,
subclass,
@@ -22,7 +20,6 @@ CSP \- USB device driver library
.ta 8n +8n +8n +8n +8n +8n +8n
#include <u.h>
#include <libc.h>
-#include <thread.h>
#include "../lib/usb.h"
.sp 0.3v
struct Dev {
@@ -118,18 +115,15 @@ int configdev(Dev *d);
int devctl(Dev *dev, char *fmt, ...);
void* emallocz(ulong size, int zero);
char* estrdup(char *s);
-int finddevs(int (*matchf)(char*,void*), void *farg, char** dirs, int ndirs);
char* hexstr(void *a, int n);
char* loaddevstr(Dev *d, int sid);
-int matchdevcsp(char *info, void *a);
Dev* opendev(char *fn);
int opendevdata(Dev *d, int mode);
Dev* openep(Dev *d, int id);
-void startdevs(char *args, char *argv[], int argc,
- int (*mf)(char*,void*), void*ma, int (*df)(Dev*,int,char**));
int unstall(Dev *dev, Dev *ep, int dir);
int usbcmd(Dev *d, int type, int req,
int value, int index, uchar *data, int count);
+Dev* getdev(int id);
.sp 0.3v
extern int usbdebug; /* more messages for bigger values */
.EE
@@ -140,27 +134,14 @@ It is not intended for user programs using USB devices.
See
.IR usb (3)
for a description of the interfaces provided for that purpose.
-For drivers that provide a file system and may be embedded into
-.IR usbd ,
-the library includes a file system implementation toolkit described in
-.IR usbfs (2).
.PP
Usb drivers rely on
.IR usb (3)
to perform I/O through USB as well as on
-.IR usbd (4)
+.IR usbd
to perform the initial configuration for the device's setup endpoint.
The rest of the work is up to the driver and is where this library may help.
.PP
-In most cases, a driver locates the devices of interest and configures them
-by calling
-.I startdevs
-and
-then sets up additional endpoints as needed (by calling
-.IR openep )
-to finally perform I/O by reading and writing the
-data files for the endpoints.
-.PP
An endpoint as provided by
.IR usb (3)
is represented by a
@@ -238,54 +219,6 @@ to the library are kept unparsed at
as an aid for the driver
(which should know how to parse them and what to do with the information).
.SS Configuration
-.I Startdevs
-is a wrapper that locates devices of interest, loads their configuration
-information, and starts a
-.IR thread (2)'s
-.I proc
-for each device located so that it executes
-.I f
-as its main entry point. The entry point is called with a pointer to
-the
-.B Dev
-for the device it has to process,
-.BR argc ,
-and
-.BR argv .
-Devices are located either from the arguments (after options) in
-.IR argv ,
-if any,
-or by calling the helper function
-.I mf
-with the argument
-.I ma
-to determine (for each device available) if the device belongs to
-the driver or not. If the function returns -1 then the device is not for us.
-.PP
-In many cases,
-.I matchdevcsp
-may be supplied as
-.I mf
-along with a (null terminated) vector of CSP values supplied as
-.IR ma .
-This function returns 0 for any device with a CSP matching one in the
-vector supplied as an argument and -1 otherwise.
-In other cases (eg., when a particular vendor and device ids are the
-ones identifying the device) the driver must include its own function
-and supply it as an argument to
-.IR startdevs .
-The first argument of the function corresponds to the information
-known about the device (the second line in its
-.B ctl
-file).
-.I Openep
-creates the endpoint number
-.I id
-for the device
-.I d
-and returns a
-.B Dev
-structure to operate on it (with just the control file open).
.PP
.I Opendev
creates a
@@ -306,11 +239,6 @@ loads and parses its configuration information.
After calling it, the device is ready for I/O and the USB description in
.B Dev.usb
is valid.
-When using
-.IR startdevs
-it is not desirable to call this function (because
-.IR startdevs
-already calls it).
.PP
Control requests for an endpoint may be written by calling
.I devctl
@@ -450,11 +378,9 @@ and memory must be released by the caller.
returns the string obtained by reading the device string descriptor number
.IR sid .
.SH SOURCE
-.B /sys/src/cmd/usb/lib
+.B /sys/src/cmd/nusb/lib
.SH "SEE ALSO"
-.IR usbfs (2),
.IR usb (3),
-.IR usb (4),
-.IR usbd (4).
+.IR nusb (4).
.SH BUGS
Not heavily exercised yet.
diff --git a/sys/man/2/usbfs b/sys/man/2/usbfs
deleted file mode 100644
index 6c76280a8..000000000
--- a/sys/man/2/usbfs
+++ /dev/null
@@ -1,341 +0,0 @@
-.TH USBFS 2
-.SH NAME
-usbreadbuf,
-usbfsadd,
-usbfsdel,
-usbdirread,
-usbfsinit,
-usbdirfs,
-usbfs \- USB device driver file system library
-.SH SYNOPSIS
-.EX
-.ta 8n +8n +8n +8n +8n +8n +8n
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "../lib/usb.h"
-#include "../lib/usbfs.h"
-.sp 0.3v
-enum {
- Hdrsize = 128, /* plenty of room for headers */
- Msgsize = 8 * 1024,
- Bufsize = Hdrsize + Msgsize,
- Namesz = 40,
- Errmax = 128,
- ONONE = ~0, /* omode in Fid when not open */
-};
-.sp 0.3v
-struct Fid {
- int fid;
- Qid qid;
- int omode;
- Fid* next;
- void* aux;
-};
-.sp 0.3v
-struct Usbfs {
- char name[Namesz];
- uvlong qid;
- Dev* dev;
- void* aux;
-.sp 0.3v
- int (*walk)(Usbfs *fs, Fid *f, char *name);
- void (*clone)(Usbfs *fs, Fid *of, Fid *nf);
- void (*clunk)(Usbfs *fs, Fid *f);
- int (*open)(Usbfs *fs, Fid *f, int mode);
- long (*read)(Usbfs *fs, Fid *f,
- void *data, long count, vlong offset);
- long (*write)(Usbfs *fs, Fid*f,
- void *data, long count, vlong offset);
- int (*stat)(Usbfs *fs, Qid q, Dir *d);
- void (*end)(Usbfs *fs);
-};
-.sp 0.3v
-typedef int (*Dirgen)(Usbfs*, Qid, int, Dir*, void*);
-.sp 0.3v
-long usbreadbuf(void *data, long count,
- vlong offset, void *buf, long n);
-void usbfsadd(Usbfs *dfs);
-void usbfsdel(Usbfs *dfs);
-int usbdirread(Usbfs*f, Qid q, char *data, long cnt,
- vlong off, Dirgen gen, void *arg);
-void usbfsinit(char* srv, char *mnt, Usbfs *f, int flag);
-void usbfsdirdump(void);
-.sp 0.3v
-extern char Enotfound[], Etoosmall[], Eio[], Eperm[], Ebadcall[],
- Ebadfid[], Einuse[], Eisopen[], Ebadctl[];
-.sp 0.3v
-extern Usbfs usbdirfs;
-extern int usbfsdebug;
-.EE
-.SH DESCRIPTION
-This library provides an alternative to
-.IR 9p (2)
-for implementing a file server within a USB driver.
-Drivers using this
-library may be embedded into
-.IR usbd (4).
-It may be also desirable to use this library when drivers are
-not embedded because it is tailored to work well with the
-library for handling USB devices.
-.PP
-A USB file system is described by a
-.I Usbfs
-structure.
-In most cases, the driver is not responsible for the root of the
-file tree.
-It is customary that a driver creates a file server
-for each device handled and links all of them to a root directory
-implemented by the
-.I usbdirfs
-file system implemented by the library.
-This root directory is bound to
-.B /dev
-in most cases.
-.PP
-.I Usbdirfs
-implements a root directory populated by named file trees,
-each one described by a
-.B Usbfs
-structure.
-.PP
-The field
-.B Usbfs.name
-contains the name for the root directory of the file system, usually
-a directory seen at
-.BI /dev/ name
-when the driver is embedded.
-.PP
-.B Usbfs.qid
-maintains a value used to decorate qids for the file tree.
-This may be ignored when
-.I usbdirfs
-is not used.
-Otherwise,
-.I usbdirfs
-assigns a unique value kept at the high 32 bits of
-.B Qid.path
-for all files on each file tree bound to it.
-Each
-.I Usbfs
-server must bitwise OR
-.B Usbfs.qid
-to all
-.B Qid.path
-values returned by its functions.
-In the same way,
-functions usually clear bits in
-.B Usbfs.qid
-before processing
-.B Qid.path
-values supplied as input.
-.PP
-The USB device handled by a file tree is referenced from
-.B Usbfs.dev
-(and a reference must be counted for it).
-This permits the following functions to quickly locate the device of
-interest, and also permits releasing the device when
-no request is outstanding.
-.PP
-The field
-.B Usbfs.aux
-is for the device to use.
-The rest of the fields implement the 9P protocol for the device.
-Not all the operations need be implemented.
-Only
-.IR walk ,
-.IR open ,
-.IR read ,
-.IR write ,
-and
-.IR stat ,
-must be implemented (and their corresponding fields in
-.B Usbfs
-may never be
-.BR nil ).
-These functions must return -1 upon failure
-and set the error string to reflect the cause of a failure.
-.PP
-In all the functions, a 9P fid is represented by a
-.B Fid
-structure.
-It contains the 9P
-.IR fid ,
-the corresponding
-.IR qid ,
-and an auxiliary pointer for the driver to use.
-Open
-.IR fid s
-have a valid open mode in
-.I omode
-while others have
-.B ONONE
-to indicate that the
-.I fid
-is not open.
-The library takes care of which
-fids
-exist and which ones do not.
-.PP
-.I Walk
-must walk
-.I f
-to
-.I name
-(a single name, not a file path)
-in the supplied
-.IR fs .
-Its implementation should update the qid in
-.I f
-to reflect the walk.
-This function must bitwise OR any returned Qid with
-.B Usbfs.qid ,
-if
-.I usbdirfs
-is used.
-.PP
-.I Clone
-must clone fid
-.I of
-onto
-.I nf
-so that,
-upon successful completion,
-.I nf
-also refers to the file that
-.I f
-refers to.
-An implementation must update the Qid of the cloned
-fid.
-If this function is not supplied, the library copies the
-.I aux
-field to the cloned fid.
-.PP
-.I Clunk
-clunks
-.IR f .
-It usually releases data kept in the
-.I aux
-field, but may be
-set to
-.B nil
-otherwise.
-.PP
-.I Open
-prepares the fid
-.I f
-for I/O according to
-.IR mode .
-The open mode in the fid is updated by the library upon return.
-The library checks trivial cases like opening already-open fids.
-The implementation performs most permission checking.
-.PP
-.I Read
-reads up to
-.I count
-bytes into
-.I data
-starting at
-.I offset
-in the file referenced by
-.IR f .
-.I Write
-is the counterpart.
-To read from directories,
-the function
-.I usbdirread
-may be called.
-It returns the return value of
-.I read
-or -1.
-.I usbdirread
-calls
-.I gen
-to iterate through files as needed.
-The
-.B Dirgen
-function will be called with index values of 0
-and up to ask for the first file and following files.
-To read from data already in buffers, the function
-.I usbreadbuf
-may help.
-It must be given the arguments supplied
-by the user, plus the buffer and buffer size.
-.PP
-.I Stat
-must fill
-.I d
-with the directory entry for the file identified by
-.IR q.
-As an aid,
-.I d
-is initialized to fake access and modification times,
-and user and group ids.
-Also, the field
-.B name
-in
-.I d
-is initialized to point to a 40-byte buffer.
-If the file name fits,
-it may be copied directly into
-.B d->name
-without allocating memory for that purpose.
-Otherwise
-.B d->name
-must be initialized to point to static memory.
-.PP
-The function
-.I end
-is called upon termination of the file tree to
-release resources.
-.PP
-Calling
-.I usbfsinit
-starts a file server for
-.I f
-that mounts itself at
-.I mnt
-and posts
-.I srv
-at
-.IR srv (3).
-In most cases, the file system supplied is
-.IR usbdirfs .
-The
-.I flag
-is used for
-.IR mount
-(see
-.IR bind (2)).
-Once
-.I usbdirfs
-is started, calls to
-.IR usbfsadd
-add a file tree implemented by
-.I dfs
-to the root directory of
-.I usbdirfs
-and
-calls to
-.I usbfsdel
-remove that binding (and release resources including
-the reference to the USB device).
-.PP
-Various error strings are declared as an aid.
-The global
-.B usbfsdebug
-may be set to trigger diagnostics and protocol tracing.
-.SH EXAMPLE
-See
-.B /sys/src/cmd/usb/disk
-for an example driver that uses this library.
-Looking at an example is strongly suggested
-to see how reference counts for the USB device
-and the file system are handled.
-.SH SOURCE
-.B /sys/src/cmd/usb/lib
-.SH "SEE ALSO"
-.IR usb (2),
-.IR usb (3),
-.IR usb (4),
-.IR usbd (4)
diff --git a/sys/man/3/audio b/sys/man/3/audio
index e95608c83..520cbcec6 100644
--- a/sys/man/3/audio
+++ b/sys/man/3/audio
@@ -126,4 +126,4 @@ Defaults to 44100.
.SH SOURCE
.B /sys/src/9/port/devaudio.c
.SH SEE ALSO
-.IR usb (4)
+.IR nusb (4)
diff --git a/sys/man/3/usb b/sys/man/3/usb
index a79132ba0..c69129c1c 100644
--- a/sys/man/3/usb
+++ b/sys/man/3/usb
@@ -58,7 +58,7 @@ Specialization continues as subclasses and subsubclasses are explored.
.PP
Enumeration of the bus and initial configuration of devices is done
by a user level program,
-.IR usbd (4).
+.IR usbd .
Device drivers are implemented by separate user programs, although
some of them may be statically linked into
.IR usbd .
@@ -115,7 +115,7 @@ After configuring a device, other endpoints may be created
as dictated by the device to perform actual I/O.
.SS Operation
Bus enumeration and device configuration is performed by
-.IR usbd (4)
+.IR usbd
and not by this driver.
The driver provides an interface
to access existing endpoints (initially those for the built-in root hubs),
@@ -130,7 +130,7 @@ is a number identifying a device and
is a number identifying one of its endpoints.
.PP
For each device attached to the bus, and configured by
-.IR usbd (4),
+.IR usbd ,
an endpoint zero (a
.I setup
endpoint)
@@ -212,7 +212,7 @@ storage csp 0x500608 vid 0x951 did 0x1613 Kingston 'DT 101 II'
.LP
The first line contains status information.
The rest is information supplied by
-.IR usbd (4)
+.IR usbd
as an aid to locate devices.
The status information includes:
.TF "\fREndpoint mode
@@ -346,7 +346,7 @@ USB class, subclass and proto codes can be found at
Endpoint control files accept the following requests.
In most cases
the driver does not issue them, leaving the task to either
-.IR usbd (4)
+.IR usbd
or the usb driver library documented in
.IR usb (2).
.TF "\fLsamplehz\fI n
@@ -522,8 +522,7 @@ root of the USB interface
.B /sys/src/9/pc/usb?hci.c
.SH "SEE ALSO"
.IR usb (2),
-.IR usb (4),
-.IR usbd (4),
+.IR nusb (4),
.IR plan9.ini (8)
.SH BUGS
USB controllers limit the speed of all their ports
diff --git a/sys/man/4/usb b/sys/man/4/usb
deleted file mode 100644
index fa20e3a5d..000000000
--- a/sys/man/4/usb
+++ /dev/null
@@ -1,516 +0,0 @@
-.TH USB 4
-.SH NAME
-audio,
-ccid,
-disk,
-ether,
-kb,
-print,
-probe,
-serial,
-usbeject,
-usbfat:
-\- Universal Serial Bus device drivers
-.SH SYNOPSIS
-.B usb/kb
-[
-.B -dkm
-] [
-.B -a
-.I accel
-] [
-.I dev ...
-]
-.PP
-.B usb/disk
-[
-.B -Dd
-] [
-.B -m
-.I mnt
-] [
-.B -s
-.I srv
-] [
-.I dev ...
-]
-.PP
-.B usbfat:
-[
-.I disk ...
-]
-.PP
-.B usbeject
-[
-.I disk ...
-]
-.PP
-.B usb/audio
-[
-.B -dpV
-] [
-.B -m
-.I mnt
-] [
-.B -s
-.I srv
-] [
-.B -v
-.I vol
-] [
-.I dev
-]
-.PP
-.B usb/ether
-[
-.B -Dd
-] [
-.B -m
-.I mnt
-] [
-.B -s
-.I srv
-] [
-.I dev ...
-]
-.PP
-.B usb/serial
-[
-.B -Dd
-] [
-.B -m
-.I mnt
-] [
-.B -s
-.I srv
-] [
-.I dev ...
-]
-.PP
-.B usb/print
-[
-.B -d
-] [
-.I dev ...
-]
-.PP
-.B usb/ccid
-[
-.B -d
-]
-.ig
-.PP
-.B usb/ibuddy
-[
-.B -Dd
-] [
-.B -m
-.I mnt
-] [
-.B -s
-.I srv
-] [
-.I dev ...
-]
-..
-.B usb/probe
-.SH DESCRIPTION
-These programs drive USB devices of specific classes via
-.IR usb (3).
-Usually they are started by
-.IR usbd (4)
-upon attachment of the device to the bus.
-Less often, users start them manually, depending on
-.IR usbd (4)'s
-configuration.
-Usually,
-.I kb
-and
-.I disk
-are started by
-.I usbd
-and other programs are started by hand.
-.PP
-Without arguments, the drivers handle all the devices (of
-the appropriate USB class) found on the bus.
-To make a driver handle only certain devices, supply as arguments
-the paths for the directories of the devices
-(actually of their zero endpoints).
-.PP
-Drivers that provide file systems accept options
-.B -s
-and
-.B -m
-to instruct them to post a 9P connection at
-.IR srv (3)
-with the given name and/or to mount themselves at
-.IR mnt .
-When embedded into
-.IR usbd
-these options may not be used.
-In this case,
-the file tree supplied by the device driver is
-available through the file system provided by
-.IR usbd ,
-usually mounted at
-.B /dev
-and reachable through the 9P connection posted at
-.BR /srv/usb .
-.PP
-Options
-.B -d
-and
-.B -D
-present on most drivers trigger debug diagnostics and
-file system debugging diagnostics.
-Repeating any one of these may increase verbosity.
-.PP
-To help locate devices of interest,
-.I probe
-lists all the USB devices available,
-including those with no driver started.
-.SS Keyboards and mice
-.I Kb
-supports USB keyboards and mice either as separate USB devices
-or as a single combined USB device.
-Scan codes from the keyboard are sent to
-.B /dev/kbin
-to let
-.IR kbdfs (8)
-process them.
-Mouse events are sent to
-.B /dev/mousein
-in the same way.
-.PP
-The following options are understood:
-.TF -k
-.TP
-.B \-a
-Accelerate the mouse to level
-.I n
-(similar to the kernel mouse driver acceleration).
-.TP
-.B \-k
-Serve just the keyboard (and not the mouse).
-.TP
-.B \-m
-Serve just the mouse (and not the keyboard).
-.SS Disks
-.I Disk
-configures and manages USB mass storage devices. It
-provides a file system (usually seen at
-.BR /dev )
-that includes one directory per storage device, named
-.BI sdU N . M
-in correspondence with the usb device number and the storage
-unit number (or LUN).
-For example, LUN number 2 on
-.B /dev/usb/ep3.0
-can be accessed through
-.BR /dev/sdU3.2 .
-.PP
-The storage device directory contains the usual files
-served by
-.IR sd (3):
-.BR data ,
-.BR raw ,
-and
-.BR ctl .
-.PP
-The
-.B ctl
-file supplies the device
-geometry when read.
-.PP
-The script
-.B usbfat:
-mounts the FAT file systems in the DOS partitions of the named
-.IR disk s;
-if none, it mounts those file systems found at
-.BR /dev/sdU*.*/data .
-When more than one partition is found, a suffix is appended to
-the disk name to identify the partition number.
-The script
-.B usbeject
-undoes the effect. If no argument is given, it unmounts all USB
-disks. An argument
-.BI sdU N
-unmounts all partitions from disk with USB target
-.IR N .
-.ig
-An argument
-.BI sdU N . M
-or
-.BI sdU N . M . P
-.\" TODO: fill in missing words
-..
-.SS Printers
-.I Print
-provides a single file can be written to print on a USB printer.
-Options are similar to those of
-.IR disk .
-The file is also bound at
-.B /dev/lp
-as is customary.
-.SS Ethernet adapters
-.I Ether
-provides a file interface similar to that of
-.IR ether (3)
-for each USB Ethernet adapter found.
-The name of an Ethernet device is
-.BI etherU N
-where
-.I N
-is the device name.
-When started manually, the file interface is mounted at
-.B /net
-as is customary.
-.
-.SS Serial and JTAG ports
-.I Serial
-provides a file system (usually mounted at
-.BR /dev )
-that includes one directory per USB serial port, named
-.BI eiaU N
-or
-.BI eiaU N . M.
-In this directory there are two files,
-.BR eiaU ,
-similar to
-.BI eia N
-in
-.IR uart (3),
-and
-.BR eiaUctl ,
-which admits writes in the same format as
-.BI eia N ctl
-in
-.IR uart (3).
-Reading from
-.B eiaUctl
-gives the serial port's settings in the same format as
-.BI eia N status
-in
-.IR uart (3).
-Options are similar to those of
-.IR disk .
-.PP
-JTAG ports are similar
-but the files are named
-.B jtag
-and
-.BR jtagctl .
-.
-.SS Audio devices
-.I Usbaudio
-configures and manages a USB audio device.
-It implements a file system,
-normally mounted on
-.BI /dev ,
-but this can be changed with
-.BR \-m ,
-containing files
-.BR volume ,
-.BR audioctl ,
-.BR audio ,
-and
-.BR audioin .
-The names
-.B volume
-and
-.B audio
-maintain backward compatibility with the Soundblaster driver.
-.PP
-The
-.B \-V
-option (verbose)
-causes
-.I audio
-to print information about the device on startup.
-The
-.B \-s
-option specifies a name for a file descriptor to be posted in
-.BR /srv .
-The
-.B \-v
-options sets initial
-.IR volume .
-.PP
-Reading
-.B volume
-or
-.B audioctl
-yields the device's settings.
-The data format of
-.B volume
-is compatible with the Soundblaster and produces output in this
-format:
-.IP
-.EX
-audio out 65
-treb out 0
-bass out 0
-speed out 44100
-.EE
-.PP
-This file can be written using the same syntax.
-The keyword
-.L out
-may be omitted.
-Settings are given as percentages of the range,
-except for speed which is in Hz.
-.PP
-The file
-.B audioctl
-provides more information, using up to 6 columns of 12 characters each.
-From left to right, the fields are:
-.IR "control name" ,
-.I in
-or
-.IR out ,
-.IR "current value" ,
-.IR "minimum value" ,
-.IR maximum ,
-and
-.IR resolution .
-There are 3, 5, or 6 columns present.
-Maxima and resolution are omitted when they are not available or not applicable.
-The resolution for
-.I speed
-is reported as 1 (one) if the sampling frequency is continuously variable.
-It is absent if it is settable at a fixed number of discrete values only.
-.PP
-When all values from
-.B audioctl
-have been read, a zero-length buffer is returned
-(the usual end-of-file indication).
-A new
-.I read
-will then block until one of the settings changes,
-then report its new value.
-.PP
-The file
-.B audioctl
-can be written like
-.BR volume .
-.PP
-Audio data is written to
-.B audio
-and read from
-.BR audioin .
-The data format is little-endian,
-samples ordered primarily by time and
-secondarily by channel.
-Samples occupy the minimum integral number of bytes.
-Read and write operations of arbitrary size are allowed.
-.
-.SS Ccid
-.I Ccid
-discovers and configures SIM or SAM cards using the CCID standard.
-It provides a file system (usually mounted at
-.BR /dev )
-that includes three files,
-.BI ctl ,
-.B raw
-and
-.BI rpc .
-Reading from
-.B ctl
-a description of the smartcard reader capabilities is printed.
-.B raw
-is just intended for debugging.
-Reads and writes to the
-raw file send and receive raw CCID packets.
-Smart cards identify themselves by giving out an ATR,
-an array of characters describing the card uniquely.
-Users of the driver write the ATR to the
-.B rpc
-file and are blocked until a card with that ATR is seen.
-From then on they can do ICC RPCs using whatever
-language the smart card speaks. A small write cancels
-an outstanding RPC.
-.PP
-The driver takes care of powering the card adequately, based
-on its ATR, and tunnelling the RPCs through the USB device.
-Only slot 0 is supported.
-.PP
-When the smartcard disappears,
-all reads and write fail until the file is reopened and
-a new ATR is written to it.
-.
-.ig
-.SS Ibuddy
-.PP
-Ibuddy supports a USB I-buddy toy, a little winged-demon.
-The driver provides one directory per attached toy with a single
-.BR ctl
-file to control the device.
-Directories are named
-.BR ibuddyN ,
-being
-.I N
-the corresponding usb device number.
-When read, the
-.BR ctl
-file provides the state of the device in this form:
-.IP
-.EX
-hips right|left
-wings open|close
-red on|off
-green on|off
-blue on|off
-heart on|off
-.EE
-.PP
-Each line describes the status of one feature.
-.IR Red ,
-.IR blue ,
-and
-.IR green
-are the different leds in the head of
-the toy.
-.IR Heart
-represents the red led in the chest of
-the toy.
-.IR Wings
-represents the status of the wings, which
-can be closed or open.
-.IR Hips
-represents the orientation
-of the toy (left or right, from the figure's point of view).
-.PP
-Lines can be written to the
-.BR ctl
-file to command the device.
-Multiple lines (six at most) can be written
-at once, with one action per line.
-..
-.SH SOURCE
-.B /sys/src/cmd/usb
-.SH "SEE ALSO"
-.IR mouse (3),
-.IR sd (3),
-.IR uart (3),
-.IR usb (3),
-.IR usbd (4),
-.IR partfs (8),
-.IR kbdfs (8)
-.SH BUGS
-The various device drivers are generic USB drivers and
-may work only for certain devices on each class.
-.PP
-USB ATA storage devices are not supported.
-.PP
-The Ethernet device works only for certain ASIX-based cards and for CDC devices.
-Both the Ethernet and printer drivers have not
-been tested and it is likely they will fail.
-.PP
-The serial driver works only for the Prolific chip and Ftdi,
-and control of the
-.B dcd
-and
-.B dsr
-signals and some of the extra features are unimplemented.
-For Ftdi, only the Sheevaplug and Guruplug have been tried.
-There is support for the EHCI debug port, but it loses bytes.
diff --git a/sys/man/4/usbd b/sys/man/4/usbd
deleted file mode 100644
index c0d3ca6cd..000000000
--- a/sys/man/4/usbd
+++ /dev/null
@@ -1,245 +0,0 @@
-.TH USBD 4
-.SH NAME
-usbd \- Universal Serial Bus daemon
-.SH SYNOPSIS
-.B usbd
-[
-.B -Dd
-]
-[
-.B -s
-.I srv
-]
-[
-.B -m
-.I mnt
-]
-[
-.I hub...
-]
-.SH DESCRIPTION
-.I Usbd
-complements
-.IR usb (3)
-to provide USB I/O for device drivers.
-It enumerates the bus, polling
-hub ports to detect device attachments and detachments, performs
-initial configuration of setup endpoints, and writes extra information into
-.IR usb (3)
-endpoint control files, to ease device location.
-.PP
-By default,
-.I usbd
-opens all setup endpoints found at
-.B #u/usb
-(which correspond to built-in hubs initialized by the kernel during boot).
-Paths to directories representing setup endpoints for hubs can be given
-as arguments to restrict
-.I usbd
-operation to such hubs.
-.PP
-When a device is attached,
-depending upon a configuration file compiled into
-.I usbd ,
-the appropriate device driver may be started without
-user intervention.
-This mechanism can be used to statically link some USB device drivers into
-.I usbd
-itself.
-Initial configuration for setup endpoints is performed independently
-of this configuration.
-.PP
-.I Usbd
-provides a file interface used to change debugging flags, and also used by
-USB device drivers statically linked into
-.IR usbd .
-By default, the file system is mounted (after) at
-.B /dev
-and a 9P connection is posted at
-.BR /srv/usb .
-.PP
-Besides files provided by device drivers, the file
-.B usbdctl
-is always present in the file interface.
-It accepts these control requests:
-.TF "fsdebug\fI n
-.TP
-.BI debug " n"
-Sets the debugging level to
-.IR n .
-.TP
-.BI fsdebug " n"
-Sets the file system debugging level to
-.IR n .
-.TP
-.B dump
-Prints the list of devices and file systems known by
-.IR usbd .
-.PD
-.PP
-.I Usbd
-recognizes the following options:
-.TF "-m\fI mnt
-.TP
-.B -d
-Print debugging diagnostics.
-Repeating the option increases verbosity.
-.TP
-.B -D
-Print debugging diagnostics for the file system interface.
-.TP
-.BI -m " mnt"
-Mount the served file system at
-.IR mnt .
-.TP
-.BI -s " srv"
-Post a 9P connection at
-.BI #s/ srv.
-.PD
-.SS Configuration
-.PP
-.I Usbd
-can be configured to start drivers for devices matching one or more CSPs
-(hex representation of USB class, subclass and protocol), class,
-subclass, protocol, vendor id, or device id.
-When a new device is attached,
-.I usbd
-scans the configuration and, if an entry matches the device descriptor, starts
-the driver.
-If no driver is configured, the setup endpoint for the device is left
-configured to let the user start the driver by hand.
-.PP
-Configuration is via compilation
-because one of the options is to embed (link) the driver into the
-.I usbd
-binary.
-If the driver is embedded,
-.I usbd
-creates a process for it and calls its main entry point.
-Otherwise,
-.I usbd
-tries to locate the driver binary in
-.B /bin/usb
-and creates a process to execute it.
-.PP
-The configuration file,
-.BR usbdb ,
-has two sections:
-.B embed
-and
-.BR auto .
-Each section includes lines to configure particular drivers.
-A driver may have more than one line if necessary.
-Each line includes the name of the
-driver (the base name of the binary) and one or more attributes of the form
-.IP
-.IR name = value
-.PP
-The following attributes exist:
-.TF subclass
-.TP
-.B class
-.I Value
-may be the name of the class
-or a number identifying the device class (using C syntax).
-The following class names are known:
-.BR audio ,
-.BR comms ,
-.BR hid ,
-.BR printer ,
-.BR storage ,
-.BR hub ,
-and
-.BR data .
-.TP
-.B subclass
-.I Value
-is the number of the device subclass.
-.TP
-.B proto
-.I Value
-is the number of the device protocol.
-.TP
-.B csp
-.I Value
-is the hexadecimal number describing the CSP for the device.
-.TP
-.B vid
-.I Value
-is the vendor id.
-.TP
-.B did
-.I Value
-is the device id.
-.TP
-.B args
-This must be the last field.
-The value is the rest of the line,
-and is supplied as arguments to the driver process.
-.PD
-.LP
-Several environment variables can be used to alter the behaviour of
-.IR usbd ,
-for example, for use in
-.IR plan9.ini (8).
-.B usbdebug
-sets a debug level (zero for no diagnostics and positive
-values for increasing verbosity).
-.B kbargs
-overrides the keyboard arguments as specified by the configuration file.
-.B diskargs
-overrides the disk arguments in the same way.
-.SH EXAMPLE
-This configuration file links
-.B usb/kb
-into
-.I usbd
-when it is compiled.
-It arranges for the driver's entry point,
-.B kbmain
-in this case,
-to be called for any device with CSPs matching either
-.B 0x010103
-or
-.BR 0x020103 .
-Option
-.B -d
-will be supplied as command line arguments for
-.BR kbmain .
-This configuration also arranges for
-.B /bin/usb/disk
-to start (with no arguments) whenever a device of class
-.B storage
-is attached.
-.IP
-.EX
-embed
- kb csp=0x010103 csp=0x020103 args=-d
-auto
- disk class=storage args=
-.EE
-.SH FILES
-.TF /srv/usb
-.TP
-.B /srv/usb
-9P connection to the driver file system.
-.TP
-.B /dev
-mount point for the driver file system.
-.TP
-.B /sys/src/cmd/usb/usbd/usbdb
-Configuration file deciding which devices are included into
-.I usbd
-and which ones are started automatically.
-.SH SOURCE
-.B /sys/src/cmd/usb/usbd
-.SH "SEE ALSO"
-.IR usb (2),
-.IR usb (3),
-.IR usb (4)
-.SH BUGS
-.I Usbd
-is not supposed to be restarted.
-This is arguable.
-.PP
-Not heavily exercised yet.
diff --git a/sys/man/8/prep b/sys/man/8/prep
index 3d72fda47..c09232d34 100644
--- a/sys/man/8/prep
+++ b/sys/man/8/prep
@@ -709,7 +709,7 @@ disk/format -b /386/pbs -d -r 2 /dev/sdC0/9fat \e
.SH SEE ALSO
.IR floppy (3),
.IR sd (3),
-.IR usb (4),
+.IR nusb (4),
.IR 9boot (8),
.IR partfs (8)
.SH BUGS
diff --git a/sys/src/cmd/nusb/lib/usb.h b/sys/src/cmd/nusb/lib/usb.h
index adba943ec..24454a58f 100644
--- a/sys/src/cmd/nusb/lib/usb.h
+++ b/sys/src/cmd/nusb/lib/usb.h
@@ -339,8 +339,6 @@ int configdev(Dev *d);
int devctl(Dev *dev, char *fmt, ...);
void* emallocz(ulong size, int zero);
char* estrdup(char *s);
-int matchdevcsp(char *info, void *a);
-int finddevs(int (*matchf)(char*,void*), void *farg, char** dirs, int ndirs);
char* hexstr(void *a, int n);
int loaddevconf(Dev *d, int n);
int loaddevdesc(Dev *d);
@@ -351,7 +349,6 @@ Dev* openep(Dev *d, int id);
int parseconf(Usbdev *d, Conf *c, uchar *b, int n);
int parsedesc(Usbdev *d, Conf *c, uchar *b, int n);
int parsedev(Dev *xd, uchar *b, int n);
-void startdevs(char *args, char *argv[], int argc, int (*mf)(char*,void*), void*ma, int (*df)(Dev*,int,char**));
int unstall(Dev *dev, Dev *ep, int dir);
int usbcmd(Dev *d, int type, int req, int value, int index, uchar *data, int count);
Dev* getdev(int id);
diff --git a/sys/src/cmd/usb/audio/audio.c b/sys/src/cmd/usb/audio/audio.c
deleted file mode 100644
index 6a4bed1db..000000000
--- a/sys/src/cmd/usb/audio/audio.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * USB audio driver for Plan 9
- * This needs a full rewrite.
- * As it is, it does not check for all errors,
- * mixes the audio data structures with the usb configuration,
- * may cross nil pointers, and is hard to debug and fix.
- * Also, it does not issue a dettach request to the endpoint
- * after the device is unplugged. This means that the old
- * endpoint would still be around until manually reclaimed.
- */
-
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-#include "audio.h"
-#include "audioctl.h"
-
-#define STACKSIZE 16*1024
-
-extern char* srvpost;
-char * mntpt;
-
-Channel *controlchan;
-
-int verbose;
-int setrec = 0;
-int defaultspeed[2] = {44100, 44100};
-Dev *buttondev;
-Dev *epdev[2];
-
-static void
-audio_endpoint(Dev *, Desc *dd)
-{
- byte *b = (uchar*)&dd->data;
- int n = dd->data.bLength;
- char *hd;
-
- switch(b[2]){
- case 0x01:
- if(usbdebug){
- fprint(2, "CS_ENDPOINT for attributes 0x%x, lockdelayunits %d, lockdelay %#ux, ",
- b[3], b[4], b[5] | (b[6]<<8));
- if(b[3] & has_setspeed)
- fprint(2, "has sampling-frequency control");
- else
- fprint(2, "does not have sampling-frequency control");
- if(b[3] & 0x1<<1)
- fprint(2, ", has pitch control");
- else
- fprint(2, ", does not have pitch control");
- if(b[3] & 0x1<<7)
- fprint(2, ", max packets only");
- fprint(2, "\n");
- }
- if(dd->conf == nil)
- sysfatal("conf == nil");
- if(dd->iface == nil)
- sysfatal("iface == nil");
- if(dd->altc == nil)
- sysfatal("alt == nil");
- if(dd->altc->aux == nil)
- dd->altc->aux= mallocz(sizeof(Audioalt),1);
- ((Audioalt*)dd->altc->aux)->caps |= b[3];
- break;
- case 0x02:
- if(usbdebug){
- fprint(2, "CS_INTERFACE FORMAT_TYPE %d, channels %d, subframesize %d, resolution %d, freqtype %d, ",
- b[3], b[4], b[5], b[6], b[7]);
- fprint(2, "freq0 %d, freq1 %d\n",
- b[8] | (b[9]<<8) | (b[10]<<16), b[11] | (b[12]<<8) | (b[13]<<16));
- }
- break;
- default:
- if(usbdebug){
- hd = hexstr(b, n);
- fprint(2, "CS_INTERFACE: %s\n", hd);
- free(hd);
- }
- }
-}
-
-enum {
- None,
- Volumeset,
- Volumeget,
- Altset,
- Altget,
- Speedget,
-};
-
-void
-controlproc(void *)
-{
- /* Proc that looks after /dev/usb/%d/ctl */
- int i, nf;
- char *req, *args[8];
- Audiocontrol *c;
- long value[8];
- Channel *replchan;
-
- while(req = recvp(controlchan)){
- int rec;
-
- nf = tokenize(req, args, nelem(args));
- if(nf < 3)
- sysfatal("controlproc: not enough arguments");
- replchan = (Channel*)strtol(args[0], nil, 0);
- if(strcmp(args[2], "playback") == 0)
- rec = Play;
- else if(strcmp(args[2], "record") == 0)
- rec = Record;
- else{
- /* illegal request */
- dprint(2, "%s must be record or playback", args[2]);
- if(replchan) chanprint(replchan, "%s must be record or playback", args[2]);
- free(req);
- continue;
- }
- c = nil;
- for(i = 0; i < Ncontrol; i++){
- c = &controls[rec][i];
- if(strcmp(args[1], c->name) == 0)
- break;
- }
- if(i == Ncontrol){
- dprint(2, "Illegal control name: %s", args[1]);
- if(replchan) chanprint(replchan, "Illegal control name: %s", args[1]);
- }else if(!c->settable){
- dprint(2, "%s %s is not settable", args[1], args[2]);
- if(replchan)
- chanprint(replchan, "%s %s is not settable", args[1], args[2]);
- }else if(nf < 4){
- dprint(2, "insufficient arguments for %s %s", args[1], args[2]);
- if(replchan)
- chanprint(replchan, "insufficient arguments for %s %s",
- args[1], args[2]);
- }else if(ctlparse(args[3], c, value) < 0){
- if(replchan)
- chanprint(replchan, "parse error in %s %s", args[1], args[2]);
- }else{
- dprint(2, "controlproc: setcontrol %s %s %s\n",
- rec?"in":"out", args[1], args[3]);
- if(setcontrol(rec, args[1], value) < 0){
- if(replchan)
- chanprint(replchan, "setting %s %s failed", args[1], args[2]);
- }else{
- if(replchan) chanprint(replchan, "ok");
- }
- ctlevent();
- }
- free(req);
- }
-}
-
-void
-buttonproc(void *)
-{
- int i, fd, b;
- char err[32];
- byte buf[1];
- Audiocontrol *c;
-
- fd = buttondev->dfd;
-
- c = &controls[Play][Volume_control];
- for(;;){
- if((b = read(fd, buf, 1)) < 0){
- rerrstr(err, sizeof err);
- if(strcmp(err, "interrupted") == 0){
- dprint(2, "read interrupted\n");
- continue;
- }
- sysfatal("read %s/data: %r", buttondev->dir);
- }
- if(b == 0 || buf[0] == 0){
- continue;
- }else if(buf[0] == 1){
- if(c->chans == 0)
- c->value[0] += c->step;
- else
- for(i = 1; i < 8; i++)
- if(c->chans & 1 << i)
- c->value[i] += c->step;
- chanprint(controlchan, "0 volume playback %A", c);
- }else if(buf[0] == 2){
- if(c->chans == 0)
- c->value[0] -= c->step;
- else
- for(i = 1; i < 8; i++)
- if(c->chans & 1 << i)
- c->value[i] -= c->step;
- chanprint(controlchan, "0 volume playback %A", c);
- }else if(usbdebug){
- fprint(2, "button");
- for(i = 0; i < b; i++)
- fprint(2, " %#2.2x", buf[i]);
- fprint(2, "\n");
- }
- }
-}
-
-
-void
-usage(void)
-{
- fprint(2, "usage: usbaudio [-dpV] [-N nb] [-m mountpoint] [-s srvname] "
- "[-v volume] [dev]\n");
- threadexitsall("usage");
-}
-
-void
-threadmain(int argc, char **argv)
-{
- char *devdir;
- int i;
- long value[8], volume[8];
- Audiocontrol *c;
- char *p;
- extern int attachok;
- Ep *ep;
- int csps[] = { Audiocsp, 0};
-
- devdir = nil;
- volume[0] = Undef;
- for(i = 0; i<8; i++)
- value[i] = 0;
- fmtinstall('A', Aconv);
- fmtinstall('U', Ufmt);
- quotefmtinstall();
-
- ARGBEGIN{
- case 'N':
- p = EARGF(usage()); /* ignore dev nb */
- break;
- case 'd':
- usbdebug++;
- verbose++;
- break;
- case 'm':
- mntpt = EARGF(usage());
- break;
- case 'p':
- attachok++;
- break;
- case 's':
- srvpost = EARGF(usage());
- break;
- case 'v':
- volume[0] = strtol(EARGF(usage()), &p, 0);
- for(i = 1; i < 8; i++)
- volume[i] = volume[0];
- break;
- case 'V':
- verbose++;
- break;
- default:
- usage();
- }ARGEND
- switch(argc){
- case 0:
- break;
- case 1:
- devdir = argv[0];
- break;
- default:
- usage();
- }
- if(devdir == nil)
- if(finddevs(matchdevcsp, csps, &devdir, 1) < 1){
- fprint(2, "No usb audio\n");
- threadexitsall("usbaudio not found");
- }
- ad = opendev(devdir);
- if(ad == nil)
- sysfatal("opendev: %r");
- if(configdev(ad) < 0)
- sysfatal("configdev: %r");
-
- for(i = 0; i < nelem(ad->usb->ddesc); i++)
- if(ad->usb->ddesc[i] != nil)
- switch(ad->usb->ddesc[i]->data.bDescriptorType){
- case AUDIO_INTERFACE:
- audio_interface(ad, ad->usb->ddesc[i]);
- break;
- case AUDIO_ENDPOINT:
- audio_endpoint(ad, ad->usb->ddesc[i]);
- break;
- }
-
- controlchan = chancreate(sizeof(char*), 8);
-
- for(i = 0; i < nelem(ad->usb->ep); i++)
- if((ep = ad->usb->ep[i]) != nil){
- if(ep->iface->csp == CSP(Claudio, 2, 0) && ep->dir == Eout)
- endpt[0] = ep->id;
- if(ep->iface->csp == CSP(Claudio, 2, 0) && ep->dir == Ein)
- endpt[1] = ep->id;
- if(buttonendpt<0 && Class(ep->iface->csp) == Clhid)
- buttonendpt = ep->id;
- }
- if(endpt[0] != -1){
- if(verbose)
- fprint(2, "usb/audio: playback on ep %d\n", endpt[0]);
- interface[0] = ad->usb->ep[endpt[0]]->iface->id;
- }
- if(endpt[1] != -1){
- if(verbose)
- fprint(2, "usb/audio: record on ep %d\n", endpt[0]);
- interface[1] = ad->usb->ep[endpt[1]]->iface->id;
- }
- if(verbose && buttonendpt >= 0)
- fprint(2, "usb/audio: buttons on ep %d\n", buttonendpt);
-
- if(endpt[Play] >= 0){
- if(verbose)
- fprint(2, "Setting default play parameters: %d Hz, %d channels at %d bits\n",
- defaultspeed[Play], 2, 16);
- if(findalt(Play, 2, 16, defaultspeed[Play]) < 0){
- if(findalt(Play, 2, 16, 48000) < 0)
- sysfatal("Can't configure playout for %d or %d Hz", defaultspeed[Play], 48000);
- fprint(2, "Warning, can't configure playout for %d Hz, configuring for %d Hz instead\n",
- defaultspeed[Play], 48000);
- defaultspeed[Play] = 48000;
- }
- value[0] = 2;
- if(setcontrol(Play, "channels", value) == Undef)
- sysfatal("Can't set play channels");
- value[0] = 16;
- if(setcontrol(Play, "resolution", value) == Undef)
- sysfatal("Can't set play resolution");
- }
-
- if(endpt[Record] >= 0){
- setrec = 1;
- if(verbose)
- fprint(2, "Setting default record parameters: "
- "%d Hz, %d channels at %d bits\n",
- defaultspeed[Record], 2, 16);
- i = 2;
- while(findalt(Record, i, 16, defaultspeed[Record]) < 0)
- if(i == 2 && controls[Record][Channel_control].max == 1){
- fprint(2, "Warning, can't configure stereo "
- "recording, configuring mono instead\n");
- i = 1;
- }else
- break;
- if(findalt(Record, i, 16, 48000) < 0){
- endpt[Record] = -1; /* disable recording */
- setrec = 0;
- fprint(2, "Warning, can't configure record for %d Hz or %d Hz\n",
- defaultspeed[Record], 48000);
- }else
- fprint(2, "Warning, can't configure record for %d Hz, "
- "configuring for %d Hz instead\n",
- defaultspeed[Record], 48000);
- defaultspeed[Record] = 48000;
- if(setrec){
- value[0] = i;
- if(setcontrol(Record, "channels", value) == Undef)
- fprint(2, "%s: can't set record channels\n", argv0);
- value[0] = 16;
- if(setcontrol(Record, "resolution", value) == Undef)
- fprint(2, "%s: can't set record resolution\n", argv0);
- }
- }
-
- getcontrols(); /* Get the initial value of all controls */
- value[0] = defaultspeed[Play];
- if(endpt[Play] >= 0 && setcontrol(Play, "speed", value) < 0)
- fprint(2, "%s: can't set play speed\n", argv0);
- value[0] = defaultspeed[Record];
- if(endpt[Record] >= 0 && setcontrol(Record, "speed", value) < 0)
- fprint(2, "%s: can't set record speed\n", argv0);
- value[0] = 0;
- setcontrol(Play, "mute", value);
-
- if(volume[0] != Undef){
- c = &controls[Play][Volume_control];
- if(*p == '%' && c->min != Undef)
- for(i = 0; i < 8; i++)
- volume[i] = (volume[i]*c->max + (100-volume[i])*c->min)/100;
- if(c->settable)
- setcontrol(Play, "volume", volume);
- c = &controls[Record][Volume_control];
- if(c->settable && setrec)
- setcontrol(Record, "volume", volume);
- }
-
- if(buttonendpt > 0){
- buttondev = openep(ad, buttonendpt);
- if(buttondev == nil)
- sysfatal("openep: buttons: %r");
- if(opendevdata(buttondev, OREAD) < 0)
- sysfatal("open buttons fd: %r");
- proccreate(buttonproc, nil, STACKSIZE);
- }
- proccreate(controlproc, nil, STACKSIZE);
- proccreate(serve, nil, STACKSIZE);
-
- threadexits(nil);
-}
diff --git a/sys/src/cmd/usb/audio/audio.h b/sys/src/cmd/usb/audio/audio.h
deleted file mode 100644
index 8944a1372..000000000
--- a/sys/src/cmd/usb/audio/audio.h
+++ /dev/null
@@ -1,84 +0,0 @@
-enum {
- master_chan = 0x00,
- Speed_control = 0x00,
- /* Items below are defined by USB standard: */
- Mute_control = 0x01,
- Volume_control = 0x02,
- Bass_control = 0x03,
- Mid_control = 0x04,
- Treble_control = 0x05,
- Equalizer_control = 0x06,
- Agc_control = 0x07,
- Delay_control = 0x08,
- Bassboost_control = 0x09,
- Loudness_control = 0x0a,
- /* Items below are defined by implementation: */
- Channel_control = 0x0b,
- Resolution_control = 0x0c,
- Ncontrol,
- Selector_control = 0x0d,
-
- sampling_freq_control = 0x01,
-
- Audiocsp = 0x000101, /* audio.control.0 */
-
- AUDIO_INTERFACE = 0x24,
- AUDIO_ENDPOINT = 0x25,
-};
-
-
-#define AS_GENERAL 1
-#define FORMAT_TYPE 2
-#define FORMAT_SPECIFIC 3
-
-#define PCM 1
-#define PCM8 2
-#define IEEE_FLOAT 3
-#define ALAW 4
-#define MULAW 5
-
-#define SAMPLING_FREQ_CONTROL 0x01
-
-typedef struct Audioalt Audioalt;
-
-struct Audioalt {
- int nchan;
- int res;
- int subframesize;
- int minfreq, maxfreq; /* continuous freqs */
- int freqs[8]; /* discrete freqs */
- int caps; /* see below for meanings */
-};
-
-enum {
- /* Audioalt->caps bits */
- has_setspeed = 0x1, /* has a speed_set command */
- has_pitchset = 0x2, /* has a pitch_set command */
- has_contfreq = 0x4, /* frequency continuously variable */
- has_discfreq = 0x8, /* discrete set of frequencies */
- onefreq = 0x10, /* only one frequency */
- maxpkt_only = 0x80, /* packets must be padded to max size */
-};
-
-typedef uchar byte;
-
-extern int setrec;
-extern int verbose;
-extern int defaultspeed[2];
-extern Dev *ad;
-extern Dev *buttondev;
-extern Channel *controlchan;
-extern Dev *epdev[2];
-
-void audio_interface(Dev *d, Desc *dd);
-void setalt(Dev *d, int endpt, int value);
-int getalt(Dev *d, int endpt);
-int setspeed(int rec, int speed);
-int setcontrol(int rec, char *name, long *value);
-int getspecialcontrol(int rec, int ctl, int req, long *value);
-int getcontrol(int rec, char *name, long *value);
-int findalt(int rec, int nchan, int res, int speed);
-void getcontrols(void);
-void serve(void *);
-int nbchanprint(Channel *c, char *fmt, ...);
-int Aconv(Fmt *fp);
diff --git a/sys/src/cmd/usb/audio/audioctl.c b/sys/src/cmd/usb/audio/audioctl.c
deleted file mode 100644
index ab63c0d37..000000000
--- a/sys/src/cmd/usb/audio/audioctl.c
+++ /dev/null
@@ -1,688 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-#include "audio.h"
-#include "audioctl.h"
-
-int endpt[2] = {-1, -1};
-int interface[2] = {-1, -1};
-int featureid[2] = {-1, -1};
-int selectorid[2] = {-1, -1};
-int mixerid[2] = {-1, -1};
-int curalt[2] = {-1, -1};
-int buttonendpt = -1;
-
-int id;
-Dev *ad;
-
-Audiocontrol controls[2][Ncontrol] = {
- {
- [Speed_control] = { "speed", 0, {0}, 0, 44100, Undef},
- [Mute_control] = { "mute", 0, {0}, 0, 0, Undef},
- [Volume_control] = { "volume", 0, {0}, 0, 0, Undef},
- [Bass_control] = { "bass", 0, {0}, 0, 0, Undef},
- [Mid_control] = { "mid", 0, {0}, 0, 0, Undef},
- [Treble_control] = { "treble", 0, {0}, 0, 0, Undef},
- [Equalizer_control] = { "equalizer", 0, {0}, 0, 0, Undef},
- [Agc_control] = { "agc", 0, {0}, 0, 0, Undef},
- [Delay_control] = { "delay", 0, {0}, 0, 0, Undef},
- [Bassboost_control] = { "bassboost", 0, {0}, 0, 0, Undef},
- [Loudness_control] = { "loudness", 0, {0}, 0, 0, Undef},
- [Channel_control] = { "channels", 0, {0}, 0, 2, Undef},
- [Resolution_control] = { "resolution", 0, {0}, 0, 16, Undef},
-// [Selector_control] = { "selector", 0, {0}, 0, 0, Undef},
- }, {
- [Speed_control] = { "speed", 0, {0}, 0, 44100, Undef},
- [Mute_control] = { "mute", 0, {0}, 0, 0, Undef},
- [Volume_control] = { "volume", 0, {0}, 0, 0, Undef},
- [Bass_control] = { "bass", 0, {0}, 0, 0, Undef},
- [Mid_control] = { "mid", 0, {0}, 0, 0, Undef},
- [Treble_control] = { "treble", 0, {0}, 0, 0, Undef},
- [Equalizer_control] = { "equalizer", 0, {0}, 0, 0, Undef},
- [Agc_control] = { "agc", 0, {0}, 0, 0, Undef},
- [Delay_control] = { "delay", 0, {0}, 0, 0, Undef},
- [Bassboost_control] = { "bassboost", 0, {0}, 0, 0, Undef},
- [Loudness_control] = { "loudness", 0, {0}, 0, 0, Undef},
- [Channel_control] = { "channels", 0, {0}, 0, 2, Undef},
- [Resolution_control] = { "resolution", 0, {0}, 0, 16, Undef},
-// [Selector_control] = { "selector", 0, {0}, 0, 0, Undef},
- }
-};
-
-int
-setaudioalt(int rec, Audiocontrol *c, int control)
-{
- dprint(2, "setcontrol %s: Set alt %d\n", c->name, control);
- curalt[rec] = control;
- if(usbcmd(ad, Rh2d|Rstd|Riface, Rsetiface, control, interface[rec], nil, 0) < 0){
- dprint(2, "setcontrol: setupcmd %s failed\n", c->name);
- return -1;
- }
- return control;
-}
-
-int
-findalt(int rec, int nchan, int res, int speed)
-{
- Ep *ep;
- Audioalt *a;
- Altc *da;
- int i, j, k, retval;
-
- retval = -1;
- controls[rec][Channel_control].min = 1000000;
- controls[rec][Channel_control].max = 0;
- controls[rec][Channel_control].step = Undef;
- controls[rec][Resolution_control].min = 1000000;
- controls[rec][Resolution_control].max = 0;
- controls[rec][Resolution_control].step = Undef;
- for(i = 0; i < nelem(ad->usb->ep); i++){
- if((ep = ad->usb->ep[i]) == nil)
- continue;
- if(ep->iface == nil){
- fprint(2, "\tno interface\n");
- return 0;
- }
- if(ep->iface->csp != CSP(Claudio, 2, 0))
- continue;
- if((rec == Play && (ep->addr & 0x80))
- || (rec == Record && (ep->addr & 0x80) == 0))
- continue;
- for(j = 0; j < 16; j++){
- if((da = ep->iface->altc[j]) == nil || (a = da->aux) == nil)
- continue;
- if(a->nchan < controls[rec][Channel_control].min)
- controls[rec][Channel_control].min = a->nchan;
- if(a->nchan > controls[rec][Channel_control].max)
- controls[rec][Channel_control].max = a->nchan;
- if(a->res < controls[rec][Resolution_control].min)
- controls[rec][Resolution_control].min = a->res;
- if(a->res > controls[rec][Resolution_control].max)
- controls[rec][Resolution_control].max = a->res;
- controls[rec][Channel_control].settable = 1;
- controls[rec][Channel_control].readable = 1;
- controls[rec][Resolution_control].settable = 1;
- controls[rec][Resolution_control].readable = 1;
- controls[rec][Speed_control].settable = 1;
- controls[rec][Speed_control].readable = 1;
- if(a->nchan == nchan && a->res == res){
- if(speed == Undef)
- retval = j;
- else if(a->caps & (has_discfreq|onefreq)){
- for(k = 0; k < nelem(a->freqs); k++){
- if(a->freqs[k] == speed){
- retval = j;
- break;
- }
- }
- }else{
- if(speed >= a->minfreq && speed <= a->maxfreq)
- retval = j;
- }
- }
- }
- }
- if(usbdebug && retval < 0)
- fprint(2, "findalt(%d, %d, %d, %d) failed\n", rec, nchan, res, speed);
- return retval;
-}
-
-int
-setspeed(int rec, int speed)
-{
- int n, no, dist, i;
- Audioalt *a;
- Altc *da;
- Ep *ep;
- uchar buf[3];
-
- if(rec == Record && !setrec)
- return Undef;
- if(curalt[rec] < 0){
- fprint(2, "Must set channels and resolution before speed\n");
- return Undef;
- }
- if(endpt[rec] < 0)
- sysfatal("endpt[%s] not set", rec?"Record":"Playback");
- ep = ad->usb->ep[endpt[rec]];
- if(ep->iface == nil)
- sysfatal("no interface");
- if(curalt[rec] < 0)
- sysfatal("curalt[%s] not set", rec?"Record":"Playback");
- da = ep->iface->altc[curalt[rec]];
- a = da->aux;
- if(a->caps & onefreq){
- dprint(2, "setspeed %d: onefreq\n", speed);
- /* speed not settable, but packet size must still be set */
- speed = a->freqs[0];
- }else if(a->caps & has_contfreq){
- dprint(2, "setspeed %d: contfreq\n", speed);
- if(speed < a->minfreq)
- speed = a->minfreq;
- else if(speed > a->maxfreq)
- speed = a->maxfreq;
- dprint(2, "Setting continuously variable %s speed to %d\n",
- rec?"record":"playback", speed);
- }else if(a->caps & has_discfreq){
- dprint(2, "setspeed %d: discfreq\n", speed);
- dist = 1000000;
- no = -1;
- for(i = 0; a->freqs[i] > 0; i++)
- if(abs(a->freqs[i] - speed) < dist){
- dist = abs(a->freqs[i] - speed);
- no = i;
- }
- if(no == -1){
- dprint(2, "no = -1\n");
- return Undef;
- }
- speed = a->freqs[no];
- dprint(2, "Setting discreetly variable %s speed to %d\n",
- rec?"record":"playback", speed);
- }else{
- dprint(2, "can't happen\n?");
- return Undef;
- }
- if(a->caps & has_setspeed){
- dprint(2, "Setting %s speed to %d Hz;", rec?"record":"playback", speed);
- buf[0] = speed;
- buf[1] = speed >> 8;
- buf[2] = speed >> 16;
- n = endpt[rec];
- if(rec)
- n |= 0x80;
- if(usbcmd(ad, Rh2d|Rclass|Rep, Rsetcur, sampling_freq_control<<8, n, buf, 3) < 0){
- fprint(2, "Error in setupcmd\n");
- return Undef;
- }
- if((n=usbcmd(ad, Rd2h|Rclass|Rep, Rgetcur, sampling_freq_control<<8, n, buf, 3)) < 0){
- fprint(2, "Error in setupreq\n");
- return Undef;
- }
- if(n != 3)
- fprint(2, "Error in setupreply: %d\n", n);
- else{
- n = buf[0] | buf[1] << 8 | buf[2] << 16;
- if(buf[2] || n == 0){
- dprint(2, "Speed out of bounds %d (0x%x)\n", n, n);
- }else if(n != speed && ad->usb->vid == 0x077d &&
- (ad->usb->did == 0x0223 || ad->usb->did == 0x07af)){
- /* Griffin iMic responds incorrectly to sample rate inquiry */
- dprint(2, " reported as %d (iMic bug?);", n);
- }else
- speed = n;
- }
- dprint(2, " speed now %d Hz;", speed);
- }
- dprint(2, "Configuring %s endpoint for %d Hz\n",
- rec?"record":"playback", speed);
- epdev[rec] = openep(ad, endpt[rec]);
- if(epdev[rec] == nil)
- sysfatal("openep rec %d: %r", rec);
-
- devctl(epdev[rec], "pollival %d", da->interval);
- devctl(epdev[rec], "samplesz %ld", controls[rec][Channel_control].value[0] *
- controls[rec][Resolution_control].value[0]/8);
- devctl(epdev[rec], "hz %d", speed);
-
- /* NO: the client uses the endpoint file directly
- if(opendevdata(epdev[rec], rec ? OREAD : OWRITE) < 0)
- sysfatal("openep rec %d: %r", rec);
- */
- return speed;
-}
-
-long
-getspeed(int rec, int which)
-{
- int i, n;
- Audioalt *a;
- Altc *da;
- Ep *ep;
- uchar buf[3];
- int r;
-
- if(curalt[rec] < 0){
- fprint(2, "Must set channels and resolution before getspeed\n");
- return Undef;
- }
- if(endpt[rec] < 0)
- sysfatal("endpt[%s] not set", rec?"Record":"Playback");
- dprint(2, "getspeed: endpt[%d] == %d\n", rec, endpt[rec]);
- ep = ad->usb->ep[endpt[rec]];
- if(ep->iface == nil)
- sysfatal("no interface");
- if(curalt[rec] < 0)
- sysfatal("curalt[%s] not set", rec?"Record":"Playback");
- da = ep->iface->altc[curalt[rec]];
- a = da->aux;
- if(a->caps & onefreq){
- dprint(2, "getspeed: onefreq\n");
- if(which == Rgetres)
- return Undef;
- return a->freqs[0]; /* speed not settable */
- }
- if(a->caps & has_setspeed){
- dprint(2, "getspeed: has_setspeed, ask\n");
- n = endpt[rec];
- if(rec)
- n |= 0x80;
- r = Rd2h|Rclass|Rep;
- if(usbcmd(ad,r,which,sampling_freq_control<<8, n, buf, 3) < 0)
- return Undef;
- if(n == 3){
- if(buf[2]){
- dprint(2, "Speed out of bounds\n");
- if((a->caps & has_discfreq) && (buf[0] | buf[1] << 8) < 8)
- return a->freqs[buf[0] | buf[1] << 8];
- }
- return buf[0] | buf[1] << 8 | buf[2] << 16;
- }
- dprint(2, "getspeed: n = %d\n", n);
- }
- if(a->caps & has_contfreq){
- dprint(2, "getspeed: has_contfreq\n");
- if(which == Rgetcur)
- return controls[rec][Speed_control].value[0];
- if(which == Rgetmin)
- return a->minfreq;
- if(which == Rgetmax)
- return a->maxfreq;
- if(which == Rgetres)
- return 1;
- }
- if(a->caps & has_discfreq){
- dprint(2, "getspeed: has_discfreq\n");
- if(which == Rgetcur)
- return controls[rec][Speed_control].value[0];
- if(which == Rgetmin)
- return a->freqs[0];
- for(i = 0; i < 8 && a->freqs[i] > 0; i++)
- ;
- if(which == Rgetmax)
- return a->freqs[i-1];
- if(which == Rgetres)
- return Undef;
- }
- dprint(2, "can't happen\n?");
- return Undef;
-}
-
-int
-setcontrol(int rec, char *name, long *value)
-{
- int i, ctl, m;
- byte buf[3];
- int type, req, control, index, count;
- Audiocontrol *c;
-
- c = nil;
- for(ctl = 0; ctl < Ncontrol; ctl++){
- c = &controls[rec][ctl];
- if(strcmp(name, c->name) == 0)
- break;
- }
- if(ctl == Ncontrol){
- dprint(2, "setcontrol: control not found\n");
- return -1;
- }
- if(c->settable == 0){
- dprint(2, "setcontrol: control %d.%d not settable\n", rec, ctl);
- if(c->chans){
- for(i = 0; i < 8; i++)
- if((c->chans & 1 << i) && c->value[i] != value[i])
- return -1;
- return 0;
- }
- if(c->value[0] != value[0])
- return -1;
- return 0;
- }
- if(c->chans){
- value[0] = 0; // set to average
- m = 0;
- for(i = 1; i < 8; i++)
- if(c->chans & 1 << i){
- if(c->min != Undef && value[i] < c->min)
- value[i] = c->min;
- if(c->max != Undef && value[i] > c->max)
- value[i] = c->max;
- value[0] += value[i];
- m++;
- }else
- value[i] = Undef;
- if(m) value[0] /= m;
- }else{
- if(c->min != Undef && value[0] < c->min)
- value[0] = c->min;
- if(c->max != Undef && value[0] > c->max)
- value[0] = c->max;
- }
- req = Rsetcur;
- count = 1;
- switch(ctl){
- default:
- dprint(2, "setcontrol: can't happen\n");
- return -1;
- case Speed_control:
- if((rec != Record || setrec) && (value[0] = setspeed(rec, value[0])) < 0)
- return -1;
- c->value[0] = value[0];
- return 0;
- case Equalizer_control:
- /* not implemented */
- return -1;
- case Resolution_control:
- control = findalt(rec, controls[rec][Channel_control].value[0], value[0], defaultspeed[rec]);
- if(control < 0 || setaudioalt(rec, c, control) < 0){
- dprint(2, "setcontrol: can't find setting for %s\n", c->name);
- return -1;
- }
- c->value[0] = value[0];
- controls[rec][Speed_control].value[0] = defaultspeed[rec];
- return 0;
- case Volume_control:
- case Delay_control:
- count = 2;
- /* fall through */
- case Mute_control:
- case Bass_control:
- case Mid_control:
- case Treble_control:
- case Agc_control:
- case Bassboost_control:
- case Loudness_control:
- type = Rh2d|Rclass|Riface;
- control = ctl<<8;
- index = featureid[rec]<<8;
- break;
- case Selector_control:
- type = Rh2d|Rclass|Riface;
- control = 0;
- index = selectorid[rec]<<8;
- break;
- case Channel_control:
- control = findalt(rec, value[0], controls[rec][Resolution_control].value[0], defaultspeed[rec]);
- if(control < 0 || setaudioalt(rec, c, control) < 0){
- dprint(2, "setcontrol: can't find setting for %s\n", c->name);
- return -1;
- }
- c->value[0] = value[0];
- controls[rec][Speed_control].value[0] = defaultspeed[rec];
- return 0;
- }
- if(c->chans){
- for(i = 1; i < 8; i++)
- if(c->chans & 1 << i){
- switch(count){
- case 2:
- buf[1] = value[i] >> 8;
- case 1:
- buf[0] = value[i];
- }
- if(usbcmd(ad, type, req, control | i, index, buf, count) < 0){
- dprint(2, "setcontrol: setupcmd %s failed\n",
- controls[rec][ctl].name);
- return -1;
- }
- c->value[i] = value[i];
- }
- }else{
- switch(count){
- case 2:
- buf[1] = value[0] >> 8;
- case 1:
- buf[0] = value[0];
- }
- if(usbcmd(ad, type, req, control, index, buf, count) < 0){
- dprint(2, "setcontrol: setupcmd %s failed\n", c->name);
- return -1;
- }
- }
- c->value[0] = value[0];
- return 0;
-}
-
-int
-getspecialcontrol(int rec, int ctl, int req, long *value)
-{
- byte buf[3];
- int m, n, i;
- int type, control, index, count, signedbyte;
- short svalue;
-
- count = 1;
- signedbyte = 0;
- switch(ctl){
- default:
- return Undef;
- case Speed_control:
- value[0] = getspeed(rec, req);
- return 0;
- case Channel_control:
- case Resolution_control:
- if(req == Rgetmin)
- value[0] = controls[rec][ctl].min;
- if(req == Rgetmax)
- value[0] = controls[rec][ctl].max;
- if(req == Rgetres)
- value[0] = controls[rec][ctl].step;
- if(req == Rgetcur)
- value[0] = controls[rec][ctl].value[0];
- return 0;
- case Volume_control:
- case Delay_control:
- count = 2;
- /* fall through */
- case Bass_control:
- case Mid_control:
- case Treble_control:
- case Equalizer_control:
- signedbyte = 1;
- type = Rd2h|Rclass|Riface;
- control = ctl<<8;
- index = featureid[rec]<<8;
- break;
- case Selector_control:
- type = Rd2h|Rclass|Riface;
- control = 0;
- index = selectorid[rec]<<8;
- break;
- case Mute_control:
- case Agc_control:
- case Bassboost_control:
- case Loudness_control:
- if(req != Rgetcur)
- return Undef;
- type = Rd2h|Rclass|Riface;
- control = ctl<<8;
- index = featureid[rec]<<8;
- break;
- }
- if(controls[rec][ctl].chans){
- m = 0;
- value[0] = 0; // set to average
- for(i = 1; i < 8; i++){
- value[i] = Undef;
- if(controls[rec][ctl].chans & 1 << i){
- n=usbcmd(ad, type,req, control|i,index,buf,count);
- if(n < 0)
- return Undef;
- if(n != count)
- return -1;
- switch (count){
- case 2:
- svalue = buf[1] << 8 | buf[0];
- if(req == Rgetcur){
- value[i] = svalue;
- value[0] += svalue;
- m++;
- }else
- value[0] = svalue;
- break;
- case 1:
- svalue = buf[0];
- if(signedbyte && (svalue&0x80))
- svalue |= 0xFF00;
- if(req == Rgetcur){
- value[i] = svalue;
- value[0] += svalue;
- m++;
- }else
- value[0] = svalue;
- }
- }
- }
- if(m) value[0] /= m;
- return 0;
- }
- value[0] = Undef;
- if(usbcmd(ad, type, req, control, index, buf, count) != count)
- return -1;
- switch (count){
- case 2:
- svalue = buf[1] << 8 | buf[0];
- value[0] = svalue;
- break;
- case 1:
- svalue = buf[0];
- if(signedbyte && (svalue&0x80))
- svalue |= 0xFF00;
- value[0] = svalue;
- }
- return 0;
-}
-
-int
-getcontrol(int rec, char *name, long *value)
-{
- int i;
-
- for(i = 0; i < Ncontrol; i++){
- if(strcmp(name, controls[rec][i].name) == 0)
- break;
- }
- if(i == Ncontrol)
- return -1;
- if(controls[rec][i].readable == 0)
- return -1;
- if(getspecialcontrol(rec, i, Rgetcur, value) < 0)
- return -1;
- memmove(controls[rec][i].value, value, sizeof controls[rec][i].value);
- return 0;
-}
-
-void
-getcontrols(void)
-{
- int rec, ctl, i;
- Audiocontrol *c;
- long v[8];
-
- for(rec = 0; rec < 2; rec++){
- if(rec == Record && !setrec)
- continue;
- for(ctl = 0; ctl < Ncontrol; ctl++){
- c = &controls[rec][ctl];
- if(c->readable){
- if(verbose)
- fprint(2, "%s %s control",
- rec?"Record":"Playback", controls[rec][ctl].name);
- c->min = (getspecialcontrol(rec, ctl, Rgetmin, v) < 0) ? Undef : v[0];
- if(verbose && c->min != Undef)
- fprint(2, ", min %ld", c->min);
- c->max = (getspecialcontrol(rec, ctl, Rgetmax, v) < 0) ? Undef : v[0];
- if(verbose && c->max != Undef)
- fprint(2, ", max %ld", c->max);
- c->step = (getspecialcontrol(rec, ctl, Rgetres, v) < 0) ? Undef : v[0];
- if(verbose && c->step != Undef)
- fprint(2, ", step %ld", c->step);
- if(getspecialcontrol(rec, ctl, Rgetcur, c->value) == 0){
- if(verbose){
- if(c->chans){
- fprint(2, ", values");
- for(i = 1; i < 8; i++)
- if(c->chans & 1 << i)
- fprint(2, "[%d] %ld ", i, c->value[i]);
- }else
- fprint(2, ", value %ld", c->value[0]);
- }
- }
- if(verbose)
- fprint(2, "\n");
- }else{
- c->min = Undef;
- c->max = Undef;
- c->step = Undef;
- c->value[0] = Undef;
- dprint(2, "%s %s control not settable\n",
- rec?"Playback":"Record", controls[rec][ctl].name);
- }
- }
- }
-}
-
-int
-ctlparse(char *s, Audiocontrol *c, long *v)
-{
- int i, j, nf, m;
- char *vals[9];
- char *p;
- long val;
-
- nf = tokenize(s, vals, nelem(vals));
- if(nf <= 0)
- return -1;
- if(c->chans){
- j = 0;
- m = 0;
- SET(val);
- v[0] = 0; // will compute average of v[i]
- for(i = 1; i < 8; i++)
- if(c->chans & 1 << i){
- if(j < nf){
- val = strtol(vals[j], &p, 0);
- if(val == 0 && *p != '\0' && *p != '%')
- return -1;
- if(*p == '%' && c->min != Undef)
- val = (val*c->max + (100-val)*c->min)/100;
- j++;
- }
- v[i] = val;
- v[0] += val;
- m++;
- }else
- v[i] = Undef;
- if(m) v[0] /= m;
- }else{
- val = strtol(vals[0], &p, 0);
- if(*p == '%' && c->min != Undef)
- val = (val*c->max + (100-val)*c->min)/100;
- v[0] = val;
- }
- return 0;
-}
-
-int
-Aconv(Fmt *fp)
-{
- char str[256];
- Audiocontrol *c;
- int fst, i;
- char *p;
-
- c = va_arg(fp->args, Audiocontrol*);
- p = str;
- if(c->chans){
- fst = 1;
- for(i = 1; i < 8; i++)
- if(c->chans & 1 << i){
- p = seprint(p, str+sizeof str, "%s%ld", fst?"'":" ", c->value[i]);
- fst = 0;
- }
- seprint(p, str+sizeof str, "'");
- }else
- seprint(p, str+sizeof str, "%ld", c->value[0]);
- return fmtstrcpy(fp, str);
-}
diff --git a/sys/src/cmd/usb/audio/audioctl.h b/sys/src/cmd/usb/audio/audioctl.h
deleted file mode 100644
index 82f88a5d1..000000000
--- a/sys/src/cmd/usb/audio/audioctl.h
+++ /dev/null
@@ -1,29 +0,0 @@
-enum{
- Undef = 0x80000000,
- Play = 0,
- Record = 1,
-};
-
-typedef struct Audiocontrol Audiocontrol;
-
-struct Audiocontrol {
- char *name;
- uchar readable;
- uchar settable;
- uchar chans; /* 0 is master, non-zero is bitmap */
- long value[8]; /* 0 is master; value[0] == Undef -> all values Undef */
- long min, max, step;
-};
-
-extern Audiocontrol controls[2][Ncontrol];
-extern int endpt[2];
-extern int interface[2];
-extern int featureid[2];
-extern int selectorid[2];
-extern int mixerid[2];
-extern int buttonendpt;
-
-int ctlparse(char *s, Audiocontrol *c, long *v);
-void ctlevent(void);
-
-#pragma varargck type "A" Audiocontrol*
diff --git a/sys/src/cmd/usb/audio/audiofs.c b/sys/src/cmd/usb/audio/audiofs.c
deleted file mode 100644
index d7a7bafd7..000000000
--- a/sys/src/cmd/usb/audio/audiofs.c
+++ /dev/null
@@ -1,939 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include <auth.h>
-#include <fcall.h>
-#include <libsec.h>
-#include "usb.h"
-#include "audio.h"
-#include "audioctl.h"
-
-int attachok;
-
-#define STACKSIZE 16*1024
-
-enum
-{
- OPERM = 0x3, /* mask of all permission types in open mode */
-};
-
-typedef struct Fid Fid;
-typedef struct Audioctldata Audioctldata;
-typedef struct Worker Worker;
-
-struct Audioctldata
-{
- long offoff; /* offset of the offset for audioctl */
- long values[2][Ncontrol][8]; /* last values transmitted */
- char *s;
- int ns;
-};
-
-enum {
- Busy = 0x01,
- Open = 0x02,
- Eof = 0x04,
-};
-
-struct Fid
-{
- QLock;
- int fid;
- Dir *dir;
- ushort flags;
- short readers;
- void *fiddata; /* file specific per-fid data (used for audioctl) */
- Fid *next;
-};
-
-struct Worker
-{
- Fid *fid;
- ushort tag;
- Fcall *rhdr;
- Dir *dir;
- Channel *eventc;
- Worker *next;
-};
-
-enum {
- /* Event channel messages for worker */
- Work = 0x01,
- Check = 0x02,
- Flush = 0x03,
-};
-
-enum {
- Qdir,
- Qvolume,
- Qaudioctl,
- Qaudiostat,
- Nqid,
-};
-
-Dir dirs[] = {
-[Qdir] = {0,0,{Qdir, 0,QTDIR},0555|DMDIR,0,0,0, ".", nil,nil,nil},
-[Qvolume] = {0,0,{Qvolume, 0,QTFILE},0666,0,0,0, "volume", nil,nil,nil},
-[Qaudioctl] = {0,0,{Qaudioctl, 0,QTFILE},0666,0,0,0, "audioctl",nil,nil,nil},
-[Qaudiostat] = {0,0,{Qaudiostat,0,QTFILE},0666,0,0,0, "audiostat",nil,nil,nil},
-};
-
-int messagesize = 4*1024+IOHDRSZ;
-uchar mdata[8*1024+IOHDRSZ];
-uchar mbuf[8*1024+IOHDRSZ];
-
-Fcall thdr;
-Fcall rhdr;
-Worker *workers;
-
-char srvfile[64], mntdir[64], epdata[64], audiofile[64];
-int mfd[2], p[2];
-char user[32];
-char *srvpost;
-
-Channel *procchan;
-Channel *replchan;
-
-Fid *fids;
-
-Fid* newfid(int);
-void io(void *);
-void usage(void);
-
-extern char *mntpt;
-
-char *rflush(Fid*), *rauth(Fid*),
- *rattach(Fid*), *rwalk(Fid*),
- *ropen(Fid*), *rcreate(Fid*),
- *rread(Fid*), *rwrite(Fid*), *rclunk(Fid*),
- *rremove(Fid*), *rstat(Fid*), *rwstat(Fid*),
- *rversion(Fid*);
-
-char *(*fcalls[])(Fid*) = {
- [Tflush] rflush,
- [Tversion] rversion,
- [Tauth] rauth,
- [Tattach] rattach,
- [Twalk] rwalk,
- [Topen] ropen,
- [Tcreate] rcreate,
- [Tread] rread,
- [Twrite] rwrite,
- [Tclunk] rclunk,
- [Tremove] rremove,
- [Tstat] rstat,
- [Twstat] rwstat,
-};
-
-char Eperm[] = "permission denied";
-char Enotdir[] = "not a directory";
-char Enoauth[] = "no authentication in ramfs";
-char Enotexist[] = "file does not exist";
-char Einuse[] = "file in use";
-char Eexist[] = "file exists";
-char Enotowner[] = "not owner";
-char Eisopen[] = "file already open for I/O";
-char Excl[] = "exclusive use file already open";
-char Ename[] = "illegal name";
-char Ebadctl[] = "unknown control message";
-
-int
-notifyf(void *, char *s)
-{
- if(strncmp(s, "interrupt", 9) == 0)
- return 1;
- return 0;
-}
-
-void
-post(char *name, char *envname, int srvfd)
-{
- int fd;
- char buf[32];
-
- fd = create(name, OWRITE, attachok?0666:0600);
- if(fd < 0)
- return;
- snprint(buf, sizeof buf, "%d", srvfd);
- if(write(fd, buf, strlen(buf)) != strlen(buf))
- sysfatal("srv write");
- close(fd);
- putenv(envname, name);
-}
-
-/*
- * BUG: If audio is later used on a different name space, the
- * audio/audioin files are not there because of the bind trick.
- * We should actually implement those files despite the binds.
- * If audio is used from within the same ns nothing would change,
- * otherwise, whoever would mount the audio files could still
- * play/record audio (unlike now).
- */
-void
-serve(void *)
-{
- int i;
- ulong t;
-
- if(pipe(p) < 0)
- sysfatal("pipe failed");
- mfd[0] = p[0];
- mfd[1] = p[0];
-
- atnotify(notifyf, 1);
- strcpy(user, getuser());
- t = time(nil);
- for(i = 0; i < Nqid; i++){
- dirs[i].uid = user;
- dirs[i].gid = user;
- dirs[i].muid = user;
- dirs[i].atime = t;
- dirs[i].mtime = t;
- }
- if(mntpt == nil){
- snprint(mntdir, sizeof(mntdir), "/dev");
- mntpt = mntdir;
- }
-
- if(usbdebug)
- fmtinstall('F', fcallfmt);
-
- procrfork(io, nil, STACKSIZE, RFFDG|RFNAMEG);
-
- close(p[0]); /* don't deadlock if child fails */
- if(srvpost){
- snprint(srvfile, sizeof srvfile, "/srv/%s", srvpost);
- remove(srvfile);
- post(srvfile, "usbaudio", p[1]);
- }
- if(mount(p[1], -1, mntpt, MBEFORE, "") < 0)
- sysfatal("mount failed");
- if(endpt[Play] >= 0 && devctl(epdev[Play], "name audio") < 0)
- fprint(2, "audio: name audio: %r\n");
- if(endpt[Record] >= 0 && devctl(epdev[Record], "name audioin") < 0)
- fprint(2, "audio: name audioin: %r\n");
- threadexits(nil);
-}
-
-char*
-rversion(Fid*)
-{
- Fid *f;
-
- if(thdr.msize < 256)
- return "max messagesize too small";
- if(thdr.msize < messagesize)
- messagesize = thdr.msize;
- rhdr.msize = messagesize;
- if(strncmp(thdr.version, "9P2000", 6) != 0)
- return "unknown 9P version";
- else
- rhdr.version = "9P2000";
- for(f = fids; f; f = f->next)
- if(f->flags & Busy)
- rclunk(f);
- return nil;
-}
-
-char*
-rauth(Fid*)
-{
- return "usbaudio: no authentication required";
-}
-
-char*
-rflush(Fid *)
-{
- Worker *w;
- int waitflush;
-
- do {
- waitflush = 0;
- for(w = workers; w; w = w->next)
- if(w->tag == thdr.oldtag){
- waitflush++;
- nbsendul(w->eventc, thdr.oldtag << 16 | Flush);
- }
- if(waitflush)
- sleep(50);
- } while(waitflush);
- dprint(2, "flush done on tag %d\n", thdr.oldtag);
- return 0;
-}
-
-char*
-rattach(Fid *f)
-{
- f->flags |= Busy;
- f->dir = &dirs[Qdir];
- rhdr.qid = f->dir->qid;
- if(attachok == 0 && strcmp(thdr.uname, user) != 0)
- return Eperm;
- return 0;
-}
-
-static Fid*
-doclone(Fid *f, int nfid)
-{
- Fid *nf;
-
- nf = newfid(nfid);
- if(nf->flags & Busy)
- return nil;
- nf->flags |= Busy;
- nf->flags &= ~Open;
- nf->dir = f->dir;
- return nf;
-}
-
-char*
-dowalk(Fid *f, char *name)
-{
- int t;
-
- if(strcmp(name, ".") == 0)
- return nil;
- if(strcmp(name, "..") == 0){
- f->dir = &dirs[Qdir];
- return nil;
- }
- if(f->dir != &dirs[Qdir])
- return Enotexist;
- for(t = 1; t < Nqid; t++){
- if(strcmp(name, dirs[t].name) == 0){
- f->dir = &dirs[t];
- return nil;
- }
- }
- return Enotexist;
-}
-
-char*
-rwalk(Fid *f)
-{
- Fid *nf;
- char *rv;
- int i;
- Dir *savedir;
-
- if(f->flags & Open)
- return Eisopen;
-
- rhdr.nwqid = 0;
- nf = nil;
- savedir = f->dir;
- /* clone if requested */
- if(thdr.newfid != thdr.fid){
- nf = doclone(f, thdr.newfid);
- if(nf == nil)
- return "new fid in use";
- f = nf;
- }
-
- /* if it's just a clone, return */
- if(thdr.nwname == 0 && nf != nil)
- return nil;
-
- /* walk each element */
- rv = nil;
- for(i = 0; i < thdr.nwname; i++){
- rv = dowalk(f, thdr.wname[i]);
- if(rv != nil){
- if(nf != nil)
- rclunk(nf);
- else
- f->dir = savedir;
- break;
- }
- rhdr.wqid[i] = f->dir->qid;
- }
- rhdr.nwqid = i;
-
- /* we only error out if no walk */
- if(i > 0)
- rv = nil;
-
- return rv;
-}
-
-Audioctldata *
-allocaudioctldata(void)
-{
- int i, j, k;
- Audioctldata *a;
-
- a = emallocz(sizeof(Audioctldata), 1);
- for(i = 0; i < 2; i++)
- for(j=0; j < Ncontrol; j++)
- for(k=0; k < 8; k++)
- a->values[i][j][k] = Undef;
- return a;
-}
-
-char *
-ropen(Fid *f)
-{
- if(f->flags & Open)
- return Eisopen;
-
- if(thdr.mode != OREAD && (f->dir->mode & 0x2) == 0)
- return Eperm;
- qlock(f);
- if(f->dir == &dirs[Qaudioctl] && f->fiddata == nil)
- f->fiddata = allocaudioctldata();
- qunlock(f);
- rhdr.iounit = 0;
- rhdr.qid = f->dir->qid;
- f->flags |= Open;
- return nil;
-}
-
-char *
-rcreate(Fid*)
-{
- return Eperm;
-}
-
-int
-readtopdir(Fid*, uchar *buf, long off, int cnt, int blen)
-{
- int i, m, n;
- long pos;
-
- n = 0;
- pos = 0;
- for(i = 1; i < Nqid; i++){
- m = convD2M(&dirs[i], &buf[n], blen-n);
- if(off <= pos){
- if(m <= BIT16SZ || m > cnt)
- break;
- n += m;
- cnt -= m;
- }
- pos += m;
- }
- return n;
-}
-
-enum { Chunk = 1024, };
-
-int
-makeaudioctldata(Fid *f)
-{
- int rec, ctl, i, diff;
- long *actls; /* 8 of them */
- char *p, *e;
- Audiocontrol *c;
- Audioctldata *a;
-
- if((a = f->fiddata) == nil)
- sysfatal("fiddata");
- if((p = a->s) == nil)
- a->s = p = emallocz(Chunk, 0);
- e = p + Chunk - 1; /* e must point *at* last byte, not *after* */
- for(rec = 0; rec < 2; rec++)
- for(ctl = 0; ctl < Ncontrol; ctl++){
- c = &controls[rec][ctl];
- actls = a->values[rec][ctl];
- diff = 0;
- if(c->chans){
- for(i = 1; i < 8; i++)
- if((c->chans & 1<<i) &&
- c->value[i] != actls[i])
- diff = 1;
- }else
- if(c->value[0] != actls[0])
- diff = 1;
- if(diff){
- p = seprint(p, e, "%s %s %A", c->name,
- rec? "in": "out", c);
- memmove(actls, c->value, sizeof c->value);
- if(c->min != Undef){
- p = seprint(p, e, " %ld %ld", c->min,
- c->max);
- if(c->step != Undef)
- p = seprint(p, e, " %ld",
- c->step);
- }
- p = seprint(p, e, "\n");
- }
- }
- assert(strlen(a->s) < Chunk);
- a->ns = p - a->s;
- return a->ns;
-}
-
-void
-readproc(void *x)
-{
- int n, cnt;
- ulong event;
- vlong off;
- uchar *mdata;
- Audioctldata *a;
- Fcall *rhdr;
- Fid *f;
- Worker *w;
-
- w = x;
- mdata = emallocz(8*1024+IOHDRSZ, 0);
- while(event = recvul(w->eventc)){
- if(event != Work)
- continue;
- f = w->fid;
- rhdr = w->rhdr;
- a = f->fiddata;
- off = rhdr->offset;
- cnt = rhdr->count;
- assert(a->offoff == off);
- /* f is already locked */
- for(;;){
- qunlock(f);
- event = recvul(w->eventc);
- qlock(f);
- ddprint(2, "readproc unblocked fid %d %lld\n",
- f->fid, f->dir->qid.path);
- switch (event & 0xffff){
- case Work:
- sysfatal("readproc phase error");
- case Check:
- if(f->fiddata && makeaudioctldata(f) == 0)
- continue;
- break;
- case Flush:
- if((event >> 16) == rhdr->tag){
- ddprint(2, "readproc flushing fid %d, tag %d\n",
- f->fid, rhdr->tag);
- goto flush;
- }
- continue;
- }
- if(f->fiddata){
- rhdr->data = a->s;
- rhdr->count = a->ns;
- break;
- }
- yield();
- }
- if(rhdr->count > cnt)
- rhdr->count = cnt;
- if(rhdr->count)
- f->flags &= ~Eof;
- ddprint(2, "readproc:->%F\n", rhdr);
- n = convS2M(rhdr, mdata, messagesize);
- if(write(mfd[1], mdata, n) != n)
- sysfatal("mount write");
-flush:
- w->tag = NOTAG;
- f->readers--;
- assert(f->readers == 0);
- free(rhdr);
- w->rhdr = nil;
- qunlock(f);
- sendp(procchan, w);
- }
- threadexits(nil);
-}
-
-char*
-rread(Fid *f)
-{
- int i, n, cnt, rec, div;
- vlong off;
- char *p;
- Audiocontrol *c;
- Audioctldata *a;
- Worker *w;
- static char buf[1024];
-
- rhdr.count = 0;
- off = thdr.offset;
- cnt = thdr.count;
-
- if(cnt > messagesize - IOHDRSZ)
- cnt = messagesize - IOHDRSZ;
-
- rhdr.data = (char*)mbuf;
-
- if(f->dir == &dirs[Qdir]){
- n = readtopdir(f, mbuf, off, cnt, messagesize - IOHDRSZ);
- rhdr.count = n;
- return nil;
- }
-
- if(f->dir == &dirs[Qvolume]){
- p = buf;
- n = sizeof buf;
- for(rec = 0; rec < 2; rec++){
- c = &controls[rec][Volume_control];
- if(c->readable){
- div = c->max - c->min;
- i = snprint(p, n, "audio %s %ld\n",
- rec? "in": "out", (c->min != Undef?
- 100*(c->value[0]-c->min)/(div? div: 1):
- c->value[0]));
- p += i;
- n -= i;
- }
- c = &controls[rec][Treble_control];
- if(c->readable){
- div = c->max - c->min;
- i = snprint(p, n, "treb %s %ld\n",
- rec? "in": "out", (c->min != Undef?
- 100*(c->value[0]-c->min)/(div? div: 1):
- c->value[0]));
- p += i;
- n -= i;
- }
- c = &controls[rec][Bass_control];
- if(c->readable){
- div = c->max - c->min;
- i = snprint(p, n, "bass %s %ld\n",
- rec? "in": "out", (c->min != Undef?
- 100*(c->value[0]-c->min)/(div? div: 1):
- c->value[0]));
- p += i;
- n -= i;
- }
- c = &controls[rec][Speed_control];
- if(c->readable){
- i = snprint(p, n, "speed %s %ld\n",
- rec? "in": "out", c->value[0]);
- p += i;
- n -= i;
- }
- }
- n = sizeof buf - n;
- if(off > n)
- rhdr.count = 0;
- else{
- rhdr.data = buf + off;
- rhdr.count = n - off;
- if(rhdr.count > cnt)
- rhdr.count = cnt;
- }
- return nil;
- }
-
- if(f->dir == &dirs[Qaudioctl]){
- Fcall *hdr;
-
- qlock(f);
- a = f->fiddata;
- if(off - a->offoff < 0){
- /* there was a seek */
- a->offoff = off;
- a->ns = 0;
- }
- do {
- if(off - a->offoff < a->ns){
- rhdr.data = a->s + (off - a->offoff);
- rhdr.count = a->ns - (off - a->offoff);
- if(rhdr.count > cnt)
- rhdr.count = cnt;
- qunlock(f);
- return nil;
- }
- if(a->offoff != off){
- a->ns = 0;
- a->offoff = off;
- rhdr.count = 0;
- qunlock(f);
- return nil;
- }
- } while(makeaudioctldata(f) != 0);
-
- assert(a->offoff == off);
- /* Wait for data off line */
- f->readers++;
- w = nbrecvp(procchan);
- if(w == nil){
- w = emallocz(sizeof(Worker), 1);
- w->eventc = chancreate(sizeof(ulong), 1);
- w->next = workers;
- workers = w;
- proccreate(readproc, w, 4096);
- }
- hdr = emallocz(sizeof(Fcall), 0);
- w->fid = f;
- w->tag = thdr.tag;
- assert(w->rhdr == nil);
- w->rhdr = hdr;
- hdr->count = cnt;
- hdr->offset = off;
- hdr->type = thdr.type+1;
- hdr->fid = thdr.fid;
- hdr->tag = thdr.tag;
- sendul(w->eventc, Work);
- return (char*)~0;
- }
-
- return Eperm;
-}
-
-char*
-rwrite(Fid *f)
-{
- long cnt, value;
- char *lines[2*Ncontrol], *fields[4], *subfields[9], *err, *p;
- int nlines, i, nf, nnf, rec, ctl;
- Audiocontrol *c;
- Worker *w;
- static char buf[256];
-
- rhdr.count = 0;
- cnt = thdr.count;
-
- if(cnt > messagesize - IOHDRSZ)
- cnt = messagesize - IOHDRSZ;
-
- err = nil;
- if(f->dir == &dirs[Qvolume] || f->dir == &dirs[Qaudioctl]){
- thdr.data[cnt] = '\0';
- nlines = getfields(thdr.data, lines, 2*Ncontrol, 1, "\n");
- for(i = 0; i < nlines; i++){
- dprint(2, "line: %s\n", lines[i]);
- nf = tokenize(lines[i], fields, 4);
- if(nf == 0)
- continue;
- if(nf == 3)
- if(strcmp(fields[1], "in") == 0 ||
- strcmp(fields[1], "record") == 0)
- rec = 1;
- else if(strcmp(fields[1], "out") == 0 ||
- strcmp(fields[1], "playback") == 0)
- rec = 0;
- else{
- dprint(2, "bad1\n");
- return Ebadctl;
- }
- else if(nf == 2)
- rec = 0;
- else{
- dprint(2, "bad2 %d\n", nf);
- return Ebadctl;
- }
- c = nil;
- if(strcmp(fields[0], "audio") == 0) /* special case */
- fields[0] = "volume";
- for(ctl = 0; ctl < Ncontrol; ctl++){
- c = &controls[rec][ctl];
- if(strcmp(fields[0], c->name) == 0)
- break;
- }
- if(ctl == Ncontrol){
- dprint(2, "bad3\n");
- return Ebadctl;
- }
- if(f->dir == &dirs[Qvolume] && ctl != Speed_control &&
- c->min != Undef && c->max != Undef){
- nnf = tokenize(fields[nf-1], subfields,
- nelem(subfields));
- if(nnf <= 0 || nnf > 8){
- dprint(2, "bad4\n");
- return Ebadctl;
- }
- p = buf;
- for(i = 0; i < nnf; i++){
- value = strtol(subfields[i], nil, 0);
- value = ((100 - value)*c->min +
- value*c->max) / 100;
- if(p == buf){
- dprint(2, "rwrite: %s %s '%ld",
- c->name, rec?
- "record":
- "playback",
- value);
- }else
- dprint(2, " %ld", value);
- if(p == buf)
- p = seprint(p, buf+sizeof buf,
- "0x%p %s %s '%ld",
- replchan, c->name, rec?
- "record": "playback",
- value);
- else
- p = seprint(p, buf+sizeof buf,
- " %ld", value);
- }
- dprint(2, "'\n");
- seprint(p, buf+sizeof buf-1, "'");
- chanprint(controlchan, buf);
- }else{
- dprint(2, "rwrite: %s %s %q", c->name,
- rec? "record": "playback",
- fields[nf-1]);
- chanprint(controlchan, "0x%p %s %s %q",
- replchan, c->name, rec? "record":
- "playback", fields[nf-1]);
- }
- p = recvp(replchan);
- if(p){
- if(strcmp(p, "ok") == 0){
- free(p);
- p = nil;
- }
- if(err == nil)
- err = p;
- }
- }
- for(w = workers; w; w = w->next)
- nbsendul(w->eventc, Qaudioctl << 16 | Check);
- rhdr.count = thdr.count;
- return err;
- }
- return Eperm;
-}
-
-char *
-rclunk(Fid *f)
-{
- Audioctldata *a;
-
- qlock(f);
- f->flags &= ~(Open|Busy);
- assert(f->readers ==0);
- if(f->fiddata){
- a = f->fiddata;
- if(a->s)
- free(a->s);
- free(a);
- f->fiddata = nil;
- }
- qunlock(f);
- return 0;
-}
-
-char *
-rremove(Fid *)
-{
- return Eperm;
-}
-
-char *
-rstat(Fid *f)
-{
- Audioctldata *a;
-
- if(f->dir == &dirs[Qaudioctl]){
- qlock(f);
- if(f->fiddata == nil)
- f->fiddata = allocaudioctldata();
- a = f->fiddata;
- if(a->ns == 0)
- makeaudioctldata(f);
- f->dir->length = a->offoff + a->ns;
- qunlock(f);
- }
- rhdr.nstat = convD2M(f->dir, mbuf, messagesize - IOHDRSZ);
- rhdr.stat = mbuf;
- return 0;
-}
-
-char *
-rwstat(Fid*)
-{
- return Eperm;
-}
-
-Fid *
-newfid(int fid)
-{
- Fid *f, *ff;
-
- ff = nil;
- for(f = fids; f; f = f->next)
- if(f->fid == fid)
- return f;
- else if(ff == nil && (f->flags & Busy) == 0)
- ff = f;
- if(ff == nil){
- ff = emallocz(sizeof *ff, 1);
- ff->next = fids;
- fids = ff;
- }
- ff->fid = fid;
- ff->flags &= ~(Busy|Open);
- ff->dir = nil;
- return ff;
-}
-
-void
-io(void *)
-{
- char *err, e[32];
- int n;
-
- close(p[1]);
-
- procchan = chancreate(sizeof(Channel*), 8);
- replchan = chancreate(sizeof(char*), 0);
- for(;;){
- /*
- * reading from a pipe or a network device
- * will give an error after a few eof reads
- * however, we cannot tell the difference
- * between a zero-length read and an interrupt
- * on the processes writing to us,
- * so we wait for the error
- */
- n = read9pmsg(mfd[0], mdata, messagesize);
- if(n == 0)
- continue;
- if(n < 0){
- rerrstr(e, sizeof e);
- if(strcmp(e, "interrupted") == 0){
- dprint(2, "read9pmsg interrupted\n");
- continue;
- }
- return;
- }
- if(convM2S(mdata, n, &thdr) == 0)
- continue;
-
- ddprint(2, "io:<-%F\n", &thdr);
-
- rhdr.data = (char*)mdata + messagesize;
- if(!fcalls[thdr.type])
- err = "bad fcall type";
- else
- err = (*fcalls[thdr.type])(newfid(thdr.fid));
- if(err == (char*)~0)
- continue; /* handled off line */
- if(err){
- rhdr.type = Rerror;
- rhdr.ename = err;
- }else{
- rhdr.type = thdr.type + 1;
- rhdr.fid = thdr.fid;
- }
- rhdr.tag = thdr.tag;
- ddprint(2, "io:->%F\n", &rhdr);
- n = convS2M(&rhdr, mdata, messagesize);
- if(write(mfd[1], mdata, n) != n)
- sysfatal("mount write");
- }
-}
-
-int
-newid(void)
-{
- int rv;
- static int id;
- static Lock idlock;
-
- lock(&idlock);
- rv = ++id;
- unlock(&idlock);
-
- return rv;
-}
-
-void
-ctlevent(void)
-{
- Worker *w;
-
- for(w = workers; w; w = w->next)
- nbsendul(w->eventc, Qaudioctl << 16 | Check);
-}
diff --git a/sys/src/cmd/usb/audio/audiosub.c b/sys/src/cmd/usb/audio/audiosub.c
deleted file mode 100644
index e4ac917f5..000000000
--- a/sys/src/cmd/usb/audio/audiosub.c
+++ /dev/null
@@ -1,300 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-#include "audio.h"
-#include "audioctl.h"
-
-typedef struct Namelist Namelist;
-
-struct Namelist
-{
- short index;
- char *name;
-};
-
-Namelist terminal_types[] = {
- { 0x100, "USB Terminal, undefined type"},
- { 0x101, "USB Streaming"},
- { 0x201, "Microphone"},
- { 0x301, "Speaker"},
- { 0x603, "Line connector"},
- { 0x605, "S/PDIF"},
- { 0, nil }
-};
-
-units[2][8]; /* rec and play units */
-nunits[2]; /* number in use */
-
-char *
-namefor(Namelist *list, int item)
-{
- while(list->name){
- if(list->index == item)
- return list->name;
- list++;
- }
- return "<unnamed>";
-}
-
-static int
-findunit(int nr)
-{
- int rec, i;
- for(rec = 0; rec < 2; rec++)
- for(i = 0; i < nunits[rec]; i++)
- if(units[rec][i] == nr)
- return rec;
- return -1;
-}
-
-void
-audio_interface(Dev *, Desc *dd)
-{
- byte *b = (uchar*)&dd->data;
- byte *bb = b;
- int nb = dd->data.bLength;
- int ctl, ch, u, x;
- byte *p;
- int class, subclass;
- Audioalt *aa;
- char *hd;
-
- class = Class(dd->iface->csp);
- subclass = Subclass(dd->iface->csp);
-
- dprint(2, "%d.%d: ", class, subclass);
- switch (subclass){
- case 1: // control
- switch (b[2]){
- case 0x01:
- dprint(2, "Class-Specific AC Interface Header Descriptor\n");
- dprint(2, "\tAudioDevClass release (bcd)%c%c%c%c, "
- "TotalLength %d, InCollection %d aInterfaceNr %d\n",
- '0'+((b[4]>>4)&0xf), '0'+(b[4]&0xf),
- '0'+((b[3]>>4)&0xf), '0'+(b[3]&0xf),
- b[5]|(b[6]<<8), b[7], b[8]);
- break;
- case 0x02: // input
- dprint(2, "Audio Input Terminal Descriptor\n");
- dprint(2, "\tbTerminalId %d, wTerminalType "
- "0x%x (%s), bAssocTerminal %d bNrChannels %d, "
- "wChannelConfig %d, iChannelNames %d iTerminal %d\n",
- b[3], b[4]|(b[5]<<8),
- namefor(terminal_types, b[4]|(b[5]<<8)),
- b[6], b[7], b[8]|(b[9]<<8), b[10], b[11]);
- if((b[4]|b[5]<<8) == 0x101){
- if(verbose)
- fprint(2, "Audio output unit %d\n", b[3]);
- /* USB streaming input: play interface */
- units[Play][nunits[Play]++] = b[3];
- }else{
- if(verbose)
- fprint(2, "Dev can record from %s\n",
- namefor(terminal_types, b[4]|(b[5]<<8)));
- /* Non-USB input: record interface */
- units[Record][nunits[Record]++] = b[3];
- }
- break;
- case 0x03: // output
- if(usbdebug){
- fprint(2, "Audio Output Terminal Descriptor\n");
- fprint(2, "\tbTerminalId %d, wTerminalType 0x%x (%s), bAssocTerminal %d bSourceId %d, iTerminal %d\n",
- b[3], b[4]|(b[5]<<8),
- namefor(terminal_types, b[4]|(b[5]<<8)),
- b[6], b[7], b[8]);
- }
- if((b[4]|b[5]<<8) == 0x101){
- if(verbose)
- fprint(2, "Audio input unit %d\n", b[3]);
- /* USB streaming output: record interface */
- units[Record][nunits[Record]++] = b[3];
- if(verbose)
- fprint(2, "Dev can play to %s\n",
- namefor(terminal_types, b[4]|(b[5]<<8)));
- /* Non-USB output: play interface */
- units[Play][nunits[Play]++] = b[3];
- }
- break;
- case 0x04:
- if(verbose)
- fprint(2, "Audio Mixer Unit %d\n", b[3]);
- if(usbdebug){
- fprint(2, "\t%d bytes:", nb);
- for(ctl = 0; ctl < nb; ctl++)
- fprint(2, " 0x%2.2x", b[ctl]);
- fprint(2, "\n\tbUnitId %d, bNrInPins %d", b[3], b[4]);
- }
- if(b[4]){
- dprint(2, ", baSourceIDs: [%d", b[5]);
- u = findunit(b[5]);
- for(ctl = 1; ctl < b[4]; ctl++){
- if(u < 0)
- u = findunit(b[5+ctl]);
- else if((x = findunit(b[5+ctl])) >= 0 && u != x && verbose)
- fprint(2, "\tMixer %d for I & O \n", b[3]);
- dprint(2, ", %d", b[5+ctl]);
- }
- dprint(2, "]\n");
- if(u >= 0){
- units[u][nunits[u]++] = b[3];
- if(mixerid[u] >= 0)
- fprint(2, "Second mixer (%d, %d) on %s\n",
- mixerid[u], b[3], u?"record":"playback");
- mixerid[u] = b[3];
- }
- if(usbdebug){
- fprint(2, "Channels %d, config %d, ",
- b[ctl+5], b[ctl+5+1] | b[ctl+5+2] << 8);
- x = b[ctl+5] * b[4];
- fprint(2, "programmable: %d bits, 0x", x);
- x = (x + 7) >> 3;
- while(x--)
- fprint(2, "%2.2x", b[ctl+x+5+4]);
- }
- }
- break;
- case 0x05:
- if(verbose)
- fprint(2, "Audio Selector Unit %d\n", b[3]);
- dprint(2, "\tbUnitId %d, bNrInPins %d", b[3], b[4]);
- if(b[4]){
- u = findunit(b[5]);
- dprint(2, ", baSourceIDs: %s [%d",
- u?"record":"playback", b[5]);
- for(ctl = 1; ctl < b[4]; ctl++){
- if(u < 0)
- u = findunit(b[5+ctl]);
- else if((x = findunit(b[5+ctl])) >= 0 &&
- u != x && verbose)
- fprint(2, "\tSelector %d for I & O\n", b[3]);
- dprint(2, ", %d", b[5+ctl]);
- }
- dprint(2, "]\n");
- if(u >= 0){
- units[u][nunits[u]++] = b[3];
- if(selectorid[u] >= 0)
- fprint(2, "Second selector (%d, %d) on %s\n", selectorid[u], b[3], u?"record":"playback");
- selectorid[u] = b[3];
- controls[u][Selector_control].readable = 1;
- controls[u][Selector_control].settable = 1;
- controls[u][Selector_control].chans = 0;
- }
- }
- break;
- case 0x06: // feature
- if(verbose) fprint(2, "Audio Feature Unit %d", b[3]);
- dprint(2, "\tbUnitId %d, bSourceId %d, bControlSize %d\n",
- b[3], b[4], b[5]);
- u = findunit(b[4]);
- if(u >= 0){
- if(verbose) fprint(2, " for %s\n", u?"Record":"Playback");
- units[u][nunits[u]++] = b[3];
- if(featureid[u] >= 0)
- if(verbose)
- fprint(2, "Second feature unit (%d, %d)"
- " on %s\n", featureid[u], b[3],
- u?"record":"playback");
- featureid[u] = b[3];
- }else
- if(verbose) fprint(2, ", not known what for\n");
- p = b + 6;
- for(ctl = 1; ctl < 0x0b; ctl++)
- if((1<<(ctl-1)) & (b[6] | ((b[5]>1)?(b[7]<<8):0))){
- if(verbose)
- fprint(2, "\t%s control on master channel\n",
- controls[0][ctl].name);
- if(u >= 0){
- controls[u][ctl].readable = 1;
- controls[u][ctl].settable = 1;
- controls[u][ctl].chans = 0;
- }
- }
- p += (b[5]>1)?2:1;
- for(ch = 0; ch < (nb - 8)/b[5]; ch++){
- for(ctl = 1; ctl < 0x0b; ctl++)
- if((1<<(ctl-1)) & (p[0] | ((b[5]>1)?(p[1]<<8):0))){
- if(verbose)
- fprint(2, "\t%s control on channel %d\n",
- controls[0][ctl].name, ch+1);
- if(u >= 0){
- controls[u][ctl].readable = 1;
- controls[u][ctl].settable = 1;
- controls[u][ctl].chans |= 1 <<(ch+1);
- }
- }
- p += (b[5]>1)?2:1;
- }
- break;
- default:
- hd = hexstr(bb, nb);
- fprint(2, "audio control unknown: %s\n", hd);
- free(hd);
- }
- break;
- case 2: // stream
- switch (b[2]){
- case 0x01:
- dprint(2, "Audio stream for TerminalID %d, delay %d, format_tag %#ux\n",
- b[3], b[4], b[5] | (b[6]<<8));
- break;
- case 0x02:
- aa = (Audioalt *)dd->altc->aux;
- if(aa == nil){
- aa = mallocz(sizeof(Audioalt), 1);
- dd->altc->aux = aa;
- }
- if(verbose){
- if(b[4] <= 2)
- fprint(2, "Interface %d: %s, %d bits, ",
- dd->iface->id, (b[4] == 1)?"mono":"stereo", b[6]);
- else
- fprint(2, "Interface %d, %d channels, %d bits, ",
- dd->iface->id, b[4], b[6]);
- }
- if(b[7] == 0){
- if(verbose)
- fprint(2, "frequency variable between %d and %d\n",
- b[8] | b[9]<<8 | b[10]<<16, b[11] | b[12]<<8 | b[13]<<16);
- aa->minfreq = b[8] | b[9]<<8 | b[10]<<16;
- aa->maxfreq = b[11] | b[12]<<8 | b[13]<<16;
- aa->caps |= has_contfreq;
- }else{
- if(verbose)
- fprint(2, "discrete frequencies are:");
- for(ch = 0; ch < b[7] && ch < 8; ch++){
- aa->freqs[ch] = b[8+3*ch] | b[9+3*ch]<<8 | b[10+3*ch]<<16;
- if(verbose)
- fprint(2, " %d", b[8+3*ch] | b[9+3*ch]<<8 | b[10+3*ch]<<16);
- }
- if(ch < 8)
- aa->freqs[ch] = -1;
- if(verbose)
- fprint(2, "\n");
- if(ch > 1)
- aa->caps |= has_discfreq; /* more than one frequency */
- else
- aa->caps |= onefreq; /* only one frequency */
- }
- aa->nchan = b[4];
- aa->res = b[6];
- aa->subframesize = b[5];
- break;
- default:
- if(usbdebug){
- hd = hexstr(bb, nb);
- fprint(2, "audio stream unknown: %s\n", hd);
- free(hd);
- }
- }
- break;
- case 3: // midi
- default:
- if(usbdebug){
- hd = hexstr(bb, nb);
- fprint(2, "Unknown audio stream type: CS_INTERFACE: %s\n", hd);
- free(hd);
- }
- }
-}
-
diff --git a/sys/src/cmd/usb/audio/mkfile b/sys/src/cmd/usb/audio/mkfile
deleted file mode 100644
index 507adc3e5..000000000
--- a/sys/src/cmd/usb/audio/mkfile
+++ /dev/null
@@ -1,31 +0,0 @@
-</$objtype/mkfile
-
-TARG=audio
-OFILES=\
- audiofs.$O\
- audiosub.$O\
- audio.$O\
- audioctl.$O\
-
-HFILES=\
- audio.h\
- audioctl.h\
- ../lib/usb.h\
-
-UPDATE=\
- $HFILES\
- ${OFILES:%.$O=%.c}\
- mkfile\
- /sys/man/3/usb\
-
-LIB=../lib/usb.a$O
-
-BIN=/$objtype/bin/usb
-</sys/src/cmd/mkone
-
-CFLAGS=-I../lib $CFLAGS
-
-$LIB:
- cd ../lib
- mk install
- mk clean
diff --git a/sys/src/cmd/usb/disk/disk.c b/sys/src/cmd/usb/disk/disk.c
deleted file mode 100644
index abad3d66b..000000000
--- a/sys/src/cmd/usb/disk/disk.c
+++ /dev/null
@@ -1,982 +0,0 @@
-/*
- * usb/disk - usb mass storage file server
- *
- * supports only the scsi command interface, not ata.
- */
-
-#include <u.h>
-#include <libc.h>
-#include <ctype.h>
-#include <fcall.h>
-#include <thread.h>
-#include "scsireq.h"
-#include "usb.h"
-#include "usbfs.h"
-#include "ums.h"
-
-enum
-{
- Qdir = 0,
- Qctl,
- Qraw,
- Qdata,
- Qpart,
- Qmax = Maxparts,
-};
-
-typedef struct Dirtab Dirtab;
-struct Dirtab
-{
- char *name;
- int mode;
-};
-
-ulong ctlmode = 0664;
-
-/*
- * Partition management (adapted from disk/partfs)
- */
-
-Part *
-lookpart(Umsc *lun, char *name)
-{
- Part *part, *p;
-
- part = lun->part;
- for(p=part; p < &part[Qmax]; p++){
- if(p->inuse && strcmp(p->name, name) == 0)
- return p;
- }
- return nil;
-}
-
-Part *
-freepart(Umsc *lun)
-{
- Part *part, *p;
-
- part = lun->part;
- for(p=part; p < &part[Qmax]; p++){
- if(!p->inuse)
- return p;
- }
- return nil;
-}
-
-int
-addpart(Umsc *lun, char *name, vlong start, vlong end, ulong mode)
-{
- Part *p;
-
- if(start < 0 || start > end || end > lun->blocks){
- werrstr("bad partition boundaries");
- return -1;
- }
- if(lookpart(lun, name) != nil) {
- werrstr("partition name already in use");
- return -1;
- }
- p = freepart(lun);
- if(p == nil){
- werrstr("no free partition slots");
- return -1;
- }
- p->inuse = 1;
- free(p->name);
- p->id = p - lun->part;
- p->name = estrdup(name);
- p->offset = start;
- p->length = end - start;
- p->mode = mode;
- return 0;
-}
-
-int
-delpart(Umsc *lun, char *s)
-{
- Part *p;
-
- p = lookpart(lun, s);
- if(p == nil || p->id <= Qdata){
- werrstr("partition not found");
- return -1;
- }
- p->inuse = 0;
- free(p->name);
- p->name = nil;
- p->vers++;
- return 0;
-}
-
-void
-fixlength(Umsc *lun, vlong blocks)
-{
- Part *part, *p;
-
- part = lun->part;
- part[Qdata].length = blocks;
- for(p=&part[Qdata+1]; p < &part[Qmax]; p++){
- if(p->inuse && p->offset + p->length > blocks){
- if(p->offset > blocks){
- p->offset =blocks;
- p->length = 0;
- }else
- p->length = blocks - p->offset;
- }
- }
-}
-
-void
-makeparts(Umsc *lun)
-{
- addpart(lun, "/", 0, 0, DMDIR | 0555);
- addpart(lun, "ctl", 0, 0, 0664);
- addpart(lun, "raw", 0, 0, 0640);
- addpart(lun, "data", 0, lun->blocks, 0640);
-}
-
-/*
- * ctl parsing & formatting (adapted from partfs)
- */
-
-static char*
-ctlstring(Usbfs *fs)
-{
- Part *p, *part;
- Fmt fmt;
- Umsc *lun;
- Ums *ums;
-
- ums = fs->dev->aux;
- lun = fs->aux;
- part = &lun->part[0];
-
- fmtstrinit(&fmt);
- fmtprint(&fmt, "dev %s\n", fs->dev->dir);
- fmtprint(&fmt, "lun %ld\n", lun - &ums->lun[0]);
- if(lun->flags & Finqok)
- fmtprint(&fmt, "inquiry %s\n", lun->inq);
- if(lun->blocks > 0)
- fmtprint(&fmt, "geometry %llud %ld\n", lun->blocks, lun->lbsize);
- for (p = &part[Qdata+1]; p < &part[Qmax]; p++)
- if (p->inuse)
- fmtprint(&fmt, "part %s %lld %lld\n",
- p->name, p->offset, p->offset + p->length);
- return fmtstrflush(&fmt);
-}
-
-static int
-ctlparse(Usbfs *fs, char *msg)
-{
- vlong start, end;
- char *argv[16];
- int argc;
- Umsc *lun;
-
- lun = fs->aux;
- argc = tokenize(msg, argv, nelem(argv));
-
- if(argc < 1){
- werrstr("empty control message");
- return -1;
- }
-
- if(strcmp(argv[0], "part") == 0){
- if(argc != 4){
- werrstr("part takes 3 args");
- return -1;
- }
- start = strtoll(argv[2], 0, 0);
- end = strtoll(argv[3], 0, 0);
- return addpart(lun, argv[1], start, end, 0640);
- }else if(strcmp(argv[0], "delpart") == 0){
- if(argc != 2){
- werrstr("delpart takes 1 arg");
- return -1;
- }
- return delpart(lun, argv[1]);
- }
- werrstr("unknown ctl");
- return -1;
-}
-
-/*
- * These are used by scuzz scsireq
- */
-int exabyte, force6bytecmds;
-
-int diskdebug;
-
-static void
-ding(void *, char *msg)
-{
- if(strstr(msg, "alarm") != nil)
- noted(NCONT);
- noted(NDFLT);
-}
-
-static int
-getmaxlun(Dev *dev)
-{
- uchar max;
- int r;
-
- max = 0;
- r = Rd2h|Rclass|Riface;
- if(usbcmd(dev, r, Getmaxlun, 0, 0, &max, 1) < 0){
- dprint(2, "disk: %s: getmaxlun failed: %r\n", dev->dir);
- }else{
- max &= 017; /* 15 is the max. allowed */
- dprint(2, "disk: %s: maxlun %d\n", dev->dir, max);
- }
- return max;
-}
-
-static int
-umsreset(Ums *ums)
-{
- int r;
-
- r = Rh2d|Rclass|Riface;
- if(usbcmd(ums->dev, r, Umsreset, 0, 0, nil, 0) < 0){
- fprint(2, "disk: reset: %r\n");
- return -1;
- }
- return 0;
-}
-
-static int
-umsrecover(Ums *ums)
-{
- if(umsreset(ums) < 0)
- return -1;
- if(unstall(ums->dev, ums->epin, Ein) < 0)
- dprint(2, "disk: unstall epin: %r\n");
-
- /* do we need this when epin == epout? */
- if(unstall(ums->dev, ums->epout, Eout) < 0)
- dprint(2, "disk: unstall epout: %r\n");
- return 0;
-}
-
-static void
-umsfatal(Ums *ums)
-{
- int i;
-
- devctl(ums->dev, "detach");
- for(i = 0; i < ums->maxlun; i++)
- usbfsdel(&ums->lun[i].fs);
-}
-
-static int
-ispow2(uvlong ul)
-{
- return (ul & (ul - 1)) == 0;
-}
-
-/*
- * return smallest power of 2 >= n
- */
-static int
-log2(int n)
-{
- int i;
-
- for(i = 0; (1 << i) < n; i++)
- ;
- return i;
-}
-
-static int
-umscapacity(Umsc *lun)
-{
- uchar data[32];
-
- lun->blocks = 0;
- lun->capacity = 0;
- lun->lbsize = 0;
- memset(data, 0, sizeof data);
- if(SRrcapacity(lun, data) < 0 && SRrcapacity(lun, data) < 0)
- return -1;
- lun->blocks = GETBELONG(data);
- lun->lbsize = GETBELONG(data+4);
- if(lun->blocks == 0xFFFFFFFF){
- if(SRrcapacity16(lun, data) < 0){
- lun->lbsize = 0;
- lun->blocks = 0;
- return -1;
- }else{
- lun->lbsize = GETBELONG(data + 8);
- lun->blocks = (uvlong)GETBELONG(data)<<32 |
- GETBELONG(data + 4);
- }
- }
- lun->blocks++; /* SRcapacity returns LBA of last block */
- lun->capacity = (vlong)lun->blocks * lun->lbsize;
- fixlength(lun, lun->blocks);
- if(diskdebug)
- fprint(2, "disk: logical block size %lud, # blocks %llud\n",
- lun->lbsize, lun->blocks);
- return 0;
-}
-
-static int
-umsinit(Ums *ums)
-{
- uchar i;
- Umsc *lun;
- int some;
-
- umsreset(ums);
- ums->maxlun = getmaxlun(ums->dev);
- ums->lun = mallocz((ums->maxlun+1) * sizeof(*ums->lun), 1);
- some = 0;
- for(i = 0; i <= ums->maxlun; i++){
- lun = &ums->lun[i];
- lun->ums = ums;
- lun->umsc = lun;
- lun->lun = i;
- lun->flags = Fopen | Fusb | Frw10;
- if(SRinquiry(lun) < 0 && SRinquiry(lun) < 0){
- dprint(2, "disk: lun %d inquiry failed\n", i);
- continue;
- }
- switch(lun->inquiry[0]){
- case Devdir:
- case Devworm: /* a little different than the others */
- case Devcd:
- case Devmo:
- break;
- default:
- fprint(2, "disk: lun %d is not a disk (type %#02x)\n",
- i, lun->inquiry[0]);
- continue;
- }
- SRstart(lun, 1);
- /*
- * we ignore the device type reported by inquiry.
- * Some devices return a wrong value but would still work.
- */
- some++;
- lun->inq = smprint("%.48s", (char *)lun->inquiry+8);
- umscapacity(lun);
- }
- if(some == 0){
- dprint(2, "disk: all luns failed\n");
- devctl(ums->dev, "detach");
- return -1;
- }
- return 0;
-}
-
-
-/*
- * called by SR*() commands provided by scuzz's scsireq
- */
-long
-umsrequest(Umsc *umsc, ScsiPtr *cmd, ScsiPtr *data, int *status)
-{
- Cbw cbw;
- Csw csw;
- int n, nio, left;
- Ums *ums;
-
- ums = umsc->ums;
-
- memcpy(cbw.signature, "USBC", 4);
- cbw.tag = ++ums->seq;
- cbw.datalen = data->count;
- cbw.flags = data->write? CbwDataOut: CbwDataIn;
- cbw.lun = umsc->lun;
- if(cmd->count < 1 || cmd->count > 16)
- print("disk: umsrequest: bad cmd count: %ld\n", cmd->count);
-
- cbw.len = cmd->count;
- assert(cmd->count <= sizeof(cbw.command));
- memcpy(cbw.command, cmd->p, cmd->count);
- memset(cbw.command + cmd->count, 0, sizeof(cbw.command) - cmd->count);
-
- werrstr(""); /* we use %r later even for n == 0 */
- if(diskdebug){
- fprint(2, "disk: cmd: tag %#lx: ", cbw.tag);
- for(n = 0; n < cbw.len; n++)
- fprint(2, " %2.2x", cbw.command[n]&0xFF);
- fprint(2, " datalen: %ld\n", cbw.datalen);
- }
-
- /* issue tunnelled scsi command */
- if(write(ums->epout->dfd, &cbw, CbwLen) != CbwLen){
- fprint(2, "disk: cmd: %r\n");
- goto Fail;
- }
-
- /* transfer the data */
- nio = data->count;
- if(nio != 0){
- if(data->write)
- n = write(ums->epout->dfd, data->p, nio);
- else{
- n = read(ums->epin->dfd, data->p, nio);
- left = nio - n;
- if (n >= 0 && left > 0) /* didn't fill data->p? */
- memset(data->p + n, 0, left);
- }
- nio = n;
- if(diskdebug)
- if(n < 0)
- fprint(2, "disk: data: %r\n");
- else
- fprint(2, "disk: data: %d bytes\n", n);
- if(n <= 0)
- if(data->write == 0)
- unstall(ums->dev, ums->epin, Ein);
- }
-
- /* read the transfer's status */
- n = read(ums->epin->dfd, &csw, CswLen);
- if(n <= 0){
- /* n == 0 means "stalled" */
- unstall(ums->dev, ums->epin, Ein);
- n = read(ums->epin->dfd, &csw, CswLen);
- }
-
- if(n != CswLen || strncmp(csw.signature, "USBS", 4) != 0){
- dprint(2, "disk: read n=%d: status: %r\n", n);
- goto Fail;
- }
- if(csw.tag != cbw.tag){
- dprint(2, "disk: status tag mismatch\n");
- goto Fail;
- }
- if(csw.status >= CswPhaseErr){
- dprint(2, "disk: phase error\n");
- goto Fail;
- }
- if(csw.dataresidue == 0 || ums->wrongresidues)
- csw.dataresidue = data->count - nio;
- if(diskdebug){
- fprint(2, "disk: status: %2.2ux residue: %ld\n",
- csw.status, csw.dataresidue);
- if(cbw.command[0] == ScmdRsense){
- fprint(2, "sense data:");
- for(n = 0; n < data->count - csw.dataresidue; n++)
- fprint(2, " %2.2x", data->p[n]);
- fprint(2, "\n");
- }
- }
- switch(csw.status){
- case CswOk:
- *status = STok;
- break;
- case CswFailed:
- *status = STcheck;
- break;
- default:
- dprint(2, "disk: phase error\n");
- goto Fail;
- }
- ums->nerrs = 0;
- return data->count - csw.dataresidue;
-
-Fail:
- *status = STharderr;
- if(ums->nerrs++ > 15){
- fprint(2, "disk: %s: too many errors: device detached\n", ums->dev->dir);
- umsfatal(ums);
- }else
- umsrecover(ums);
- return -1;
-}
-
-static int
-dwalk(Usbfs *fs, Fid *fid, char *name)
-{
- Umsc *lun;
- Part *p;
-
- lun = fs->aux;
-
- if((fid->qid.type & QTDIR) == 0){
- werrstr("walk in non-directory");
- return -1;
- }
- if(strcmp(name, "..") == 0)
- return 0;
-
- p = lookpart(lun, name);
- if(p == nil){
- werrstr(Enotfound);
- return -1;
- }
- fid->qid.path = p->id | fs->qid;
- fid->qid.vers = p->vers;
- fid->qid.type = p->mode >> 24;
- return 0;
-}
-static int
-dstat(Usbfs *fs, Qid qid, Dir *d);
-
-static void
-dostat(Usbfs *fs, int path, Dir *d)
-{
- Umsc *lun;
- Part *p;
-
- lun = fs->aux;
- p = &lun->part[path];
- d->qid.path = path;
- d->qid.vers = p->vers;
- d->qid.type =p->mode >> 24;
- d->mode = p->mode;
- d->length = (vlong) p->length * lun->lbsize;
- strecpy(d->name, d->name + Namesz - 1, p->name);
-}
-
-static int
-dirgen(Usbfs *fs, Qid, int n, Dir *d, void*)
-{
- Umsc *lun;
- int i;
-
- lun = fs->aux;
- for(i = Qctl; i < Qmax; i++){
- if(lun->part[i].inuse == 0)
- continue;
- if(n-- == 0)
- break;
- }
- if(i == Qmax)
- return -1;
- dostat(fs, i, d);
- d->qid.path |= fs->qid;
- return 0;
-}
-
-static int
-dstat(Usbfs *fs, Qid qid, Dir *d)
-{
- int path;
-
- path = qid.path & ~fs->qid;
- dostat(fs, path, d);
- d->qid.path |= fs->qid;
- return 0;
-}
-
-static int
-dopen(Usbfs *fs, Fid *fid, int)
-{
- ulong path;
- Umsc *lun;
-
- path = fid->qid.path & ~fs->qid;
- lun = fs->aux;
- switch(path){
- case Qraw:
- lun->phase = Pcmd;
- break;
- }
- return 0;
-}
-
-/*
- * check i/o parameters and compute values needed later.
- * we shift & mask manually to avoid run-time calls to _divv and _modv,
- * since we don't need general division nor its cost.
- */
-static int
-setup(Umsc *lun, Part *p, char *data, int count, vlong offset)
-{
- long nb, lbsize, lbshift, lbmask;
- uvlong bno;
-
- if(count < 0 || lun->lbsize <= 0 && umscapacity(lun) < 0 ||
- lun->lbsize == 0)
- return -1;
- lbsize = lun->lbsize;
- assert(ispow2(lbsize));
- lbshift = log2(lbsize);
- lbmask = lbsize - 1;
-
- bno = offset >> lbshift; /* offset / lbsize */
- nb = ((offset + count + lbsize - 1) >> lbshift) - bno;
-
- if(bno + nb > p->length) /* past end of partition? */
- nb = p->length - bno;
- if(nb * lbsize > Maxiosize)
- nb = Maxiosize / lbsize;
- lun->nb = nb;
- if(bno >= p->length || nb == 0)
- return 0;
-
- bno += p->offset; /* start of partition */
- lun->offset = bno;
- lun->off = offset & lbmask; /* offset % lbsize */
- if(lun->off == 0 && (count & lbmask) == 0)
- lun->bufp = data;
- else
- /* not transferring full, aligned blocks; need intermediary */
- lun->bufp = lun->buf;
- return count;
-}
-
-/*
- * Upon SRread/SRwrite errors we assume the medium may have changed,
- * and ask again for the capacity of the media.
- * BUG: How to proceed to avoid confussing dossrv??
- */
-static long
-dread(Usbfs *fs, Fid *fid, void *data, long count, vlong offset)
-{
- long n;
- ulong path;
- char buf[64];
- char *s;
- Part *p;
- Umsc *lun;
- Ums *ums;
- Qid q;
-
- q = fid->qid;
- path = fid->qid.path & ~fs->qid;
- ums = fs->dev->aux;
- lun = fs->aux;
-
- qlock(ums);
- switch(path){
- case Qdir:
- count = usbdirread(fs, q, data, count, offset, dirgen, nil);
- break;
- case Qctl:
- s = ctlstring(fs);
- count = usbreadbuf(data, count, offset, s, strlen(s));
- free(s);
- break;
- case Qraw:
- if(lun->lbsize <= 0 && umscapacity(lun) < 0){
- count = -1;
- break;
- }
- switch(lun->phase){
- case Pcmd:
- qunlock(ums);
- werrstr("phase error");
- return -1;
- case Pdata:
- lun->data.p = data;
- lun->data.count = count;
- lun->data.write = 0;
- count = umsrequest(lun,&lun->cmd,&lun->data,&lun->status);
- lun->phase = Pstatus;
- if(count < 0)
- lun->lbsize = 0; /* medium may have changed */
- break;
- case Pstatus:
- n = snprint(buf, sizeof buf, "%11.0ud ", lun->status);
- count = usbreadbuf(data, count, 0LL, buf, n);
- lun->phase = Pcmd;
- break;
- }
- break;
- case Qdata:
- default:
- p = &lun->part[path];
- if(!p->inuse){
- count = -1;
- werrstr(Eperm);
- break;
- }
- count = setup(lun, p, data, count, offset);
- if (count <= 0)
- break;
- n = SRread(lun, lun->bufp, lun->nb * lun->lbsize);
- if(n < 0){
- lun->lbsize = 0; /* medium may have changed */
- count = -1;
- } else if (lun->bufp == data)
- count = n;
- else{
- /*
- * if n == lun->nb*lun->lbsize (as expected),
- * just copy count bytes.
- */
- if(lun->off + count > n)
- count = n - lun->off; /* short read */
- if(count > 0)
- memmove(data, lun->bufp + lun->off, count);
- }
- break;
- }
- qunlock(ums);
- return count;
-}
-
-static long
-dwrite(Usbfs *fs, Fid *fid, void *data, long count, vlong offset)
-{
- long len, ocount;
- ulong path;
- uvlong bno;
- Ums *ums;
- Part *p;
- Umsc *lun;
- char *s;
-
- ums = fs->dev->aux;
- lun = fs->aux;
- path = fid->qid.path & ~fs->qid;
-
- qlock(ums);
- switch(path){
- case Qdir:
- count = -1;
- werrstr(Eperm);
- break;
- case Qctl:
- s = emallocz(count+1, 1);
- memmove(s, data, count);
- if(s[count-1] == '\n')
- s[count-1] = 0;
- if(ctlparse(fs, s) == -1)
- count = -1;
- free(s);
- break;
- case Qraw:
- if(lun->lbsize <= 0 && umscapacity(lun) < 0){
- count = -1;
- break;
- }
- switch(lun->phase){
- case Pcmd:
- if(count != 6 && count != 10){
- qunlock(ums);
- werrstr("bad command length");
- return -1;
- }
- memmove(lun->rawcmd, data, count);
- lun->cmd.p = lun->rawcmd;
- lun->cmd.count = count;
- lun->cmd.write = 1;
- lun->phase = Pdata;
- break;
- case Pdata:
- lun->data.p = data;
- lun->data.count = count;
- lun->data.write = 1;
- count = umsrequest(lun,&lun->cmd,&lun->data,&lun->status);
- lun->phase = Pstatus;
- if(count < 0)
- lun->lbsize = 0; /* medium may have changed */
- break;
- case Pstatus:
- lun->phase = Pcmd;
- werrstr("phase error");
- count = -1;
- break;
- }
- break;
- case Qdata:
- default:
- p = &lun->part[path];
- if(!p->inuse){
- count = -1;
- werrstr(Eperm);
- break;
- }
- len = ocount = count;
- count = setup(lun, p, data, count, offset);
- if (count <= 0)
- break;
- bno = lun->offset;
- if (lun->bufp == lun->buf) {
- count = SRread(lun, lun->bufp, lun->nb * lun->lbsize);
- if(count < 0) {
- lun->lbsize = 0; /* medium may have changed */
- break;
- }
- /*
- * if count == lun->nb*lun->lbsize, as expected, just
- * copy len (the original count) bytes of user data.
- */
- if(lun->off + len > count)
- len = count - lun->off; /* short read */
- if(len > 0)
- memmove(lun->bufp + lun->off, data, len);
- }
-
- lun->offset = bno;
- count = SRwrite(lun, lun->bufp, lun->nb * lun->lbsize);
- if(count < 0)
- lun->lbsize = 0; /* medium may have changed */
- else{
- if(lun->off + len > count)
- count -= lun->off; /* short write */
- /* never report more bytes written than requested */
- if(count < 0)
- count = 0;
- else if(count > ocount)
- count = ocount;
- }
- break;
- }
- qunlock(ums);
- return count;
-}
-
-int
-findendpoints(Ums *ums)
-{
- Ep *ep;
- Usbdev *ud;
- ulong csp, sc;
- int i, epin, epout;
-
- epin = epout = -1;
- ud = ums->dev->usb;
- for(i = 0; i < nelem(ud->ep); i++){
- if((ep = ud->ep[i]) == nil)
- continue;
- csp = ep->iface->csp;
- sc = Subclass(csp);
- if(!(Class(csp) == Clstorage && (Proto(csp) == Protobulk)))
- continue;
- if(sc != Subatapi && sc != Sub8070 && sc != Subscsi)
- fprint(2, "disk: subclass %#ulx not supported. trying anyway\n", sc);
- if(ep->type == Ebulk){
- if(ep->dir == Eboth || ep->dir == Ein)
- if(epin == -1)
- epin = ep->id;
- if(ep->dir == Eboth || ep->dir == Eout)
- if(epout == -1)
- epout = ep->id;
- }
- }
- dprint(2, "disk: ep ids: in %d out %d\n", epin, epout);
- if(epin == -1 || epout == -1)
- return -1;
- ums->epin = openep(ums->dev, epin);
- if(ums->epin == nil){
- fprint(2, "disk: openep %d: %r\n", epin);
- return -1;
- }
- if(epout == epin){
- incref(ums->epin);
- ums->epout = ums->epin;
- }else
- ums->epout = openep(ums->dev, epout);
- if(ums->epout == nil){
- fprint(2, "disk: openep %d: %r\n", epout);
- closedev(ums->epin);
- return -1;
- }
- if(ums->epin == ums->epout)
- opendevdata(ums->epin, ORDWR);
- else{
- opendevdata(ums->epin, OREAD);
- opendevdata(ums->epout, OWRITE);
- }
- if(ums->epin->dfd < 0 || ums->epout->dfd < 0){
- fprint(2, "disk: open i/o ep data: %r\n");
- closedev(ums->epin);
- closedev(ums->epout);
- return -1;
- }
- dprint(2, "disk: ep in %s out %s\n", ums->epin->dir, ums->epout->dir);
-
- devctl(ums->epin, "timeout 2000");
- devctl(ums->epout, "timeout 2000");
-
- if(usbdebug > 1 || diskdebug > 2){
- devctl(ums->epin, "debug 1");
- devctl(ums->epout, "debug 1");
- devctl(ums->dev, "debug 1");
- }
- return 0;
-}
-
-static int
-usage(void)
-{
- werrstr("usage: usb/disk [-d] [-N nb]");
- return -1;
-}
-
-static void
-umsdevfree(void *a)
-{
- Ums *ums = a;
-
- if(ums == nil)
- return;
- closedev(ums->epin);
- closedev(ums->epout);
- ums->epin = ums->epout = nil;
- free(ums->lun);
- free(ums);
-}
-
-static Usbfs diskfs = {
- .walk = dwalk,
- .open = dopen,
- .read = dread,
- .write = dwrite,
- .stat = dstat,
-};
-
-int
-diskmain(Dev *dev, int argc, char **argv)
-{
- Ums *ums;
- Umsc *lun;
- int i, devid;
-
- devid = dev->id;
- ARGBEGIN{
- case 'd':
- scsidebug(diskdebug);
- diskdebug++;
- break;
- case 'N':
- devid = atoi(EARGF(usage()));
- break;
- default:
- return usage();
- }ARGEND
- if(argc != 0) {
- return usage();
- }
-
-// notify(ding);
- ums = dev->aux = emallocz(sizeof(Ums), 1);
- ums->maxlun = -1;
- ums->dev = dev;
- dev->free = umsdevfree;
- if(findendpoints(ums) < 0){
- werrstr("disk: endpoints not found");
- return -1;
- }
-
- /*
- * SanDISK 512M gets residues wrong.
- */
- if(dev->usb->vid == 0x0781 && dev->usb->did == 0x5150)
- ums->wrongresidues = 1;
-
- if(umsinit(ums) < 0){
- dprint(2, "disk: umsinit: %r\n");
- return -1;
- }
-
- for(i = 0; i <= ums->maxlun; i++){
- lun = &ums->lun[i];
- lun->fs = diskfs;
- snprint(lun->fs.name, sizeof(lun->fs.name), "sdU%d.%d", devid, i);
- lun->fs.dev = dev;
- incref(dev);
- lun->fs.aux = lun;
- makeparts(lun);
- usbfsadd(&lun->fs);
- }
- return 0;
-}
diff --git a/sys/src/cmd/usb/disk/main.c b/sys/src/cmd/usb/disk/main.c
deleted file mode 100644
index 8ecc9ad56..000000000
--- a/sys/src/cmd/usb/disk/main.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * usb/disk - usb mass storage file server
- */
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include <thread.h>
-#include "scsireq.h"
-#include "usb.h"
-#include "usbfs.h"
-#include "ums.h"
-
-enum
-{
- Arglen = 80,
-};
-
-static void
-usage(void)
-{
- fprint(2, "usage: %s [-Dd] [-N nb] [-m mnt] [-s srv] [dev...]\n", argv0);
- threadexitsall("usage");
-}
-
-static int csps[] = {
- CSP(Clstorage,Subatapi,Protobulk),
- CSP(Clstorage,Sub8070,Protobulk),
- CSP(Clstorage,Subscsi,Protobulk),
- 0,
-};
-
-void
-threadmain(int argc, char **argv)
-{
- char args[Arglen];
- char *as, *ae, *srv, *mnt;
-
- srv = nil;
- mnt = "/n/disk";
-
- quotefmtinstall();
- ae = args+sizeof(args);
- as = seprint(args, ae, "disk");
- ARGBEGIN{
- case 'D':
- usbfsdebug++;
- break;
- case 'd':
- usbdebug++;
- as = seprint(as, ae, " -d");
- break;
- case 'N':
- as = seprint(as, ae, " -N %s", EARGF(usage()));
- break;
- case 'm':
- mnt = EARGF(usage());
- break;
- case 's':
- srv = EARGF(usage());
- break;
- default:
- usage();
- }ARGEND
-
- rfork(RFNOTEG);
- threadsetgrp(threadid());
- fmtinstall('U', Ufmt);
- usbfsinit(srv, mnt, &usbdirfs, MBEFORE);
- startdevs(args, argv, argc, matchdevcsp, csps, diskmain);
- threadexits(nil);
-}
diff --git a/sys/src/cmd/usb/disk/mkfile b/sys/src/cmd/usb/disk/mkfile
deleted file mode 100644
index 45070a34a..000000000
--- a/sys/src/cmd/usb/disk/mkfile
+++ /dev/null
@@ -1,41 +0,0 @@
-</$objtype/mkfile
-
-TARG=disk
-OFILES=\
- main.$O
-
-LIBDOFILES=\
- disk.$O\
- scsireq.$O\
- scsierrs.$O\
-
-HFILES =\
- scsireq.h\
- ../lib/usb.h\
- ../lib/usbfs.h\
- ums.h\
-
-LIBD=../lib/usbdev.a$O
-LIBU=../lib/usb.a$O
-LIB=\
- $LIBD\
- $LIBU\
-
-BIN=/$objtype/bin/usb
-
-</sys/src/cmd/mkone
-CFLAGS=-I../lib $CFLAGS
-CLEANFILES=scsierrs.c
-
-$LIBU:
- cd ../lib
- mk install
- mk clean
-
-$LIBD:V: $LIBDOFILES
- ar vu $LIBD $newprereq
- rm $newprereq
-
-scsierrs.c: /sys/lib/scsicodes mkscsierrs
- mkscsierrs >scsierrs.c
-
diff --git a/sys/src/cmd/usb/disk/mkscsierrs b/sys/src/cmd/usb/disk/mkscsierrs
deleted file mode 100755
index a7cc32e5d..000000000
--- a/sys/src/cmd/usb/disk/mkscsierrs
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/rc
-
-cat <<EOF
-#include <u.h>
-#include <libc.h>
-
-typedef struct Err Err;
-struct Err
-{
- int n;
- char *s;
-};
-
-static Err scsierrs[] = {
-EOF
-
-grep '^[0-9a-c][0-9a-c][0-9a-c][0-9a-c][ ]' /sys/lib/scsicodes |
- sed -e 's/^(....) (.*)/ {0x\1, "\2"},\n/'
-cat <<EOF
-};
-
-char*
-scsierrmsg(int n)
-{
- int i;
-
- for(i = 0; i < nelem(scsierrs); i++)
- if(scsierrs[i].n == n)
- return scsierrs[i].s;
- return "scsi error";
-}
-EOF
diff --git a/sys/src/cmd/usb/disk/scsireq.c b/sys/src/cmd/usb/disk/scsireq.c
deleted file mode 100644
index f9994e286..000000000
--- a/sys/src/cmd/usb/disk/scsireq.c
+++ /dev/null
@@ -1,986 +0,0 @@
-/*
- * This is /sys/src/cmd/scuzz/scsireq.c
- * changed to add more debug support, to keep
- * disk compiling without a scuzz that includes these changes.
- * Also, this includes minor tweaks for usb:
- * we set req.lun/unit to rp->lun/unit in SRreqsense
- * we set the rp->sense[0] bit Sd0valid in SRreqsense
- * This does not use libdisk to retrieve the scsi error to make
- * user see the diagnostics if we boot with debug enabled.
- *
- * BUGS:
- * no luns
- * and incomplete in many other ways
- */
-
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include "scsireq.h"
-
-enum {
- Debug = 0,
-};
-
-/*
- * exabyte tape drives, at least old ones like the 8200 and 8505,
- * are dumb: you have to read the exact block size on the tape,
- * they don't take 10-byte SCSI commands, and various other fine points.
- */
-extern int exabyte, force6bytecmds;
-
-static int debug = Debug;
-
-static char *scmdnames[256] = {
-[ScmdTur] "Tur",
-[ScmdRewind] "Rewind",
-[ScmdRsense] "Rsense",
-[ScmdFormat] "Format",
-[ScmdRblimits] "Rblimits",
-[ScmdRead] "Read",
-[ScmdWrite] "Write",
-[ScmdSeek] "Seek",
-[ScmdFmark] "Fmark",
-[ScmdSpace] "Space",
-[ScmdInq] "Inq",
-[ScmdMselect6] "Mselect6",
-[ScmdMselect10] "Mselect10",
-[ScmdMsense6] "Msense6",
-[ScmdMsense10] "Msense10",
-[ScmdStart] "Start",
-[ScmdRcapacity] "Rcapacity",
-[ScmdRcapacity16] "Rcap16",
-[ScmdExtread] "Extread",
-[ScmdExtwrite] "Extwrite",
-[ScmdExtseek] "Extseek",
-
-[ScmdSynccache] "Synccache",
-[ScmdRTOC] "RTOC",
-[ScmdRdiscinfo] "Rdiscinfo",
-[ScmdRtrackinfo] "Rtrackinfo",
-[ScmdReserve] "Reserve",
-[ScmdBlank] "Blank",
-
-[ScmdCDpause] "CDpause",
-[ScmdCDstop] "CDstop",
-[ScmdCDplay] "CDplay",
-[ScmdCDload] "CDload",
-[ScmdCDscan] "CDscan",
-[ScmdCDstatus] "CDstatus",
-[Scmdgetconf] "getconf",
-};
-
-long
-SRready(ScsiReq *rp)
-{
- uchar cmd[6];
-
- memset(cmd, 0, sizeof cmd);
- rp->cmd.p = cmd;
- rp->cmd.count = sizeof cmd;
- rp->data.p = cmd;
- rp->data.count = 0;
- rp->data.write = 1;
- return SRrequest(rp);
-}
-
-long
-SRrewind(ScsiReq *rp)
-{
- uchar cmd[6];
-
- memset(cmd, 0, sizeof cmd);
- cmd[0] = ScmdRewind;
- rp->cmd.p = cmd;
- rp->cmd.count = sizeof cmd;
- rp->data.p = cmd;
- rp->data.count = 0;
- rp->data.write = 1;
- if(SRrequest(rp) >= 0){
- rp->offset = 0;
- return 0;
- }
- return -1;
-}
-
-long
-SRreqsense(ScsiReq *rp)
-{
- uchar cmd[6];
- ScsiReq req;
- long status;
-
- if(rp->status == Status_SD){
- rp->status = STok;
- return 0;
- }
- memset(cmd, 0, sizeof cmd);
- cmd[0] = ScmdRsense;
- cmd[4] = sizeof(req.sense);
- memset(&req, 0, sizeof(req));
- if(rp->flags&Fusb)
- req.flags |= Fusb;
- req.lun = rp->lun;
- req.unit = rp->unit;
- req.fd = rp->fd;
- req.umsc = rp->umsc;
- req.cmd.p = cmd;
- req.cmd.count = sizeof cmd;
- req.data.p = rp->sense;
- req.data.count = sizeof(rp->sense);
- req.data.write = 0;
- status = SRrequest(&req);
- rp->status = req.status;
- if(status != -1)
- rp->sense[0] |= Sd0valid;
- return status;
-}
-
-long
-SRformat(ScsiReq *rp)
-{
- uchar cmd[6];
-
- memset(cmd, 0, sizeof cmd);
- cmd[0] = ScmdFormat;
- rp->cmd.p = cmd;
- rp->cmd.count = sizeof cmd;
- rp->data.p = cmd;
- rp->data.count = 6;
- rp->data.write = 0;
- return SRrequest(rp);
-}
-
-long
-SRrblimits(ScsiReq *rp, uchar *list)
-{
- uchar cmd[6];
-
- memset(cmd, 0, sizeof cmd);
- cmd[0] = ScmdRblimits;
- rp->cmd.p = cmd;
- rp->cmd.count = sizeof cmd;
- rp->data.p = list;
- rp->data.count = 6;
- rp->data.write = 0;
- return SRrequest(rp);
-}
-
-static int
-dirdevrw(ScsiReq *rp, uchar *cmd, long nbytes)
-{
- long n;
-
- n = nbytes / rp->lbsize;
- if(rp->offset <= Max24off && n <= 256 && (rp->flags & Frw10) == 0){
- PUTBE24(cmd+1, rp->offset);
- cmd[4] = n;
- cmd[5] = 0;
- return 6;
- }
- cmd[0] |= ScmdExtread;
- cmd[1] = 0;
- PUTBELONG(cmd+2, rp->offset);
- cmd[6] = 0;
- cmd[7] = n>>8;
- cmd[8] = n;
- cmd[9] = 0;
- return 10;
-}
-
-static int
-seqdevrw(ScsiReq *rp, uchar *cmd, long nbytes)
-{
- long n;
-
- /* don't set Cmd1sili; we want the ILI bit instead of a fatal error */
- cmd[1] = rp->flags&Fbfixed? Cmd1fixed: 0;
- n = nbytes / rp->lbsize;
- PUTBE24(cmd+2, n);
- cmd[5] = 0;
- return 6;
-}
-
-extern int diskdebug;
-
-long
-SRread(ScsiReq *rp, void *buf, long nbytes)
-{
- uchar cmd[10];
- long n;
-
- if(rp->lbsize == 0 || (nbytes % rp->lbsize) || nbytes > Maxiosize){
- if(diskdebug)
- if (nbytes % rp->lbsize)
- fprint(2, "disk: i/o size %ld %% %ld != 0\n",
- nbytes, rp->lbsize);
- else
- fprint(2, "disk: i/o size %ld > %d\n",
- nbytes, Maxiosize);
- rp->status = Status_BADARG;
- return -1;
- }
-
- /* set up scsi read cmd */
- cmd[0] = ScmdRead;
- if(rp->flags & Fseqdev)
- rp->cmd.count = seqdevrw(rp, cmd, nbytes);
- else
- rp->cmd.count = dirdevrw(rp, cmd, nbytes);
- rp->cmd.p = cmd;
- rp->data.p = buf;
- rp->data.count = nbytes;
- rp->data.write = 0;
-
- /* issue it */
- n = SRrequest(rp);
- if(n != -1){ /* it worked? */
- rp->offset += n / rp->lbsize;
- return n;
- }
-
- /* request failed; maybe we just read a short record? */
- if (exabyte) {
- fprint(2, "read error\n");
- rp->status = STcheck;
- return n;
- }
- if(rp->status != Status_SD || !(rp->sense[0] & Sd0valid))
- return -1;
- /* compute # of bytes not read */
- n = GETBELONG(rp->sense+3) * rp->lbsize;
- if(!(rp->flags & Fseqdev))
- return -1;
-
- /* device is a tape or something similar */
- if (rp->sense[2] == Sd2filemark || rp->sense[2] == 0x08 ||
- rp->sense[2] & Sd2ili && n > 0)
- rp->data.count = nbytes - n;
- else
- return -1;
- n = rp->data.count;
- if (!rp->readblock++ || debug)
- fprint(2, "SRread: tape data count %ld%s\n", n,
- (rp->sense[2] & Sd2ili? " with ILI": ""));
- rp->status = STok;
- rp->offset += n / rp->lbsize;
- return n;
-}
-
-long
-SRwrite(ScsiReq *rp, void *buf, long nbytes)
-{
- uchar cmd[10];
- long n;
-
- if(rp->lbsize == 0 || (nbytes % rp->lbsize) || nbytes > Maxiosize){
- if(diskdebug)
- if (nbytes % rp->lbsize)
- fprint(2, "disk: i/o size %ld %% %ld != 0\n",
- nbytes, rp->lbsize);
- else
- fprint(2, "disk: i/o size %ld > %d\n",
- nbytes, Maxiosize);
- rp->status = Status_BADARG;
- return -1;
- }
-
- /* set up scsi write cmd */
- cmd[0] = ScmdWrite;
- if(rp->flags & Fseqdev)
- rp->cmd.count = seqdevrw(rp, cmd, nbytes);
- else
- rp->cmd.count = dirdevrw(rp, cmd, nbytes);
- rp->cmd.p = cmd;
- rp->data.p = buf;
- rp->data.count = nbytes;
- rp->data.write = 1;
-
- /* issue it */
- if((n = SRrequest(rp)) == -1){
- if (exabyte) {
- fprint(2, "write error\n");
- rp->status = STcheck;
- return n;
- }
- if(rp->status != Status_SD || rp->sense[2] != Sd2eom)
- return -1;
- if(rp->sense[0] & Sd0valid){
- n -= GETBELONG(rp->sense+3) * rp->lbsize;
- rp->data.count = nbytes - n;
- }
- else
- rp->data.count = nbytes;
- n = rp->data.count;
- }
- rp->offset += n / rp->lbsize;
- return n;
-}
-
-long
-SRseek(ScsiReq *rp, long offset, int type)
-{
- uchar cmd[10];
-
- switch(type){
-
- case 0:
- break;
-
- case 1:
- offset += rp->offset;
- if(offset >= 0)
- break;
- /*FALLTHROUGH*/
-
- default:
- if(diskdebug)
- fprint(2, "disk: seek failed\n");
- rp->status = Status_BADARG;
- return -1;
- }
- memset(cmd, 0, sizeof cmd);
- if(offset <= Max24off && (rp->flags & Frw10) == 0){
- cmd[0] = ScmdSeek;
- PUTBE24(cmd+1, offset & Max24off);
- rp->cmd.count = 6;
- }else{
- cmd[0] = ScmdExtseek;
- PUTBELONG(cmd+2, offset);
- rp->cmd.count = 10;
- }
- rp->cmd.p = cmd;
- rp->data.p = cmd;
- rp->data.count = 0;
- rp->data.write = 1;
- SRrequest(rp);
- if(rp->status == STok) {
- rp->offset = offset;
- return offset;
- }
- return -1;
-}
-
-long
-SRfilemark(ScsiReq *rp, ulong howmany)
-{
- uchar cmd[6];
-
- memset(cmd, 0, sizeof cmd);
- cmd[0] = ScmdFmark;
- PUTBE24(cmd+2, howmany);
- rp->cmd.p = cmd;
- rp->cmd.count = sizeof cmd;
- rp->data.p = cmd;
- rp->data.count = 0;
- rp->data.write = 1;
- return SRrequest(rp);
-}
-
-long
-SRspace(ScsiReq *rp, uchar code, long howmany)
-{
- uchar cmd[6];
-
- memset(cmd, 0, sizeof cmd);
- cmd[0] = ScmdSpace;
- cmd[1] = code;
- PUTBE24(cmd+2, howmany);
- rp->cmd.p = cmd;
- rp->cmd.count = sizeof cmd;
- rp->data.p = cmd;
- rp->data.count = 0;
- rp->data.write = 1;
- /*
- * what about rp->offset?
- */
- return SRrequest(rp);
-}
-
-long
-SRinquiry(ScsiReq *rp)
-{
- uchar cmd[6];
-
- memset(cmd, 0, sizeof cmd);
- cmd[0] = ScmdInq;
- cmd[4] = sizeof rp->inquiry;
- rp->cmd.p = cmd;
- rp->cmd.count = sizeof cmd;
- memset(rp->inquiry, 0, sizeof rp->inquiry);
- rp->data.p = rp->inquiry;
- rp->data.count = sizeof rp->inquiry;
- rp->data.write = 0;
- if(SRrequest(rp) >= 0){
- rp->flags |= Finqok;
- return 0;
- }
- rp->flags &= ~Finqok;
- return -1;
-}
-
-long
-SRmodeselect6(ScsiReq *rp, uchar *list, long nbytes)
-{
- uchar cmd[6];
-
- memset(cmd, 0, sizeof cmd);
- cmd[0] = ScmdMselect6;
- if((rp->flags & Finqok) && (rp->inquiry[2] & 0x07) >= 2)
- cmd[1] = 0x10;
- cmd[4] = nbytes;
- rp->cmd.p = cmd;
- rp->cmd.count = sizeof cmd;
- rp->data.p = list;
- rp->data.count = nbytes;
- rp->data.write = 1;
- return SRrequest(rp);
-}
-
-long
-SRmodeselect10(ScsiReq *rp, uchar *list, long nbytes)
-{
- uchar cmd[10];
-
- memset(cmd, 0, sizeof cmd);
- if((rp->flags & Finqok) && (rp->inquiry[2] & 0x07) >= 2)
- cmd[1] = 0x10;
- cmd[0] = ScmdMselect10;
- cmd[7] = nbytes>>8;
- cmd[8] = nbytes;
- rp->cmd.p = cmd;
- rp->cmd.count = sizeof cmd;
- rp->data.p = list;
- rp->data.count = nbytes;
- rp->data.write = 1;
- return SRrequest(rp);
-}
-
-long
-SRmodesense6(ScsiReq *rp, uchar page, uchar *list, long nbytes)
-{
- uchar cmd[6];
-
- memset(cmd, 0, sizeof cmd);
- cmd[0] = ScmdMsense6;
- cmd[2] = page;
- cmd[4] = nbytes;
- rp->cmd.p = cmd;
- rp->cmd.count = sizeof cmd;
- rp->data.p = list;
- rp->data.count = nbytes;
- rp->data.write = 0;
- return SRrequest(rp);
-}
-
-long
-SRmodesense10(ScsiReq *rp, uchar page, uchar *list, long nbytes)
-{
- uchar cmd[10];
-
- memset(cmd, 0, sizeof cmd);
- cmd[0] = ScmdMsense10;
- cmd[2] = page;
- cmd[7] = nbytes>>8;
- cmd[8] = nbytes;
- rp->cmd.p = cmd;
- rp->cmd.count = sizeof cmd;
- rp->data.p = list;
- rp->data.count = nbytes;
- rp->data.write = 0;
- return SRrequest(rp);
-}
-
-long
-SRstart(ScsiReq *rp, uchar code)
-{
- uchar cmd[6];
-
- memset(cmd, 0, sizeof cmd);
- cmd[0] = ScmdStart;
- cmd[4] = code;
- rp->cmd.p = cmd;
- rp->cmd.count = sizeof cmd;
- rp->data.p = cmd;
- rp->data.count = 0;
- rp->data.write = 1;
- return SRrequest(rp);
-}
-
-long
-SRrcapacity(ScsiReq *rp, uchar *data)
-{
- uchar cmd[10];
-
- memset(cmd, 0, sizeof cmd);
- cmd[0] = ScmdRcapacity;
- rp->cmd.p = cmd;
- rp->cmd.count = sizeof cmd;
- rp->data.p = data;
- rp->data.count = 8;
- rp->data.write = 0;
- return SRrequest(rp);
-}
-
-long
-SRrcapacity16(ScsiReq *rp, uchar *data)
-{
- uchar cmd[16];
- uint i;
-
- i = 32;
- memset(cmd, 0, sizeof cmd);
- cmd[0] = ScmdRcapacity16;
- cmd[1] = 0x10;
- cmd[10] = i>>24;
- cmd[11] = i>>16;
- cmd[12] = i>>8;
- cmd[13] = i;
-
- rp->cmd.p = cmd;
- rp->cmd.count = sizeof cmd;
- rp->data.p = data;
- rp->data.count = i;
- rp->data.write = 0;
- return SRrequest(rp);
-}
-
-void
-scsidebug(int d)
-{
- debug = d;
- if(debug)
- fprint(2, "scsidebug on\n");
-}
-
-static long
-request(int fd, ScsiPtr *cmd, ScsiPtr *data, int *status)
-{
- long n, r;
- char buf[16];
-
- /* this was an experiment but it seems to be a good idea */
- *status = STok;
-
- /* send SCSI command */
- if(write(fd, cmd->p, cmd->count) != cmd->count){
- fprint(2, "scsireq: write cmd: %r\n");
- *status = Status_SW;
- return -1;
- }
-
- /* read or write actual data */
- werrstr("");
-// alarm(5*1000);
- if(data->write)
- n = write(fd, data->p, data->count);
- else {
- n = read(fd, data->p, data->count);
- if (n < 0)
- memset(data->p, 0, data->count);
- else if (n < data->count)
- memset(data->p + n, 0, data->count - n);
- }
-// alarm(0);
- if (n != data->count && n <= 0) {
- if (debug)
- fprint(2,
- "request: tried to %s %ld bytes of data for cmd 0x%x but got %r\n",
- (data->write? "write": "read"),
- data->count, cmd->p[0]);
- } else if (n != data->count && (data->write || debug))
- fprint(2, "request: %s %ld of %ld bytes of actual data\n",
- (data->write? "wrote": "read"), n, data->count);
-
- /* read status */
- buf[0] = '\0';
- r = read(fd, buf, sizeof buf-1);
- if(exabyte && r <= 0 || !exabyte && r < 0){
- fprint(2, "scsireq: read status: %r\n");
- *status = Status_SW;
- return -1;
- }
- if (r >= 0)
- buf[r] = '\0';
- *status = atoi(buf);
- if(n < 0 && (exabyte || *status != STcheck))
- fprint(2, "scsireq: status 0x%2.2uX: data transfer: %r\n",
- *status);
- return n;
-}
-
-static char*
-seprintcmd(char *s, char* e, char *cmd, int count, int args)
-{
- uint c;
-
- if(count < 6)
- return seprint(s, e, "<short cmd>");
- c = cmd[0];
- if(scmdnames[c] != nil)
- s = seprint(s, e, "%s", scmdnames[c]);
- else
- s = seprint(s, e, "cmd:%#02uX", c);
- if(args != 0)
- switch(c){
- case ScmdRsense:
- case ScmdInq:
- case ScmdMselect6:
- case ScmdMsense6:
- s = seprint(s, e, " sz %d", cmd[4]);
- break;
- case ScmdSpace:
- s = seprint(s, e, " code %d", cmd[1]);
- break;
- case ScmdStart:
- s = seprint(s, e, " code %d", cmd[4]);
- break;
-
- }
- return s;
-}
-
-static char*
-seprintdata(char *s, char *se, uchar *p, int count)
-{
- int i;
-
- if(count == 0)
- return s;
- for(i = 0; i < 20 && i < count; i++)
- s = seprint(s, se, " %02x", p[i]);
- return s;
-}
-
-static void
-SRdumpReq(ScsiReq *rp)
-{
- char buf[128];
- char *s;
- char *se;
-
- se = buf+sizeof(buf);
- s = seprint(buf, se, "lun %d ", rp->lun);
- s = seprintcmd(s, se, (char*)rp->cmd.p, rp->cmd.count, 1);
- s = seprint(s, se, " [%ld]", rp->data.count);
- if(rp->cmd.write)
- seprintdata(s, se, rp->data.p, rp->data.count);
- fprint(2, "scsi⇒ %s\n", buf);
-}
-
-static void
-SRdumpRep(ScsiReq *rp)
-{
- char buf[128];
- char *s;
- char *se;
-
- se = buf+sizeof(buf);
- s = seprint(buf, se, "lun %d ", rp->lun);
- s = seprintcmd(s, se, (char*)rp->cmd.p, rp->cmd.count, 0);
- switch(rp->status){
- case STok:
- s = seprint(s, se, " good [%ld] ", rp->data.count);
- if(rp->cmd.write == 0)
- s = seprintdata(s, se, rp->data.p, rp->data.count);
- break;
- case STnomem:
- s = seprint(s, se, " buffer allocation failed");
- break;
- case STharderr:
- s = seprint(s, se, " controller error");
- break;
- case STtimeout:
- s = seprint(s, se, " bus timeout");
- break;
- case STcheck:
- s = seprint(s, se, " check condition");
- break;
- case STcondmet:
- s = seprint(s, se, " condition met/good");
- break;
- case STbusy:
- s = seprint(s, se, " busy");
- break;
- case STintok:
- s = seprint(s, se, " intermediate/good");
- break;
- case STintcondmet:
- s = seprint(s, se, " intermediate/condition met/good");
- break;
- case STresconf:
- s = seprint(s, se, " reservation conflict");
- break;
- case STterminated:
- s = seprint(s, se, " command terminated");
- break;
- case STqfull:
- s = seprint(s, se, " queue full");
- break;
- default:
- s = seprint(s, se, " sts=%#x", rp->status);
- }
- USED(s);
- fprint(2, "scsi← %s\n", buf);
-}
-
-static char*
-scsierr(ScsiReq *rp)
-{
- int ec;
-
- switch(rp->status){
- case 0:
- return "";
- case Status_SD:
- ec = (rp->sense[12] << 8) | rp->sense[13];
- return scsierrmsg(ec);
- case Status_SW:
- return "software error";
- case Status_BADARG:
- return "bad argument";
- case Status_RO:
- return "device is read only";
- default:
- return "unknown";
- }
-}
-
-static void
-SRdumpErr(ScsiReq *rp)
-{
- char buf[128];
- char *se;
-
- se = buf+sizeof(buf);
- seprintcmd(buf, se, (char*)rp->cmd.p, rp->cmd.count, 0);
- print("\t%s status: %s\n", buf, scsierr(rp));
-}
-
-long
-SRrequest(ScsiReq *rp)
-{
- long n;
- int status;
-
-retry:
- if(debug)
- SRdumpReq(rp);
- if(rp->flags&Fusb)
- n = umsrequest(rp->umsc, &rp->cmd, &rp->data, &status);
- else
- n = request(rp->fd, &rp->cmd, &rp->data, &status);
- rp->status = status;
- if(status == STok)
- rp->data.count = n;
- if(debug)
- SRdumpRep(rp);
- switch(status){
- case STok:
- break;
- case STcheck:
- if(rp->cmd.p[0] != ScmdRsense && SRreqsense(rp) != -1)
- rp->status = Status_SD;
- if(debug || exabyte)
- SRdumpErr(rp);
- werrstr("%s", scsierr(rp));
- return -1;
- case STbusy:
- sleep(1000); /* TODO: try a shorter sleep? */
- goto retry;
- default:
- if(debug || exabyte)
- SRdumpErr(rp);
- werrstr("%s", scsierr(rp));
- return -1;
- }
- return n;
-}
-
-int
-SRclose(ScsiReq *rp)
-{
- if((rp->flags & Fopen) == 0){
- if(diskdebug)
- fprint(2, "disk: closing closed file\n");
- rp->status = Status_BADARG;
- return -1;
- }
- close(rp->fd);
- rp->flags = 0;
- return 0;
-}
-
-static int
-dirdevopen(ScsiReq *rp)
-{
- uvlong blocks;
- uchar data[8+4+20]; /* 16-byte result: lba, blksize, reserved */
-
- memset(data, 0, sizeof data);
- if(SRstart(rp, 1) == -1 || SRrcapacity(rp, data) == -1)
- return -1;
- rp->lbsize = GETBELONG(data+4);
- blocks = GETBELONG(data);
- if(debug)
- fprint(2, "disk: dirdevopen: 10-byte logical block size %lud, "
- "# blocks %llud\n", rp->lbsize, blocks);
- if(blocks == 0xffffffff){
- if(SRrcapacity16(rp, data) == -1)
- return -1;
- rp->lbsize = GETBELONG(data + 8);
- blocks = (vlong)GETBELONG(data)<<32 | GETBELONG(data + 4);
- if(debug)
- fprint(2, "disk: dirdevopen: 16-byte logical block size"
- " %lud, # blocks %llud\n", rp->lbsize, blocks);
- }
- /* some newer dev's don't support 6-byte commands */
- if(blocks > Max24off && !force6bytecmds)
- rp->flags |= Frw10;
- return 0;
-}
-
-static int
-seqdevopen(ScsiReq *rp)
-{
- uchar mode[16], limits[6];
-
- if(SRrblimits(rp, limits) == -1)
- return -1;
- if(limits[1] == 0 && limits[2] == limits[4] && limits[3] == limits[5]){
- rp->flags |= Fbfixed;
- rp->lbsize = limits[4]<<8 | limits[5];
- if(debug)
- fprint(2, "disk: seqdevopen: 10-byte logical block size %lud\n",
- rp->lbsize);
- return 0;
- }
- /*
- * On some older hardware the optional 10-byte
- * modeselect command isn't implemented.
- */
- if (force6bytecmds)
- rp->flags |= Fmode6;
- if(!(rp->flags & Fmode6)){
- /* try 10-byte command first */
- memset(mode, 0, sizeof mode);
- mode[3] = 0x10; /* device-specific param. */
- mode[7] = 8; /* block descriptor length */
- /*
- * exabytes can't handle this, and
- * modeselect(10) is optional.
- */
- if(SRmodeselect10(rp, mode, sizeof mode) != -1){
- rp->lbsize = 1;
- return 0; /* success */
- }
- /* can't do 10-byte commands, back off to 6-byte ones */
- rp->flags |= Fmode6;
- }
-
- /* 6-byte command */
- memset(mode, 0, sizeof mode);
- mode[2] = 0x10; /* device-specific param. */
- mode[3] = 8; /* block descriptor length */
- /*
- * bsd sez exabytes need this bit (NBE: no busy enable) in
- * vendor-specific page (0), but so far we haven't needed it.
- mode[12] |= 8;
- */
- if(SRmodeselect6(rp, mode, 4+8) == -1)
- return -1;
- rp->lbsize = 1;
- return 0;
-}
-
-static int
-wormdevopen(ScsiReq *rp)
-{
- long status;
- uchar list[MaxDirData];
-
- if (SRstart(rp, 1) == -1 ||
- (status = SRmodesense10(rp, Allmodepages, list, sizeof list)) == -1)
- return -1;
- /* nbytes = list[0]<<8 | list[1]; */
-
- /* # of bytes of block descriptors of 8 bytes each; not even 1? */
- if((list[6]<<8 | list[7]) < 8)
- rp->lbsize = 2048;
- else
- /* last 3 bytes of block 0 descriptor */
- rp->lbsize = GETBE24(list+13);
- if(debug)
- fprint(2, "disk: wormdevopen: 10-byte logical block size %lud\n",
- rp->lbsize);
- return status;
-}
-
-int
-SRopenraw(ScsiReq *rp, char *unit)
-{
- char name[128];
-
- if(rp->flags & Fopen){
- if(diskdebug)
- fprint(2, "disk: opening open file\n");
- rp->status = Status_BADARG;
- return -1;
- }
- memset(rp, 0, sizeof *rp);
- rp->unit = unit;
-
- snprint(name, sizeof name, "%s/raw", unit);
- if((rp->fd = open(name, ORDWR)) == -1){
- rp->status = STtimeout;
- return -1;
- }
- rp->flags = Fopen;
- return 0;
-}
-
-int
-SRopen(ScsiReq *rp, char *unit)
-{
- if(SRopenraw(rp, unit) == -1)
- return -1;
- SRready(rp);
- if(SRinquiry(rp) >= 0){
- switch(rp->inquiry[0]){
-
- default:
- fprint(2, "unknown device type 0x%.2x\n", rp->inquiry[0]);
- rp->status = Status_SW;
- break;
-
- case Devdir:
- case Devcd:
- case Devmo:
- if(dirdevopen(rp) == -1)
- break;
- return 0;
-
- case Devseq:
- rp->flags |= Fseqdev;
- if(seqdevopen(rp) == -1)
- break;
- return 0;
-
- case Devprint:
- rp->flags |= Fprintdev;
- return 0;
-
- case Devworm:
- rp->flags |= Fwormdev;
- if(wormdevopen(rp) == -1)
- break;
- return 0;
-
- case Devjuke:
- rp->flags |= Fchanger;
- return 0;
- }
- }
- SRclose(rp);
- return -1;
-}
diff --git a/sys/src/cmd/usb/disk/scsireq.h b/sys/src/cmd/usb/disk/scsireq.h
deleted file mode 100644
index 0fbd2b938..000000000
--- a/sys/src/cmd/usb/disk/scsireq.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * This is /sys/src/cmd/scuzz/scsireq.h
- * changed to add more debug support, and to keep
- * disk compiling without a scuzz that includes these changes.
- *
- * scsireq.h is also included by usb/disk and cdfs.
- */
-typedef struct Umsc Umsc;
-#pragma incomplete Umsc
-
-enum { /* fundamental constants/defaults */
- MaxDirData = 255, /* max. direct data returned */
- /*
- * Because we are accessed via devmnt, we can never get i/o counts
- * larger than 8216 (Msgsize and devmnt's offered iounit) - 24
- * (IOHDRSZ) = 8K.
- */
- Maxiosize = 8216 - IOHDRSZ, /* max. I/O transfer size */
-};
-
-typedef struct {
- uchar *p;
- long count;
- uchar write;
-} ScsiPtr;
-
-typedef struct {
- int flags;
- char *unit; /* unit directory */
- int lun;
- ulong lbsize;
- uvlong offset; /* in blocks of lbsize bytes */
- int fd;
- Umsc *umsc; /* lun */
- ScsiPtr cmd;
- ScsiPtr data;
- int status; /* returned status */
- uchar sense[MaxDirData]; /* returned sense data */
- uchar inquiry[MaxDirData]; /* returned inquiry data */
- int readblock; /* flag: read a block since open */
-} ScsiReq;
-
-enum { /* software flags */
- Fopen = 0x0001, /* open */
- Fseqdev = 0x0002, /* sequential-access device */
- Fwritten = 0x0004, /* device written */
- Fronly = 0x0008, /* device is read-only */
- Fwormdev = 0x0010, /* write-once read-multiple device */
- Fprintdev = 0x0020, /* printer */
- Fbfixed = 0x0040, /* fixed block size */
- Fchanger = 0x0080, /* medium-changer device */
- Finqok = 0x0100, /* inquiry data is OK */
- Fmode6 = 0x0200, /* use 6-byte modeselect */
- Frw10 = 0x0400, /* use 10-byte read/write */
- Fusb = 0x0800, /* USB transparent scsi */
-};
-
-enum {
- STnomem =-4, /* buffer allocation failed */
- STharderr =-3, /* controller error of some kind */
- STtimeout =-2, /* bus timeout */
- STok = 0, /* good */
- STcheck = 0x02, /* check condition */
- STcondmet = 0x04, /* condition met/good */
- STbusy = 0x08, /* busy */
- STintok = 0x10, /* intermediate/good */
- STintcondmet = 0x14, /* intermediate/condition met/good */
- STresconf = 0x18, /* reservation conflict */
- STterminated = 0x22, /* command terminated */
- STqfull = 0x28, /* queue full */
-};
-
-enum { /* status */
- Status_SD = 0x80, /* sense-data available */
- Status_SW = 0x83, /* internal software error */
- Status_BADARG = 0x84, /* bad argument to request */
- Status_RO = 0x85, /* device is read-only */
-};
-
-enum { /* SCSI command codes */
- ScmdTur = 0x00, /* test unit ready */
- ScmdRewind = 0x01, /* rezero/rewind */
- ScmdRsense = 0x03, /* request sense */
- ScmdFormat = 0x04, /* format unit */
- ScmdRblimits = 0x05, /* read block limits */
- ScmdRead = 0x08, /* read */
- ScmdWrite = 0x0A, /* write */
- ScmdSeek = 0x0B, /* seek */
- ScmdFmark = 0x10, /* write filemarks */
- ScmdSpace = 0x11, /* space forward/backward */
- ScmdInq = 0x12, /* inquiry */
- ScmdMselect6 = 0x15, /* mode select */
- ScmdMselect10 = 0x55, /* mode select */
- ScmdMsense6 = 0x1A, /* mode sense */
- ScmdMsense10 = 0x5A, /* mode sense */
- ScmdStart = 0x1B, /* start/stop unit */
- ScmdRcapacity = 0x25, /* read capacity */
- ScmdRcapacity16 = 0x9e, /* long read capacity */
- ScmdExtread = 0x28, /* extended read */
- ScmdExtwrite = 0x2A, /* extended write */
- ScmdExtseek = 0x2B, /* extended seek */
-
- ScmdSynccache = 0x35, /* flush cache */
- ScmdRTOC = 0x43, /* read TOC data */
- ScmdRdiscinfo = 0x51, /* read disc information */
- ScmdRtrackinfo = 0x52, /* read track information */
- ScmdReserve = 0x53, /* reserve track */
- ScmdBlank = 0xA1, /* blank *-RW media */
-
- ScmdCDpause = 0x4B, /* pause/resume */
- ScmdCDstop = 0x4E, /* stop play/scan */
- ScmdCDplay = 0xA5, /* play audio */
- ScmdCDload = 0xA6, /* load/unload */
- ScmdCDscan = 0xBA, /* fast forward/reverse */
- ScmdCDstatus = 0xBD, /* mechanism status */
- Scmdgetconf = 0x46, /* get configuration */
-
- ScmdEInitialise = 0x07, /* initialise element status */
- ScmdMMove = 0xA5, /* move medium */
- ScmdEStatus = 0xB8, /* read element status */
- ScmdMExchange = 0xA6, /* exchange medium */
- ScmdEposition = 0x2B, /* position to element */
-
- ScmdReadDVD = 0xAD, /* read dvd structure */
- ScmdReportKey = 0xA4, /* read dvd key */
- ScmdSendKey = 0xA3, /* write dvd key */
-
- ScmdClosetracksess= 0x5B,
- ScmdRead12 = 0xA8,
- ScmdSetcdspeed = 0xBB,
- ScmdReadcd = 0xBE,
-
- /* vendor-specific */
- ScmdFwaddr = 0xE2, /* first writeable address */
- ScmdTreserve = 0xE4, /* reserve track */
- ScmdTinfo = 0xE5, /* read track info */
- ScmdTwrite = 0xE6, /* write track */
- ScmdMload = 0xE7, /* medium load/unload */
- ScmdFixation = 0xE9, /* fixation */
-};
-
-enum {
- /* sense data byte 0 */
- Sd0valid = 0x80, /* valid sense data present */
-
- /* sense data byte 2 */
- /* incorrect-length indicator, difference in bytes 3—6 */
- Sd2ili = 0x20,
- Sd2eom = 0x40, /* end of medium (tape) */
- Sd2filemark = 0x80, /* at a filemark (tape) */
-
- /* command byte 1 */
- Cmd1fixed = 1, /* use fixed-length blocks */
- Cmd1sili = 2, /* don't set Sd2ili */
-
- /* limit of block #s in 24-bit ccbs */
- Max24off = (1<<21) - 1, /* 2⁲ⁱ - 1 */
-
- /* mode pages */
- Allmodepages = 0x3F,
-};
-
-/* scsi device types, from the scsi standards */
-enum {
- Devdir, /* usually disk */
- Devseq, /* usually tape */
- Devprint,
- Dev3,
- Devworm, /* also direct, but special */
- Devcd, /* also direct */
- Dev6,
- Devmo, /* also direct */
- Devjuke,
-};
-
-/* p arguments should be of type uchar* */
-#define GETBELONG(p) ((ulong)(p)[0]<<24 | (ulong)(p)[1]<<16 | (p)[2]<<8 | (p)[3])
-#define PUTBELONG(p, ul) ((p)[0] = (ul)>>24, (p)[1] = (ul)>>16, \
- (p)[2] = (ul)>>8, (p)[3] = (ul))
-#define GETBE24(p) ((ulong)(p)[0]<<16 | (p)[1]<<8 | (p)[2])
-#define PUTBE24(p, ul) ((p)[0] = (ul)>>16, (p)[1] = (ul)>>8, (p)[2] = (ul))
-
-long SRready(ScsiReq*);
-long SRrewind(ScsiReq*);
-long SRreqsense(ScsiReq*);
-long SRformat(ScsiReq*);
-long SRrblimits(ScsiReq*, uchar*);
-long SRread(ScsiReq*, void*, long);
-long SRwrite(ScsiReq*, void*, long);
-long SRseek(ScsiReq*, long, int);
-long SRfilemark(ScsiReq*, ulong);
-long SRspace(ScsiReq*, uchar, long);
-long SRinquiry(ScsiReq*);
-long SRmodeselect6(ScsiReq*, uchar*, long);
-long SRmodeselect10(ScsiReq*, uchar*, long);
-long SRmodesense6(ScsiReq*, uchar, uchar*, long);
-long SRmodesense10(ScsiReq*, uchar, uchar*, long);
-long SRstart(ScsiReq*, uchar);
-long SRrcapacity(ScsiReq*, uchar*);
-long SRrcapacity16(ScsiReq*, uchar*);
-
-long SRblank(ScsiReq*, uchar, uchar); /* MMC CD-R/CD-RW commands */
-long SRsynccache(ScsiReq*);
-long SRTOC(ScsiReq*, void*, int, uchar, uchar);
-long SRrdiscinfo(ScsiReq*, void*, int);
-long SRrtrackinfo(ScsiReq*, void*, int, int);
-
-long SRcdpause(ScsiReq*, int); /* MMC CD audio commands */
-long SRcdstop(ScsiReq*);
-long SRcdload(ScsiReq*, int, int);
-long SRcdplay(ScsiReq*, int, long, long);
-long SRcdstatus(ScsiReq*, uchar*, int);
-long SRgetconf(ScsiReq*, uchar*, int);
-
-/* old CD-R/CD-RW commands */
-long SRfwaddr(ScsiReq*, uchar, uchar, uchar, uchar*);
-long SRtreserve(ScsiReq*, long);
-long SRtinfo(ScsiReq*, uchar, uchar*);
-long SRwtrack(ScsiReq*, void*, long, uchar, uchar);
-long SRmload(ScsiReq*, uchar);
-long SRfixation(ScsiReq*, uchar);
-
-long SReinitialise(ScsiReq*); /* CHANGER commands */
-long SRestatus(ScsiReq*, uchar, uchar*, int);
-long SRmmove(ScsiReq*, int, int, int, int);
-
-long SRrequest(ScsiReq*);
-int SRclose(ScsiReq*);
-int SRopenraw(ScsiReq*, char*);
-int SRopen(ScsiReq*, char*);
-
-void makesense(ScsiReq*);
-
-long umsrequest(struct Umsc*, ScsiPtr*, ScsiPtr*, int*);
-
-void scsidebug(int);
-
-char* scsierrmsg(int n);
diff --git a/sys/src/cmd/usb/disk/ums.h b/sys/src/cmd/usb/disk/ums.h
deleted file mode 100644
index 16f782a69..000000000
--- a/sys/src/cmd/usb/disk/ums.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * mass storage transport protocols and subclasses,
- * from usb mass storage class specification overview rev 1.2
- */
-
-typedef struct Umsc Umsc;
-typedef struct Ums Ums;
-typedef struct Cbw Cbw; /* command block wrapper */
-typedef struct Csw Csw; /* command status wrapper */
-typedef struct Part Part;
-
-enum
-{
- Protocbi = 0, /* control/bulk/interrupt; mainly floppies */
- Protocb = 1, /* " with no interrupt; mainly floppies */
- Protobulk = 0x50, /* bulk only */
-
- Subrbc = 1, /* reduced blk cmds */
- Subatapi = 2, /* cd/dvd using sff-8020i or mmc-2 cmd blks */
- Subqic = 3, /* QIC-157 tapes */
- Subufi = 4, /* floppy */
- Sub8070 = 5, /* removable media, atapi-like */
- Subscsi = 6, /* scsi transparent cmd set */
- Subisd200 = 7, /* ISD200 ATA */
- Subdev = 0xff, /* use device's value */
-
- Umsreset = 0xFF,
- Getmaxlun = 0xFE,
-
-// Maxlun = 256,
- Maxlun = 32,
-
- CMreset = 1,
-
- Pcmd = 0,
- Pdata,
- Pstatus,
-
- CbwLen = 31,
- CbwDataIn = 0x80,
- CbwDataOut = 0x00,
- CswLen = 13,
- CswOk = 0,
- CswFailed = 1,
- CswPhaseErr = 2,
-
- Maxparts = 16,
-};
-
-/*
- * corresponds to a lun.
- * these are ~600+Maxiosize bytes each; ScsiReq is not tiny.
- */
-
-struct Part
-{
- int id;
- int inuse;
- int vers;
- ulong mode;
- char *name;
- vlong offset; /* in lbsize units */
- vlong length; /* in lbsize units */
-};
-
-
-struct Umsc
-{
- ScsiReq;
- uvlong blocks;
- vlong capacity;
-
- /* from setup */
- char *bufp;
- long off; /* offset within a block */
- long nb; /* byte count */
-
- /* partitions */
- Part part[Maxparts];
-
- uchar rawcmd[10];
- uchar phase;
- char *inq;
- Ums *ums;
- Usbfs fs;
- char buf[Maxiosize];
-};
-
-struct Ums
-{
- QLock;
- Dev *dev;
- Dev *epin;
- Dev *epout;
- Umsc *lun;
- uchar maxlun;
- int seq;
- int nerrs;
- int wrongresidues;
-};
-
-/*
- * USB transparent SCSI devices
- */
-struct Cbw
-{
- char signature[4]; /* "USBC" */
- long tag;
- long datalen;
- uchar flags;
- uchar lun;
- uchar len;
- char command[16];
-};
-
-struct Csw
-{
- char signature[4]; /* "USBS" */
- long tag;
- long dataresidue;
- uchar status;
-};
-
-
-int diskmain(Dev*, int, char**);
diff --git a/sys/src/cmd/usb/ether/asix.c b/sys/src/cmd/usb/ether/asix.c
deleted file mode 100644
index d7087cc08..000000000
--- a/sys/src/cmd/usb/ether/asix.c
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Asix USB ether adapters
- * I got no documentation for it, thus the bits
- * come from other systems; it's likely this is
- * doing more than needed in some places and
- * less than required in others.
- */
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include <thread.h>
-#include "usb.h"
-#include "usbfs.h"
-#include "ether.h"
-
-enum
-{
-
- /* Asix commands */
- Cswmii = 0x06, /* set sw mii */
- Crmii = 0x07, /* read mii reg */
- Cwmii = 0x08, /* write mii reg */
- Chwmii = 0x0a, /* set hw mii */
- Creeprom = 0x0b, /* read eeprom */
- Cwdis = 0x0e, /* write disable */
- Cwena = 0x0d, /* write enable */
- Crrxctl = 0x0f, /* read rx ctl */
- Cwrxctl = 0x10, /* write rx ctl */
- Cwipg = 0x12, /* write ipg */
- Crmac = 0x13, /* read mac addr */
- Crphy = 0x19, /* read phy id */
- Cwmedium = 0x1b, /* write medium mode */
- Crgpio = 0x1e, /* read gpio */
- Cwgpio = 0x1f, /* write gpios */
- Creset = 0x20, /* reset */
- Cwphy = 0x22, /* select phy */
-
- /* reset codes */
- Rclear = 0x00,
- Rprte = 0x04,
- Rprl = 0x08,
- Riprl = 0x20,
- Rippd = 0x40,
-
- Gpiogpo1en = 0x04, /* gpio1 enable */,
- Gpiogpo1 = 0x08, /* gpio1 value */
- Gpiogpo2en = 0x10, /* gpio2 enable */
- Gpiogpo2 = 0x20, /* gpio2 value */
- Gpiorse = 0x80, /* gpio reload serial eeprom */
-
- Pmask = 0x1F,
- Pembed = 0x10, /* embedded phy */
-
- Mfd = 0x002, /* media */
- Mac = 0x004,
- Mrfc = 0x010,
- Mtfc = 0x020,
- Mjfe = 0x040,
- Mre = 0x100,
- Mps = 0x200,
- Mall772 = Mfd|Mrfc|Mtfc|Mps|Mac|Mre,
- Mall178 = Mps|Mfd|Mac|Mrfc|Mtfc|Mjfe|Mre,
-
- Ipgdflt = 0x15|0x0c|0x12, /* default ipg0, 1, 2 */
- Rxctlso = 0x80,
- Rxctlab = 0x08,
- Rxctlsep = 0x04,
- Rxctlamall = 0x02, /* all multicast */
- Rxctlprom = 0x01, /* promiscuous */
-
- /* MII */
- Miibmcr = 0x00, /* basic mode ctrl reg. */
- Bmcrreset = 0x8000, /* reset */
- Bmcranena = 0x1000, /* auto neg. enable */
- Bmcrar = 0x0200, /* announce restart */
-
- Miiad = 0x04, /* advertise reg. */
- Adcsma = 0x0001,
- Ad1000f = 0x0200,
- Ad1000h = 0x0100,
- Ad10h = 0x0020,
- Ad10f = 0x0040,
- Ad100h = 0x0080,
- Ad100f = 0x0100,
- Adpause = 0x0400,
- Adall = Ad10h|Ad10f|Ad100h|Ad100f,
-
- Miimctl = 0x14, /* marvell ctl */
- Mtxdly = 0x02,
- Mrxdly = 0x80,
- Mtxrxdly = 0x82,
-
- Miic1000 = 0x09,
-
-};
-
-static int
-asixset(Dev *d, int c, int v)
-{
- int r;
- int ec;
-
- r = Rh2d|Rvendor|Rdev;
- ec = usbcmd(d, r, c, v, 0, nil, 0);
- if(ec < 0)
- deprint(2, "%s: asixset %x %x: %r\n", argv0, c, v);
- return ec;
-}
-
-static int
-asixget(Dev *d, int c, uchar *buf, int l)
-{
- int r;
- int ec;
-
- r = Rd2h|Rvendor|Rdev;
- ec = usbcmd(d, r, c, 0, 0, buf, l);
- if(ec < 0)
- deprint(2, "%s: asixget %x: %r\n", argv0, c);
- return ec;
-}
-
-static int
-getgpio(Dev *d)
-{
- uchar c;
-
- if(asixget(d, Crgpio, &c, 1) < 0)
- return -1;
- return c;
-}
-
-static int
-getphy(Dev *d)
-{
- uchar buf[2];
-
- if(asixget(d, Crphy, buf, sizeof(buf)) < 0)
- return -1;
- deprint(2, "%s: phy addr %#ux\n", argv0, buf[1]);
- return buf[1];
-}
-
-static int
-getrxctl(Dev *d)
-{
- uchar buf[2];
- int r;
-
- memset(buf, 0, sizeof(buf));
- if(asixget(d, Crrxctl, buf, sizeof(buf)) < 0)
- return -1;
- r = GET2(buf);
- deprint(2, "%s: rxctl %#x\n", argv0, r);
- return r;
-}
-
-static int
-getmac(Dev *d, uchar buf[])
-{
- if(asixget(d, Crmac, buf, Eaddrlen) < 0)
- return -1;
- return Eaddrlen;
-}
-
-static int
-miiread(Dev *d, int phy, int reg)
-{
- int r;
- uchar v[2];
-
- r = Rd2h|Rvendor|Rdev;
- if(usbcmd(d, r, Crmii, phy, reg, v, 2) < 0){
- dprint(2, "%s: miiwrite: %r\n", argv0);
- return -1;
- }
- r = GET2(v);
- if(r == 0xFFFF)
- return -1;
- return r;
-}
-
-
-static int
-miiwrite(Dev *d, int phy, int reg, int val)
-{
- int r;
- uchar v[2];
-
- if(asixset(d, Cswmii, 0) < 0)
- return -1;
- r = Rh2d|Rvendor|Rdev;
- PUT2(v, val);
- if(usbcmd(d, r, Cwmii, phy, reg, v, 2) < 0){
- deprint(2, "%s: miiwrite: %#x %#x %r\n", argv0, reg, val);
- return -1;
- }
- if(asixset(d, Chwmii, 0) < 0)
- return -1;
- return 0;
-}
-
-static int
-eepromread(Dev *d, int i)
-{
- int r;
- int ec;
- uchar buf[2];
-
- r = Rd2h|Rvendor|Rdev;
- ec = usbcmd(d, r, Creeprom, i, 0, buf, sizeof(buf));
- if(ec < 0)
- deprint(2, "%s: eepromread %d: %r\n", argv0, i);
- ec = GET2(buf);
- deprint(2, "%s: eeprom %#x = %#x\n", argv0, i, ec);
- if(ec == 0xFFFF)
- ec = -1;
- return ec;
-}
-
-/*
- * No doc. we are doing what Linux does as closely
- * as we can.
- */
-static int
-ctlrinit(Ether *ether)
-{
- Dev *d;
- int i;
- int bmcr;
- int gpio;
- int ee17;
- int rc;
-
- d = ether->dev;
- switch(ether->cid){
- default:
- fprint(2, "%s: card known but not implemented\n", argv0);
- return -1;
-
- case A88178:
- deprint(2, "%s: setting up A88178\n", argv0);
- gpio = getgpio(d);
- if(gpio < 0)
- return -1;
- deprint(2, "%s: gpio sts %#x\n", argv0, gpio);
- asixset(d, Cwena, 0);
- ee17 = eepromread(d, 0x0017);
- asixset(d, Cwdis, 0);
- asixset(d, Cwgpio, Gpiorse|Gpiogpo1|Gpiogpo1en);
- if((ee17 >> 8) != 1){
- asixset(d, Cwgpio, 0x003c);
- asixset(d, Cwgpio, 0x001c);
- asixset(d, Cwgpio, 0x003c);
- }else{
- asixset(d, Cwgpio, Gpiogpo1en);
- asixset(d, Cwgpio, Gpiogpo1|Gpiogpo1en);
- }
- asixset(d, Creset, Rclear);
- sleep(150);
- asixset(d, Creset, Rippd|Rprl);
- sleep(150);
- asixset(d, Cwrxctl, 0);
- if(getmac(d, ether->addr) < 0)
- return -1;
- ether->phy = getphy(d);
- if(ee17 < 0 || (ee17 & 0x7) == 0){
- miiwrite(d, ether->phy, Miimctl, Mtxrxdly);
- sleep(60);
- }
- miiwrite(d, ether->phy, Miibmcr, Bmcrreset|Bmcranena);
- miiwrite(d, ether->phy, Miiad, Adall|Adcsma|Adpause);
- miiwrite(d, ether->phy, Miic1000, Ad1000f);
- bmcr = miiread(d, ether->phy, Miibmcr);
- if((bmcr & Bmcranena) != 0){
- bmcr |= Bmcrar;
- miiwrite(d, ether->phy, Miibmcr, bmcr);
- }
- asixset(d, Cwmedium, Mall178);
- asixset(d, Cwrxctl, Rxctlso|Rxctlab);
- break;
-
- case A88772:
- deprint(2, "%s: setting up A88772\n", argv0);
- if(asixset(d, Cwgpio, Gpiorse|Gpiogpo2|Gpiogpo2en) < 0)
- return -1;
- ether->phy = getphy(d);
- dprint(2, "%s: phy %#x\n", argv0, ether->phy);
- if((ether->phy & Pmask) == Pembed){
- /* embedded 10/100 ethernet */
- rc = asixset(d, Cwphy, 1);
- }else
- rc = asixset(d, Cwphy, 0);
- if(rc < 0)
- return -1;
- if(asixset(d, Creset, Rippd|Rprl) < 0)
- return -1;
- sleep(150);
- if((ether->phy & Pmask) == Pembed)
- rc = asixset(d, Creset, Riprl);
- else
- rc = asixset(d, Creset, Rprte);
- if(rc < 0)
- return -1;
- sleep(150);
- rc = getrxctl(d);
- deprint(2, "%s: rxctl is %#x\n", argv0, rc);
- if(asixset(d, Cwrxctl, 0) < 0)
- return -1;
- if(getmac(d, ether->addr) < 0)
- return -1;
-
-
- if(asixset(d, Creset, Rprl) < 0)
- return -1;
- sleep(150);
- if(asixset(d, Creset, Riprl|Rprl) < 0)
- return -1;
- sleep(150);
-
- miiwrite(d, ether->phy, Miibmcr, Bmcrreset);
- miiwrite(d, ether->phy, Miiad, Adall|Adcsma);
- bmcr = miiread(d, ether->phy, Miibmcr);
- if((bmcr & Bmcranena) != 0){
- bmcr |= Bmcrar;
- miiwrite(d, ether->phy, Miibmcr, bmcr);
- }
- if(asixset(d, Cwmedium, Mall772) < 0)
- return -1;
- if(asixset(d, Cwipg, Ipgdflt) < 0)
- return -1;
- if(asixset(d, Cwrxctl, Rxctlso|Rxctlab) < 0)
- return -1;
- deprint(2, "%s: final rxctl: %#x\n", argv0, getrxctl(d));
- break;
- }
-
- if(etherdebug){
- fprint(2, "%s: ether: phy %#x addr ", argv0, ether->phy);
- for(i = 0; i < sizeof(ether->addr); i++)
- fprint(2, "%02x", ether->addr[i]);
- fprint(2, "\n");
- }
- return 0;
-}
-
-
-static long
-asixbread(Ether *e, Buf *bp)
-{
- ulong nr;
- ulong hd;
- Buf *rbp;
-
- rbp = e->aux;
- if(rbp == nil || rbp->ndata < 4){
- rbp->rp = rbp->data;
- rbp->ndata = read(e->epin->dfd, rbp->rp, sizeof(bp->data));
- if(rbp->ndata < 0)
- return -1;
- }
- if(rbp->ndata < 4){
- werrstr("short frame");
- deprint(2, "%s: asixbread got %d bytes\n", argv0, rbp->ndata);
- rbp->ndata = 0;
- return 0;
- }
- hd = GET4(rbp->rp);
- nr = hd & 0xFFFF;
- hd = (hd>>16) & 0xFFFF;
- if(nr != (~hd & 0xFFFF)){
- if(0)deprint(2, "%s: asixread: bad header %#ulx %#ulx\n",
- argv0, nr, (~hd & 0xFFFF));
- werrstr("bad usb packet header");
- rbp->ndata = 0;
- return 0;
- }
- rbp->rp += 4;
- if(nr < 6 || nr > Epktlen){
- if(nr < 6)
- werrstr("short frame");
- else
- werrstr("long frame");
- deprint(2, "%s: asixbread %r (%ld)\n", argv0, nr);
- rbp->ndata = 0;
- return 0;
- }
- bp->rp = bp->data + Hdrsize;
- memmove(bp->rp, rbp->rp, nr);
- bp->ndata = nr;
- rbp->rp += 4 + nr;
- rbp->ndata -= (4 + nr);
- return bp->ndata;
-}
-
-static long
-asixbwrite(Ether *e, Buf *bp)
-{
- ulong len;
- long n;
-
- deprint(2, "%s: asixbwrite %d bytes\n", argv0, bp->ndata);
- assert(bp->rp - bp->data >= Hdrsize);
- bp->ndata &= 0xFFFF;
- len = (0xFFFF0000 & ~(bp->ndata<<16)) | bp->ndata;
- bp->rp -= 4;
- PUT4(bp->rp, len);
- bp->ndata += 4;
- if((bp->ndata % e->epout->maxpkt) == 0){
- PUT4(bp->rp+bp->ndata, 0xFFFF0000);
- bp->ndata += 4;
- }
- n = write(e->epout->dfd, bp->rp, bp->ndata);
- deprint(2, "%s: asixbwrite wrote %ld bytes\n", argv0, n);
- if(n <= 0)
- return n;
- return n;
-}
-
-static int
-asixpromiscuous(Ether *e, int on)
-{
- int rxctl;
-
- deprint(2, "%s: aixprompiscuous %d\n", argv0, on);
- rxctl = getrxctl(e->dev);
- if(on != 0)
- rxctl |= Rxctlprom;
- else
- rxctl &= ~Rxctlprom;
- return asixset(e->dev, Cwrxctl, rxctl);
-}
-
-static int
-asixmulticast(Ether *e, uchar *addr, int on)
-{
- int rxctl;
-
- USED(addr);
- USED(on);
- /* BUG: should write multicast filter */
- rxctl = getrxctl(e->dev);
- if(e->nmcasts != 0)
- rxctl |= Rxctlamall;
- else
- rxctl &= ~Rxctlamall;
- deprint(2, "%s: asixmulticast %d\n", argv0, e->nmcasts);
- return asixset(e->dev, Cwrxctl, rxctl);
-}
-
-static void
-asixfree(Ether *ether)
-{
- deprint(2, "%s: aixfree %#p\n", argv0, ether);
- free(ether->aux);
- ether->aux = nil;
-}
-
-int
-asixreset(Ether *ether)
-{
- Cinfo *ip;
- Dev *dev;
-
- dev = ether->dev;
- for(ip = cinfo; ip->vid != 0; ip++)
- if(ip->vid == dev->usb->vid && ip->did == dev->usb->did){
- ether->cid = ip->cid;
- if(ctlrinit(ether) < 0){
- deprint(2, "%s: init failed: %r\n", argv0);
- return -1;
- }
- deprint(2, "%s: asix reset done\n", argv0);
- ether->aux = emallocz(sizeof(Buf), 1);
- ether->bread = asixbread;
- ether->bwrite = asixbwrite;
- ether->free = asixfree;
- ether->promiscuous = asixpromiscuous;
- ether->multicast = asixmulticast;
- ether->mbps = 100; /* BUG */
- return 0;
- }
- return -1;
-}
diff --git a/sys/src/cmd/usb/ether/cdc.c b/sys/src/cmd/usb/ether/cdc.c
deleted file mode 100644
index aea54e707..000000000
--- a/sys/src/cmd/usb/ether/cdc.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Standard usb ethernet communications device.
- */
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include <thread.h>
-#include "usb.h"
-#include "usbfs.h"
-#include "ether.h"
-
-static int
-okclass(Iface *iface)
-{
- return Class(iface->csp) == Clcomms && Subclass(iface->csp) == Scether;
-}
-
-static int
-getmac(Ether *ether)
-{
- int i;
- Usbdev *ud;
- uchar *b;
- Desc *dd;
- char *mac;
-
- ud = ether->dev->usb;
-
- for(i = 0; i < nelem(ud->ddesc); i++)
- if((dd = ud->ddesc[i]) != nil && okclass(dd->iface)){
- b = (uchar*)&dd->data;
- if(b[1] == Dfunction && b[2] == Fnether){
- mac = loaddevstr(ether->dev, b[3]);
- if(mac != nil && strlen(mac) != 12){
- free(mac);
- mac = nil;
- }
- if(mac != nil){
- parseaddr(ether->addr, mac);
- free(mac);
- return 0;
- }
- }
- }
- return -1;
-}
-
-int
-cdcreset(Ether *ether)
-{
- /*
- * Assume that all communication devices are going to
- * be std. ethernet communication devices. Specific controllers
- * must have been probed first.
- * NB: This ignores unions.
- */
- if(ether->dev->usb->class == Clcomms)
- return getmac(ether);
- return -1;
-}
diff --git a/sys/src/cmd/usb/ether/ether.c b/sys/src/cmd/usb/ether/ether.c
deleted file mode 100644
index cfc368416..000000000
--- a/sys/src/cmd/usb/ether/ether.c
+++ /dev/null
@@ -1,1185 +0,0 @@
-/*
- * usb/ether - usb ethernet adapter.
- * BUG: This should use /dev/etherfile to
- * use the kernel ether device code.
- */
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include <thread.h>
-#include "usb.h"
-#include "usbfs.h"
-#include "ether.h"
-
-typedef struct Dirtab Dirtab;
-
-enum
-{
- /* Qids. Maintain order (relative to dirtabs structs) */
- Qroot = 0,
- Qclone,
- Qaddr,
- Qifstats,
- Qstats,
- Qndir,
- Qndata,
- Qnctl,
- Qnifstats,
- Qnstats,
- Qntype,
- Qmax,
-};
-
-struct Dirtab
-{
- char *name;
- int qid;
- int mode;
-};
-
-typedef int (*Resetf)(Ether*);
-
-/*
- * Controllers by vid/vid. Used to locate
- * specific adapters that do not implement cdc ethernet
- * Keep null terminated.
- */
-Cinfo cinfo[] =
-{
- /* Asix controllers.
- * Only A88178 and A881772 are implemented.
- * Others are easy to add by borrowing code
- * from other systems.
- */
- {0x077b, 0x2226, A8817x},
- {0x0b95, 0x1720, A8817x},
- {0x0557, 0x2009, A8817x},
- {0x0411, 0x003d, A8817x},
- {0x0411, 0x006e, A88178},
- {0x6189, 0x182d, A8817x},
- {0x07aa, 0x0017, A8817x},
- {0x1189, 0x0893, A8817x},
- {0x1631, 0x6200, A8817x},
- {0x04f1, 0x3008, A8817x},
- {0x0b95, 0x1780, A88178}, /* Geoff */
- {0x13b1, 0x0018, A88772},
- {0x1557, 0x7720, A88772},
- {0x07d1, 0x3c05, A88772},
- {0x2001, 0x3c05, A88772},
- {0x1737, 0x0039, A88178},
- {0x050d, 0x5055, A88178},
- {0x05ac, 0x1402, A88772}, /* Apple */
- {0x0b95, 0x772a, A88772},
- {0x14ea, 0xab11, A88178},
- {0x0db0, 0xa877, A88772},
- {0, 0, 0},
-};
-
-/*
- * Each etherU%d is the root of our file system,
- * which is added to the usb root directory. We only
- * have to concern ourselfs with each /etherU%d subtree.
- *
- * NB: Maintain order in dirtabs, relative to the Qids enum.
- */
-
-static Dirtab rootdirtab[] =
-{
- "/", Qroot, DMDIR|0555, /* etherU%d */
- "clone", Qclone, 0666,
- "addr", Qaddr, 0444,
- "ifstats", Qifstats, 0444,
- "stats", Qstats, 0444,
- /* one dir per connection here */
- nil, 0, 0,
-};
-
-static Dirtab conndirtab[] =
-{
- "%d", Qndir, DMDIR|0555,
- "data", Qndata, 0666,
- "ctl", Qnctl, 0666,
- "ifstats", Qnifstats, 0444,
- "stats", Qnstats, 0444,
- "type", Qntype, 0444,
- nil, 0,
-};
-
-int etherdebug;
-
-Resetf ethers[] =
-{
- asixreset,
- cdcreset, /* keep last */
-};
-
-static int
-qtype(vlong q)
-{
- return q&0xFF;
-}
-
-static int
-qnum(vlong q)
-{
- return (q >> 8) & 0xFFFFFF;
-}
-
-static uvlong
-mkqid(int n, int t)
-{
- uvlong q;
-
- q = (n&0xFFFFFF) << 8 | t&0xFF;
- return q;
-}
-
-static void
-freebuf(Ether *e, Buf *bp)
-{
- if(0)deprint(2, "%s: freebuf %#p\n", argv0, bp);
- if(bp != nil){
- qlock(e);
- e->nbufs--;
- qunlock(e);
- sendp(e->bc, bp);
- }
-}
-
-static Buf*
-allocbuf(Ether *e)
-{
- Buf *bp;
-
- bp = nbrecvp(e->bc);
- if(bp == nil){
- qlock(e);
- if(e->nabufs < Nconns){
- bp = emallocz(sizeof(Buf), 1);
- e->nabufs++;
- setmalloctag(bp, getcallerpc(&e));
- deprint(2, "%s: %d buffers\n", argv0, e->nabufs);
- }
- qunlock(e);
- }
- if(bp == nil)
- bp = recvp(e->bc);
- bp->rp = bp->data + Hdrsize;
- bp->ndata = 0;
- if(0)deprint(2, "%s: allocbuf %#p\n", argv0, bp);
- qlock(e);
- e->nbufs++;
- qunlock(e);
- return bp;
-}
-
-static Conn*
-newconn(Ether *e)
-{
- int i;
- Conn *c;
-
- qlock(e);
- for(i = 0; i < nelem(e->conns); i++){
- c = e->conns[i];
- if(c == nil || c->ref == 0){
- if(c == nil){
- c = emallocz(sizeof(Conn), 1);
- c->rc = chancreate(sizeof(Buf*), 2);
- c->nb = i;
- }
- c->ref = 1;
- if(i == e->nconns)
- e->nconns++;
- e->conns[i] = c;
- deprint(2, "%s: newconn %d\n", argv0, i);
- qunlock(e);
- return c;
- }
- }
- qunlock(e);
- return nil;
-}
-
-static char*
-seprintaddr(char *s, char *se, uchar *addr)
-{
- int i;
-
- for(i = 0; i < Eaddrlen; i++)
- s = seprint(s, se, "%02x", addr[i]);
- return s;
-}
-
-void
-dumpframe(char *tag, void *p, int n)
-{
- Etherpkt *ep;
- char buf[128];
- char *s, *se;
- int i;
-
- ep = p;
- if(n < Eaddrlen * 2 + 2){
- fprint(2, "short packet (%d bytes)\n", n);
- return;
- }
- se = buf+sizeof(buf);
- s = seprint(buf, se, "%s [%d]: ", tag, n);
- s = seprintaddr(s, se, ep->s);
- s = seprint(s, se, " -> ");
- s = seprintaddr(s, se, ep->d);
- s = seprint(s, se, " type 0x%02ux%02ux ", ep->type[0], ep->type[1]);
- n -= Eaddrlen * 2 + 2;
- for(i = 0; i < n && i < 16; i++)
- s = seprint(s, se, "%02x", ep->data[i]);
- if(n >= 16)
- fprint(2, "%s...\n", buf);
- else
- fprint(2, "%s\n", buf);
-}
-
-static char*
-seprintstats(char *s, char *se, Ether *e)
-{
- qlock(e);
- s = seprint(s, se, "in: %ld\n", e->nin);
- s = seprint(s, se, "out: %ld\n", e->nout);
- s = seprint(s, se, "input errs: %ld\n", e->nierrs);
- s = seprint(s, se, "output errs: %ld\n", e->noerrs);
- s = seprint(s, se, "mbps: %d\n", e->mbps);
- s = seprint(s, se, "prom: %ld\n", e->prom.ref);
- s = seprint(s, se, "addr: ");
- s = seprintaddr(s, se, e->addr);
- s = seprint(s, se, "\n");
- qunlock(e);
- return s;
-}
-
-static char*
-seprintifstats(char *s, char *se, Ether *e)
-{
- int i;
- Conn *c;
-
- qlock(e);
- s = seprint(s, se, "ctlr id: %#x\n", e->cid);
- s = seprint(s, se, "phy: %#x\n", e->phy);
- s = seprint(s, se, "exiting: %s\n", e->exiting ? "y" : "n");
- s = seprint(s, se, "conns: %d\n", e->nconns);
- s = seprint(s, se, "allocated bufs: %d\n", e->nabufs);
- s = seprint(s, se, "used bufs: %d\n", e->nbufs);
- for(i = 0; i < nelem(e->conns); i++){
- c = e->conns[i];
- if(c == nil)
- continue;
- if(c->ref == 0)
- s = seprint(s, se, "c[%d]: free\n", i);
- else{
- s = seprint(s, se, "c[%d]: refs %ld t %#x h %d p %d\n",
- c->nb, c->ref, c->type, c->headersonly, c->prom);
- }
- }
- qunlock(e);
- return s;
-}
-
-static void
-etherdump(Ether *e)
-{
- char buf[256];
-
- if(etherdebug == 0)
- return;
- seprintifstats(buf, buf+sizeof(buf), e);
- fprint(2, "%s: ether %#p:\n%s\n", argv0, e, buf);
-}
-
-static Conn*
-getconn(Ether *e, int i, int idleok)
-{
- Conn *c;
-
- qlock(e);
- if(i < 0 || i >= e->nconns)
- c = nil;
- else{
- c = e->conns[i];
- if(idleok == 0 && c != nil && c->ref == 0)
- c = nil;
- }
- qunlock(e);
- return c;
-}
-
-static void
-filldir(Usbfs *fs, Dir *d, Dirtab *tab, int cn)
-{
- d->qid.path = mkqid(cn, tab->qid);
- d->qid.path |= fs->qid;
- d->mode = tab->mode;
- if((d->mode & DMDIR) != 0)
- d->qid.type = QTDIR;
- else
- d->qid.type = QTFILE;
- if(tab->qid == Qndir)
- snprint(d->name, Namesz, "%d", cn);
- else
- d->name = tab->name;
-}
-
-static int
-rootdirgen(Usbfs *fs, Qid, int i, Dir *d, void *)
-{
- Ether *e;
- Dirtab *tab;
- int cn;
-
- e = fs->aux;
- i++; /* skip root */
- cn = 0;
- if(i < nelem(rootdirtab) - 1) /* null terminated */
- tab = &rootdirtab[i];
- else{
- cn = i - nelem(rootdirtab) + 1;
- if(cn < e->nconns)
- tab = &conndirtab[0];
- else
- return -1;
- }
- filldir(fs, d, tab, cn);
- return 0;
-}
-
-static int
-conndirgen(Usbfs *fs, Qid q, int i, Dir *d, void *)
-{
- Dirtab *tab;
-
- i++; /* skip root */
- if(i < nelem(conndirtab) - 1) /* null terminated */
- tab = &conndirtab[i];
- else
- return -1;
- filldir(fs, d, tab, qnum(q.path));
- return 0;
-}
-
-static int
-fswalk(Usbfs *fs, Fid *fid, char *name)
-{
- int cn, i;
- char *es;
- Dirtab *tab;
- Ether *e;
- Qid qid;
-
- e = fs->aux;
- qid = fid->qid;
- qid.path &= ~fs->qid;
- if((qid.type & QTDIR) == 0){
- werrstr("walk in non-directory");
- return -1;
- }
-
- if(strcmp(name, "..") == 0){
- /* must be /etherU%d; i.e. our root dir. */
- fid->qid.path = mkqid(0, Qroot) | fs->qid;
- fid->qid.vers = 0;
- fid->qid.type = QTDIR;
- return 0;
- }
- switch(qtype(qid.path)){
- case Qroot:
- if(name[0] >= '0' && name[0] <= '9'){
- es = name;
- cn = strtoul(name, &es, 10);
- if(cn >= e->nconns || *es != 0){
- werrstr(Enotfound);
- return -1;
- }
- fid->qid.path = mkqid(cn, Qndir) | fs->qid;
- fid->qid.vers = 0;
- return 0;
- }
- /* fall */
- case Qndir:
- if(qtype(qid.path) == Qroot)
- tab = rootdirtab;
- else
- tab = conndirtab;
- cn = qnum(qid.path);
- for(i = 0; tab[i].name != nil; tab++)
- if(strcmp(tab[i].name, name) == 0){
- fid->qid.path = mkqid(cn, tab[i].qid)|fs->qid;
- fid->qid.vers = 0;
- if((tab[i].mode & DMDIR) != 0)
- fid->qid.type = QTDIR;
- else
- fid->qid.type = QTFILE;
- return 0;
- }
- break;
- default:
- sysfatal("usb: ether: fswalk bug");
- }
- return -1;
-}
-
-static Dirtab*
-qdirtab(vlong q)
-{
- int i, qt;
- Dirtab *tab;
-
- qt = qtype(q);
- if(qt < nelem(rootdirtab) - 1){ /* null terminated */
- tab = rootdirtab;
- i = qt;
- }else{
- tab = conndirtab;
- i = qt - (nelem(rootdirtab) - 1);
- assert(i < nelem(conndirtab) - 1);
- }
- return &tab[i];
-}
-
-static int
-fsstat(Usbfs *fs, Qid qid, Dir *d)
-{
- filldir(fs, d, qdirtab(qid.path), qnum(qid.path));
- return 0;
-}
-
-static int
-fsopen(Usbfs *fs, Fid *fid, int omode)
-{
- int qt;
- vlong qid;
- Conn *c;
- Dirtab *tab;
- Ether *e;
-
- qid = fid->qid.path & ~fs->qid;
- e = fs->aux;
- qt = qtype(qid);
- tab = qdirtab(qid);
- omode &= 3;
- if(omode != OREAD && (tab->mode&0222) == 0){
- werrstr(Eperm);
- return -1;
- }
- switch(qt){
- case Qclone:
- c = newconn(e);
- if(c == nil){
- werrstr("no more connections");
- return -1;
- }
- fid->qid.type = QTFILE;
- fid->qid.path = mkqid(c->nb, Qnctl)|fs->qid;
- fid->qid.vers = 0;
- break;
- case Qndata:
- case Qnctl:
- case Qnifstats:
- case Qnstats:
- case Qntype:
- c = getconn(e, qnum(qid), 1);
- if(c == nil)
- sysfatal("usb: ether: fsopen bug");
- incref(c);
- break;
- }
- etherdump(e);
- return 0;
-}
-
-static int
-prom(Ether *e, int set)
-{
- if(e->promiscuous != nil)
- return e->promiscuous(e, set);
- return 0;
-}
-
-static void
-fsclunk(Usbfs *fs, Fid *fid)
-{
- int qt;
- vlong qid;
- Buf *bp;
- Conn *c;
- Ether *e;
-
- e = fs->aux;
- qid = fid->qid.path & ~fs->qid;
- qt = qtype(qid);
- switch(qt){
- case Qndata:
- case Qnctl:
- case Qnifstats:
- case Qnstats:
- case Qntype:
- if(fid->omode != ONONE){
- c = getconn(e, qnum(qid), 0);
- if(c == nil)
- sysfatal("usb: ether: fsopen bug");
- if(decref(c) == 0){
- while((bp = nbrecvp(c->rc)) != nil)
- freebuf(e, bp);
- qlock(e);
- if(c->prom != 0)
- if(decref(&e->prom) == 0)
- prom(e, 0);
- c->prom = c->type = 0;
- qunlock(e);
- }
- }
- break;
- }
- etherdump(e);
-}
-
-int
-parseaddr(uchar *m, char *s)
-{
- int i, n;
- uchar v;
-
- if(strlen(s) < 12)
- return -1;
- if(strlen(s) > 12 && strlen(s) < 17)
- return -1;
- for(i = n = 0; i < strlen(s); i++){
- if(s[i] == ':')
- continue;
- if(s[i] >= 'A' && s[i] <= 'F')
- v = 10 + s[i] - 'A';
- else if(s[i] >= 'a' && s[i] <= 'f')
- v = 10 + s[i] - 'a';
- else if(s[i] >= '0' && s[i] <= '9')
- v = s[i] - '0';
- else
- return -1;
- if(n&1)
- m[n/2] |= v;
- else
- m[n/2] = v<<4;
- n++;
- }
- return 0;
-}
-
-static long
-fsread(Usbfs *fs, Fid *fid, void *data, long count, vlong offset)
-{
- int cn, qt;
- char *s, *se;
- char buf[2048]; /* keep this large for ifstats */
- Buf *bp;
- Conn *c;
- Ether *e;
- Qid q;
-
- q = fid->qid;
- q.path &= ~fs->qid;
- e = fs->aux;
- s = buf;
- se = buf+sizeof(buf);
- qt = qtype(q.path);
- cn = qnum(q.path);
- switch(qt){
- case Qroot:
- count = usbdirread(fs, q, data, count, offset, rootdirgen, nil);
- break;
- case Qaddr:
- s = seprintaddr(s, se, e->addr);
- count = usbreadbuf(data, count, offset, buf, s - buf);
- break;
- case Qnifstats:
- /* BUG */
- case Qifstats:
- s = seprintifstats(s, se, e);
- if(e->seprintstats != nil)
- s = e->seprintstats(s, se, e);
- count = usbreadbuf(data, count, offset, buf, s - buf);
- break;
- case Qnstats:
- /* BUG */
- case Qstats:
- s = seprintstats(s, se, e);
- count = usbreadbuf(data, count, offset, buf, s - buf);
- break;
-
- case Qndir:
- count = usbdirread(fs, q, data, count, offset, conndirgen, nil);
- break;
- case Qndata:
- c = getconn(e, cn, 0);
- if(c == nil){
- werrstr(Eio);
- return -1;
- }
- bp = recvp(c->rc);
- if(bp == nil)
- return -1;
- if(etherdebug > 1)
- dumpframe("etherin", bp->rp, bp->ndata);
- count = usbreadbuf(data, count, 0LL, bp->rp, bp->ndata);
- freebuf(e, bp);
- break;
- case Qnctl:
- s = seprint(s, se, "%11d ", cn);
- count = usbreadbuf(data, count, offset, buf, s - buf);
- break;
- case Qntype:
- c = getconn(e, cn, 0);
- if(c == nil)
- s = seprint(s, se, "%11d ", 0);
- else
- s = seprint(s, se, "%11d ", c->type);
- count = usbreadbuf(data, count, offset, buf, s - buf);
- break;
- default:
- sysfatal("usb: ether: fsread bug");
- }
- return count;
-}
-
-static int
-typeinuse(Ether *e, int t)
-{
- int i;
-
- for(i = 0; i < e->nconns; i++)
- if(e->conns[i]->ref > 0 && e->conns[i]->type == t)
- return 1;
- return 0;
-}
-
-static int
-isloopback(Ether *e, Buf *)
-{
- return e->prom.ref > 0; /* BUG: also loopbacks and broadcasts */
-}
-
-static int
-etherctl(Ether *e, Conn *c, char *buf)
-{
- uchar addr[Eaddrlen];
- int t;
-
- deprint(2, "%s: etherctl: %s\n", argv0, buf);
- if(strncmp(buf, "connect ", 8) == 0){
- t = atoi(buf+8);
- qlock(e);
- if(typeinuse(e, t)){
- werrstr("type already in use");
- qunlock(e);
- return -1;
- }
- c->type = atoi(buf+8);
- qunlock(e);
- return 0;
- }
- if(strncmp(buf, "nonblocking", 11) == 0){
- if(buf[11] == '\n' || buf[11] == 0)
- e->nblock = 1;
- else
- e->nblock = atoi(buf + 12);
- deprint(2, "%s: nblock %d\n", argv0, e->nblock);
- return 0;
- }
- if(strncmp(buf, "promiscuous", 11) == 0){
- if(c->prom == 0)
- incref(&e->prom);
- c->prom = 1;
- return prom(e, 1);
- }
- if(strncmp(buf, "headersonly", 11) == 0){
- c->headersonly = 1;
- return 0;
- }
- if(strncmp(buf, "addmulti ", 9) == 0 || strncmp(buf, "remmulti ", 9) == 0){
- if(parseaddr(addr, buf+9) < 0){
- werrstr("bad address");
- return -1;
- }
- if(e->multicast == nil)
- return 0;
- if(strncmp(buf, "add", 3) == 0){
- e->nmcasts++;
- return e->multicast(e, addr, 1);
- }else{
- e->nmcasts--;
- return e->multicast(e, addr, 0);
- }
- }
-
- if(e->ctl != nil)
- return e->ctl(e, buf);
- werrstr(Ebadctl);
- return -1;
-}
-
-static long
-etherbread(Ether *e, Buf *bp)
-{
- deprint(2, "%s: etherbread\n", argv0);
- bp->rp = bp->data + Hdrsize;
- bp->ndata = -1;
- bp->ndata = read(e->epin->dfd, bp->rp, sizeof(bp->data)-Hdrsize);
- if(bp->ndata < 0){
- deprint(2, "%s: etherbread: %r\n", argv0); /* keep { and } */
- }else
- deprint(2, "%s: etherbread: got %d bytes\n", argv0, bp->ndata);
- return bp->ndata;
-}
-
-static long
-etherbwrite(Ether *e, Buf *bp)
-{
- long n;
-
- deprint(2, "%s: etherbwrite %d bytes\n", argv0, bp->ndata);
- n = write(e->epout->dfd, bp->rp, bp->ndata);
- if(n < 0){
- deprint(2, "%s: etherbwrite: %r\n", argv0); /* keep { and } */
- }else
- deprint(2, "%s: etherbwrite wrote %ld bytes\n", argv0, n);
- if(n <= 0)
- return n;
- if((bp->ndata % e->epout->maxpkt) == 0){
- deprint(2, "%s: short pkt write\n", argv0);
- write(e->epout->dfd, "", 1);
- }
- return n;
-}
-
-static long
-fswrite(Usbfs *fs, Fid *fid, void *data, long count, vlong)
-{
- int cn, qt;
- char buf[128];
- Buf *bp;
- Conn *c;
- Ether *e;
- Qid q;
-
- q = fid->qid;
- q.path &= ~fs->qid;
- e = fs->aux;
- qt = qtype(q.path);
- cn = qnum(q.path);
- switch(qt){
- case Qndata:
- c = getconn(e, cn, 0);
- if(c == nil){
- werrstr(Eio);
- return -1;
- }
- bp = allocbuf(e);
- if(count > sizeof(bp->data)-Hdrsize)
- count = sizeof(bp->data)-Hdrsize;
- memmove(bp->rp, data, count);
- bp->ndata = count;
- if(etherdebug > 1)
- dumpframe("etherout", bp->rp, bp->ndata);
- if(e->nblock == 0)
- sendp(e->wc, bp);
- else if(nbsendp(e->wc, bp) == 0){
- deprint(2, "%s: (out) packet lost\n", argv0);
- freebuf(e, bp);
- }
- break;
- case Qnctl:
- c = getconn(e, cn, 0);
- if(c == nil){
- werrstr(Eio);
- return -1;
- }
- if(count > sizeof(buf) - 1)
- count = sizeof(buf) - 1;
- memmove(buf, data, count);
- buf[count] = 0;
- if(etherctl(e, c, buf) < 0)
- return -1;
- break;
- default:
- sysfatal("usb: ether: fsread bug");
- }
- return count;
-}
-
-static int
-openeps(Ether *e, int epin, int epout)
-{
- e->epin = openep(e->dev, epin);
- if(e->epin == nil){
- fprint(2, "ether: in: openep %d: %r\n", epin);
- return -1;
- }
- if(epout == epin){
- incref(e->epin);
- e->epout = e->epin;
- }else
- e->epout = openep(e->dev, epout);
- if(e->epout == nil){
- fprint(2, "ether: out: openep %d: %r\n", epout);
- closedev(e->epin);
- return -1;
- }
- if(e->epin == e->epout)
- opendevdata(e->epin, ORDWR);
- else{
- opendevdata(e->epin, OREAD);
- opendevdata(e->epout, OWRITE);
- }
- if(e->epin->dfd < 0 || e->epout->dfd < 0){
- fprint(2, "ether: open i/o ep data: %r\n");
- closedev(e->epin);
- closedev(e->epout);
- return -1;
- }
- dprint(2, "ether: ep in %s maxpkt %d; ep out %s maxpkt %d\n",
- e->epin->dir, e->epin->maxpkt, e->epout->dir, e->epout->maxpkt);
-
- /* time outs are not activated for I/O endpoints */
-
- if(usbdebug > 2 || etherdebug > 2){
- devctl(e->epin, "debug 1");
- devctl(e->epout, "debug 1");
- devctl(e->dev, "debug 1");
- }
-
- return 0;
-}
-
-static int
-usage(void)
-{
- werrstr("usage: usb/ether [-d] [-N nb]");
- return -1;
-}
-
-static Usbfs etherfs = {
- .walk = fswalk,
- .open = fsopen,
- .read = fsread,
- .write = fswrite,
- .stat = fsstat,
- .clunk = fsclunk,
-};
-
-static void
-shutdownchan(Channel *c)
-{
- Buf *bp;
-
- while((bp=nbrecvp(c)) != nil)
- free(bp);
- chanfree(c);
-}
-
-static void
-etherfree(Ether *e)
-{
- int i;
- Buf *bp;
-
- if(e->free != nil)
- e->free(e);
- closedev(e->epin);
- closedev(e->epout);
- if(e->rc == nil){ /* not really started */
- free(e);
- return;
- }
- for(i = 0; i < e->nconns; i++)
- if(e->conns[i] != nil){
- while((bp = nbrecvp(e->conns[i]->rc)) != nil)
- free(bp);
- chanfree(e->conns[i]->rc);
- free(e->conns[i]);
- }
- shutdownchan(e->bc);
- shutdownchan(e->rc);
- shutdownchan(e->wc);
- e->epin = e->epout = nil;
- devctl(e->dev, "detach");
- free(e);
-}
-
-static void
-etherdevfree(void *a)
-{
- Ether *e = a;
-
- if(e != nil)
- etherfree(e);
-}
-
-/* must return 1 if c wants bp; 0 if not */
-static int
-cwantsbp(Conn *c, Buf *bp)
-{
- if(c->ref != 0 && (c->prom != 0 || c->type < 0 || c->type == bp->type))
- return 1;
- return 0;
-}
-
-static void
-etherwriteproc(void *a)
-{
- Ether *e = a;
- Buf *bp;
- Channel *wc;
-
- wc = e->wc;
- while(e->exiting == 0){
- bp = recvp(wc);
- if(bp == nil || e->exiting != 0){
- free(bp);
- break;
- }
- e->nout++;
- if(e->bwrite(e, bp) < 0)
- e->noerrs++;
- if(isloopback(e, bp) && e->exiting == 0)
- sendp(e->rc, bp); /* send to input queue */
- else
- freebuf(e, bp);
- }
- deprint(2, "%s: writeproc exiting\n", argv0);
- closedev(e->dev);
-}
-
-static void
-setbuftype(Buf *bp)
-{
- uchar *p;
-
- bp->type = 0;
- if(bp->ndata >= Ehdrsize){
- p = bp->rp + Eaddrlen*2;
- bp->type = p[0]<<8 | p[1];
- }
-}
-
-static void
-etherexiting(Ether *e)
-{
- devctl(e->dev, "detach");
- e->exiting = 1;
- close(e->epin->dfd);
- e->epin->dfd = -1;
- close(e->epout->dfd);
- e->epout->dfd = -1;
- nbsend(e->wc, nil);
-}
-
-static void
-etherreadproc(void *a)
-{
- int i, n, nwants;
- Buf *bp, *dbp;
- Ether *e = a;
-
- while(e->exiting == 0){
- bp = nbrecvp(e->rc);
- if(bp == nil){
- bp = allocbuf(e); /* leak() may think we leak */
- if(e->bread(e, bp) < 0){
- freebuf(e, bp);
- break;
- }
- if(bp->ndata == 0){
- /* may be a short packet; continue */
- if(0)dprint(2, "%s: read: short\n", argv0);
- freebuf(e, bp);
- continue;
- }else
- setbuftype(bp);
- }
- e->nin++;
- nwants = 0;
- for(i = 0; i < e->nconns; i++)
- nwants += cwantsbp(e->conns[i], bp);
- for(i = 0; nwants > 0 && i < e->nconns; i++)
- if(cwantsbp(e->conns[i], bp)){
- n = bp->ndata;
- if(e->conns[i]->type == -2 && n > 64)
- n = 64;
- if(nwants-- == 1){
- bp->ndata = n;
- dbp = bp;
- bp = nil;
- }else{
- dbp = allocbuf(e);
- memmove(dbp->rp, bp->rp, n);
- dbp->ndata = n;
- dbp->type = bp->type;
- }
- if(nbsendp(e->conns[i]->rc, dbp) == 0){
- e->nierrs++;
- freebuf(e, dbp);
- }
- }
- freebuf(e, bp);
- }
- deprint(2, "%s: writeproc exiting\n", argv0);
- etherexiting(e);
- closedev(e->dev);
- usbfsdel(&e->fs);
-}
-
-static void
-setalt(Dev *d, int ifcid, int altid)
-{
- if(usbcmd(d, Rh2d|Rstd|Riface, Rsetiface, altid, ifcid, nil, 0) < 0)
- dprint(2, "%s: setalt ifc %d alt %d: %r\n", argv0, ifcid, altid);
-}
-
-static int
-ifaceinit(Ether *e, Iface *ifc, int *ei, int *eo)
-{
- Ep *ep;
- int epin, epout, i;
-
- if(ifc == nil)
- return -1;
-
- epin = epout = -1;
- for(i = 0; (epin < 0 || epout < 0) && i < nelem(ifc->ep); i++)
- if((ep = ifc->ep[i]) != nil && ep->type == Ebulk){
- if(ep->dir == Eboth || ep->dir == Ein)
- if(epin == -1)
- epin = ep->id;
- if(ep->dir == Eboth || ep->dir == Eout)
- if(epout == -1)
- epout = ep->id;
- }
- if(epin == -1 || epout == -1)
- return -1;
-
- dprint(2, "ether: ep ids: in %d out %d\n", epin, epout);
- for(i = 0; i < nelem(ifc->altc); i++)
- if(ifc->altc[i] != nil)
- setalt(e->dev, ifc->id, i);
-
- *ei = epin;
- *eo = epout;
- return 0;
-}
-
-static int
-etherinit(Ether *e, int *ei, int *eo)
-{
- int ctlid, datid, i, j;
- Conf *c;
- Desc *desc;
- Iface *ctlif, *datif;
- Usbdev *ud;
-
- *ei = *eo = -1;
- ud = e->dev->usb;
-
- /* look for union descriptor with ethernet ctrl interface */
- for(i = 0; i < nelem(ud->ddesc); i++){
- if((desc = ud->ddesc[i]) == nil)
- continue;
- if(desc->data.bLength < 5 || desc->data.bbytes[0] != Cdcunion)
- continue;
-
- ctlid = desc->data.bbytes[1];
- datid = desc->data.bbytes[2];
-
- if((c = desc->conf) == nil)
- continue;
-
- ctlif = datif = nil;
- for(j = 0; j < nelem(c->iface); j++){
- if(c->iface[j] == nil)
- continue;
- if(c->iface[j]->id == ctlid)
- ctlif = c->iface[j];
- if(c->iface[j]->id == datid)
- datif = c->iface[j];
-
- if(datif != nil && ctlif != nil){
- if(Subclass(ctlif->csp) == Scether &&
- ifaceinit(e, datif, ei, eo) != -1)
- return 0;
- break;
- }
- }
- }
- /* try any other one that seems to be ok */
- for(i = 0; i < nelem(ud->conf); i++)
- if((c = ud->conf[i]) != nil)
- for(j = 0; j < nelem(c->iface); j++)
- if(ifaceinit(e, c->iface[j], ei, eo) != -1)
- return 0;
- dprint(2, "%s: no valid endpoints", argv0);
- return -1;
-}
-
-int
-ethermain(Dev *dev, int argc, char **argv)
-{
- int epin, epout, i, devid;
- Ether *e;
-
- devid = dev->id;
- ARGBEGIN{
- case 'd':
- if(etherdebug == 0)
- fprint(2, "ether debug on\n");
- etherdebug++;
- break;
- case 'N':
- devid = atoi(EARGF(usage()));
- break;
- default:
- return usage();
- }ARGEND
- if(argc != 0) {
- return usage();
- }
- e = dev->aux = emallocz(sizeof(Ether), 1);
- e->dev = dev;
- dev->free = etherdevfree;
-
- for(i = 0; i < nelem(ethers); i++)
- if(ethers[i](e) == 0)
- break;
- if(i == nelem(ethers))
- return -1;
- if(e->init == nil)
- e->init = etherinit;
- if(e->init(e, &epin, &epout) < 0)
- return -1;
- if(e->bwrite == nil)
- e->bwrite = etherbwrite;
- if(e->bread == nil)
- e->bread = etherbread;
-
- if(openeps(e, epin, epout) < 0)
- return -1;
- e->fs = etherfs;
- snprint(e->fs.name, sizeof(e->fs.name), "etherU%d", devid);
- e->fs.dev = dev;
- e->fs.aux = e;
- e->bc = chancreate(sizeof(Buf*), Nconns);
- e->rc = chancreate(sizeof(Buf*), Nconns/2);
- e->wc = chancreate(sizeof(Buf*), Nconns*2);
- incref(e->dev);
- proccreate(etherwriteproc, e, 16*1024);
- incref(e->dev);
- proccreate(etherreadproc, e, 16*1024);
- deprint(2, "%s: dev ref %ld\n", argv0, dev->ref);
- incref(e->dev);
- usbfsadd(&e->fs);
- return 0;
-}
diff --git a/sys/src/cmd/usb/ether/ether.h b/sys/src/cmd/usb/ether/ether.h
deleted file mode 100644
index 3ef7976cc..000000000
--- a/sys/src/cmd/usb/ether/ether.h
+++ /dev/null
@@ -1,120 +0,0 @@
-typedef struct Ether Ether;
-typedef struct Etherops Etherops;
-typedef struct Conn Conn;
-typedef struct Cinfo Cinfo;
-typedef struct Buf Buf;
-typedef struct Etherpkt Etherpkt;
-
-enum
-{
- /* controller ids */
- Cdc = 0,
- A8817x, /* Asis */
- A88178,
- A88179,
- A88772,
-
- Eaddrlen = 6,
- Epktlen = 1514,
- Ehdrsize = 2*Eaddrlen + 2,
-
- Maxpkt = 2000, /* no jumbo packets here */
- Nconns = 8, /* max number of connections */
- Nbufs = 8, /* max number of buffers */
- Scether = 6, /* ethernet cdc subclass */
- Fnheader = 0, /* Functions */
- Fnunion = 6,
- Fnether = 15,
-
- Cdcunion = 6, /* CDC Union descriptor subtype */
-};
-
-struct Buf
-{
- int type;
- int ndata;
- uchar* rp;
- uchar data[Hdrsize+Maxpkt];
-};
-
-struct Conn
-{
- Ref; /* one per file in use */
- int nb;
- int type;
- int headersonly;
- int prom;
- Channel*rc; /* [2] of Buf* */
-};
-
-struct Etherops
-{
- int (*init)(Ether*, int *epin, int *epout);
- long (*bread)(Ether*, Buf*);
- long (*bwrite)(Ether*, Buf*);
- int (*ctl)(Ether*, char*);
- int (*promiscuous)(Ether*, int);
- int (*multicast)(Ether*, uchar*, int);
- char* (*seprintstats)(char*, char*, Ether*);
- void (*free)(Ether*);
- void* aux;
-};
-
-struct Ether
-{
- QLock;
- QLock wlck; /* write one at a time */
- int epinid; /* epin address */
- int epoutid; /* epout address */
- Dev* dev;
- Dev* epin;
- Dev* epout;
- int cid; /* ctlr id */
- int phy; /* phy id */
- Ref prom; /* nb. of promiscuous conns */
- int exiting; /* shutting down */
- int wrexited; /* write process died */
- uchar addr[Eaddrlen]; /* mac */
- int nconns; /* nb. of entries used in... */
- Conn* conns[Nconns]; /* connections */
- int nabufs; /* nb. of allocated buffers */
- int nbufs; /* nb. of buffers in use */
- int nblock; /* nonblocking (output)? */
- long nin;
- long nout;
- long nierrs;
- long noerrs;
- int mbps;
- int nmcasts;
- Channel*rc; /* read channel (of Buf*) */
- Channel*wc; /* write channel (of Buf*) */
- Channel*bc; /* free buf. chan. (of Buf*) */
- Etherops;
- Usbfs fs;
-};
-
-struct Cinfo
-{
- int vid; /* usb vendor id */
- int did; /* usb device/product id */
- int cid; /* controller id assigned by us */
-};
-
-struct Etherpkt
-{
- uchar d[Eaddrlen];
- uchar s[Eaddrlen];
- uchar type[2];
- uchar data[1500];
-};
-
-int ethermain(Dev *dev, int argc, char **argv);
-int asixreset(Ether*);
-int cdcreset(Ether*);
-int parseaddr(uchar *m, char *s);
-void dumpframe(char *tag, void *p, int n);
-
-extern Cinfo cinfo[];
-extern int etherdebug;
-
-#define deprint if(etherdebug)fprint
diff --git a/sys/src/cmd/usb/ether/main.c b/sys/src/cmd/usb/ether/main.c
deleted file mode 100644
index 3ddbc8482..000000000
--- a/sys/src/cmd/usb/ether/main.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * usb/ether - usb ethernet adapter.
- * BUG: This should use /dev/etherfile to
- * use the kernel ether device code.
- */
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include <thread.h>
-#include "usb.h"
-#include "usbfs.h"
-#include "ether.h"
-
-enum
-{
- Arglen = 80,
-};
-
-static void
-usage(void)
-{
- fprint(2, "usage: %s [-Dd] [-N nb] [-m mnt] [-s srv] [dev...]\n", argv0);
- threadexitsall("usage");
-}
-
-/*
- * Ether devices may be weird.
- * Be optimistic and try to use any communication
- * device or one of the `vendor specific class' devices
- * that we know are ethernets.
- */
-static int
-matchether(char *info, void*)
-{
- Cinfo *ip;
- char buf[50];
-
- /*
- * I have an ether reporting comms.0.0
- */
- if(strstr(info, "comms") != nil)
- return 0;
- for(ip = cinfo; ip->vid != 0; ip++){
- snprint(buf, sizeof(buf), "vid %#06x did %#06x", ip->vid, ip->did);
- if(strstr(info, buf) != nil)
- return 0;
- }
- return -1;
-}
-
-void
-threadmain(int argc, char **argv)
-{
- char args[Arglen];
- char *as, *ae, *srv, *mnt;
-
- srv = nil;
- mnt = "/net";
-
- quotefmtinstall();
- ae = args+sizeof(args);
- as = seprint(args, ae, "ether");
- ARGBEGIN{
- case 'D':
- usbfsdebug++;
- break;
- case 'd':
- usbdebug++;
- as = seprint(as, ae, " -d");
- break;
- case 'N':
- as = seprint(as, ae, " -N %s", EARGF(usage()));
- break;
- case 'm':
- mnt = EARGF(usage());
- break;
- case 's':
- srv = EARGF(usage());
- break;
- default:
- usage();
- }ARGEND
-
- rfork(RFNOTEG);
- threadsetgrp(threadid());
- fmtinstall('U', Ufmt);
- usbfsinit(srv, mnt, &usbdirfs, MAFTER|MCREATE);
- startdevs(args, argv, argc, matchether, nil, ethermain);
- threadexits(nil);
-}
diff --git a/sys/src/cmd/usb/ether/mkfile b/sys/src/cmd/usb/ether/mkfile
deleted file mode 100644
index 295b640e9..000000000
--- a/sys/src/cmd/usb/ether/mkfile
+++ /dev/null
@@ -1,35 +0,0 @@
-</$objtype/mkfile
-
-TARG=ether
-OFILES=\
- main.$O\
-
-LIBDOFILES=\
- ether.$O\
- asix.$O\
- cdc.$O\
-
-HFILES=\
- ether.h\
- ../lib/usb.h\
- ../lib/usbfs.h\
-
-LIBD=../lib/usbdev.a$O
-LIBU=../lib/usb.a$O
-LIB=\
- $LIBD\
- $LIBU\
-
-BIN=/$objtype/bin/usb
-
-</sys/src/cmd/mkone
-CFLAGS=-I../lib $CFLAGS
-
-$LIBU:
- cd ../lib
- mk install
- mk clean
-
-$LIBD:V: $LIBDOFILES
- ar vu $LIBD $newprereq
- rm $newprereq
diff --git a/sys/src/cmd/usb/kb/hid.h b/sys/src/cmd/usb/kb/hid.h
deleted file mode 100644
index dba2b027d..000000000
--- a/sys/src/cmd/usb/kb/hid.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * USB keyboard/mouse constants
- */
-enum {
-
- Stack = 32 * 1024,
-
- /* HID class subclass protocol ids */
- PtrCSP = 0x020103, /* mouse.boot.hid */
- KbdCSP = 0x010103, /* keyboard.boot.hid */
-
- /* Requests */
- Getreport = 0x01,
- Setreport = 0x09,
- Getproto = 0x03,
- Setproto = 0x0b,
-
- /* protocols for SET_PROTO request */
- Bootproto = 0,
- Reportproto = 1,
-
- /* protocols for SET_REPORT request */
- Reportout = 0x0200,
-};
-
-enum {
- /* keyboard modifier bits */
- Mlctrl = 0,
- Mlshift = 1,
- Mlalt = 2,
- Mlgui = 3,
- Mrctrl = 4,
- Mrshift = 5,
- Mralt = 6,
- Mrgui = 7,
-
- /* masks for byte[0] */
- Mctrl = 1<<Mlctrl | 1<<Mrctrl,
- Mshift = 1<<Mlshift | 1<<Mrshift,
- Malt = 1<<Mlalt | 1<<Mralt,
- Mcompose = 1<<Mlalt,
- Maltgr = 1<<Mralt,
- Mgui = 1<<Mlgui | 1<<Mrgui,
-
- MaxAcc = 3, /* max. ptr acceleration */
- PtrMask= 0xf, /* 4 buttons: should allow for more. */
-
-};
-
-/*
- * Plan 9 keyboard driver constants.
- */
-enum {
- /* Scan codes (see kbd.c) */
- SCesc1 = 0xe0, /* first of a 2-character sequence */
- SCesc2 = 0xe1,
- SClshift = 0x2a,
- SCrshift = 0x36,
- SCctrl = 0x1d,
- SCcompose = 0x38,
- Keyup = 0x80, /* flag bit */
- Keymask = 0x7f, /* regular scan code bits */
-};
-
-int kbmain(Dev *d, int argc, char*argv[]);
diff --git a/sys/src/cmd/usb/kb/kb.c b/sys/src/cmd/usb/kb/kb.c
deleted file mode 100644
index 0880f5b51..000000000
--- a/sys/src/cmd/usb/kb/kb.c
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
- * USB Human Interaction Device: keyboard and mouse.
- *
- * If there's no usb keyboard, it tries to setup the mouse, if any.
- * It should be started at boot time.
- *
- * Mouse events are converted to the format of mouse(3)'s
- * mousein file.
- * Keyboard keycodes are translated to scan codes and sent to kbin(3).
- *
- */
-
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-#include "hid.h"
-
-enum
-{
- Awakemsg=0xdeaddead,
- Diemsg = 0xbeefbeef,
-};
-
-typedef struct KDev KDev;
-typedef struct Kin Kin;
-
-struct KDev
-{
- Dev* dev; /* usb device*/
- Dev* ep; /* endpoint to get events */
- Kin* in; /* used to send events to kernel */
- Channel*repeatc; /* only for keyboard */
- int accel; /* only for mouse */
-};
-
-/*
- * Kbdin and mousein files must be shared among all instances.
- */
-struct Kin
-{
- int ref;
- int fd;
- char* name;
-};
-
-/*
- * Map for the logitech bluetooth mouse with 8 buttons and wheels.
- * { ptr ->mouse}
- * { 0x01, 0x01 }, // left
- * { 0x04, 0x02 }, // middle
- * { 0x02, 0x04 }, // right
- * { 0x40, 0x08 }, // up
- * { 0x80, 0x10 }, // down
- * { 0x10, 0x08 }, // side up
- * { 0x08, 0x10 }, // side down
- * { 0x20, 0x02 }, // page
- * besides wheel and regular up/down report the 4th byte as 1/-1
- */
-
-/*
- * key code to scan code; for the page table used by
- * the logitech bluetooth keyboard.
- */
-static char sctab[256] =
-{
-[0x00] 0x0, 0x0, 0x0, 0x0, 0x1e, 0x30, 0x2e, 0x20,
-[0x08] 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26,
-[0x10] 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1f, 0x14,
-[0x18] 0x16, 0x2f, 0x11, 0x2d, 0x15, 0x2c, 0x2, 0x3,
-[0x20] 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb,
-[0x28] 0x1c, 0x1, 0xe, 0xf, 0x39, 0xc, 0xd, 0x1a,
-[0x30] 0x1b, 0x2b, 0x2b, 0x27, 0x28, 0x29, 0x33, 0x34,
-[0x38] 0x35, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
-[0x40] 0x41, 0x42, 0x43, 0x44, 0x57, 0x58, 0x63, 0x46,
-[0x48] 0x77, 0x52, 0x47, 0x49, 0x53, 0x4f, 0x51, 0x4d,
-[0x50] 0x4b, 0x50, 0x48, 0x45, 0x35, 0x37, 0x4a, 0x4e,
-[0x58] 0x1c, 0x4f, 0x50, 0x51, 0x4b, 0x4c, 0x4d, 0x47,
-[0x60] 0x48, 0x49, 0x52, 0x53, 0x56, 0x7f, 0x74, 0x75,
-[0x68] 0x55, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
-[0x70] 0x78, 0x79, 0x7a, 0x7b, 0x0, 0x0, 0x0, 0x0,
-[0x78] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71,
-[0x80] 0x73, 0x72, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0,
-[0x88] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-[0x90] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-[0x98] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-[0xa0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-[0xa8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-[0xb0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-[0xb8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-[0xc0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-[0xc8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-[0xd0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-[0xd8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-[0xe0] 0x1d, 0x2a, 0x38, 0x7d, 0x61, 0x36, 0x64, 0x7e,
-[0xe8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x73, 0x72, 0x71,
-[0xf0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-[0xf8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-};
-
-static QLock inlck;
-static Kin kbdin =
-{
- .ref = 0,
- .name = "/dev/kbin",
- .fd = -1,
-};
-static Kin ptrin =
-{
- .ref = 0,
- .name = "#m/mousein",
- .fd = -1,
-};
-
-static int kbdebug;
-
-static int
-setbootproto(KDev* f, int eid)
-{
- int r, id;
-
- r = Rh2d|Rclass|Riface;
- id = f->dev->usb->ep[eid]->iface->id;
- return usbcmd(f->dev, r, Setproto, Bootproto, id, nil, 0);
-}
-
-static int
-setleds(KDev* f, int eid, uchar leds)
-{
- return usbcmd(f->dev, Rh2d|Rclass|Riface, Setreport, Reportout, 0, &leds, 1);
-}
-
-/*
- * Try to recover from a babble error. A port reset is the only way out.
- * BUG: we should be careful not to reset a bundle with several devices.
- */
-static void
-recoverkb(KDev *f)
-{
- int i;
-
- close(f->dev->dfd); /* it's for usbd now */
- devctl(f->dev, "reset");
- for(i = 0; i < 10; i++){
- sleep(500);
- if(opendevdata(f->dev, ORDWR) >= 0){
- setbootproto(f, f->ep->id);
- break;
- }
- /* else usbd still working... */
- }
-}
-
-static void
-kbfatal(KDev *kd, char *sts)
-{
- Dev *dev;
-
- if(sts != nil)
- fprint(2, "kb: fatal: %s\n", sts);
- else
- fprint(2, "kb: exiting\n");
- if(kd->repeatc != nil)
- nbsendul(kd->repeatc, Diemsg);
- dev = kd->dev;
- kd->dev = nil;
- if(kd->ep != nil)
- closedev(kd->ep);
- kd->ep = nil;
- devctl(dev, "detach");
- closedev(dev);
- /*
- * free(kd); done by closedev.
- */
- threadexits(sts);
-}
-
-static int
-scale(KDev *f, int x)
-{
- int sign = 1;
-
- if(x < 0){
- sign = -1;
- x = -x;
- }
- switch(x){
- case 0:
- case 1:
- case 2:
- case 3:
- break;
- case 4:
- x = 6 + (f->accel>>2);
- break;
- case 5:
- x = 9 + (f->accel>>1);
- break;
- default:
- x *= MaxAcc;
- break;
- }
- return sign*x;
-}
-
-/*
- * ps2 mouse is processed mostly at interrupt time.
- * for usb we do what we can.
- */
-static void
-sethipri(void)
-{
- char fn[30];
- int fd;
-
- snprint(fn, sizeof(fn), "/proc/%d/ctl", getpid());
- fd = open(fn, OWRITE);
- if(fd < 0)
- return;
- fprint(fd, "pri 13");
- close(fd);
-}
-
-static void
-ptrwork(void* a)
-{
- static char maptab[] = {0x0, 0x1, 0x4, 0x5, 0x2, 0x3, 0x6, 0x7};
- int x, y, b, c, ptrfd;
- int mfd, nerrs;
- char buf[32];
- char mbuf[80];
- KDev* f = a;
- int hipri;
-
- hipri = nerrs = 0;
- ptrfd = f->ep->dfd;
- mfd = f->in->fd;
-
- if(f->ep->maxpkt < 3 || f->ep->maxpkt > sizeof buf)
- kbfatal(f, "weird mouse maxpkt");
- for(;;){
- memset(buf, 0, sizeof buf);
- if(f->ep == nil)
- kbfatal(f, nil);
- c = read(ptrfd, buf, f->ep->maxpkt);
- assert(f->dev != nil);
- assert(f->ep != nil);
- if(c < 0){
- dprint(2, "kb: mouse: %s: read: %r\n", f->ep->dir);
- if(++nerrs < 3){
- recoverkb(f);
- continue;
- }
- }
- if(c <= 0)
- kbfatal(f, nil);
- if(c < 3)
- continue;
- if(f->accel){
- x = scale(f, buf[1]);
- y = scale(f, buf[2]);
- }else{
- x = buf[1];
- y = buf[2];
- }
- b = maptab[buf[0] & 0x7];
- if(c > 3 && buf[3] == 1) /* up */
- b |= 0x08;
- if(c > 3 && buf[3] == -1) /* down */
- b |= 0x10;
- if(kbdebug > 1)
- fprint(2, "kb: m%11d %11d %11d\n", x, y, b);
- seprint(mbuf, mbuf+sizeof(mbuf), "m%11d %11d %11d", x, y,b);
- if(write(mfd, mbuf, strlen(mbuf)) < 0)
- kbfatal(f, "mousein i/o");
- if(hipri == 0){
- sethipri();
- hipri = 1;
- }
- }
-}
-
-static void
-stoprepeat(KDev *f)
-{
- sendul(f->repeatc, Awakemsg);
-}
-
-static void
-startrepeat(KDev *f, uchar esc1, uchar sc)
-{
- ulong c;
-
- if(esc1)
- c = SCesc1 << 8 | (sc & 0xff);
- else
- c = sc;
- sendul(f->repeatc, c);
-}
-
-static void
-putscan(int kbinfd, uchar esc, uchar sc)
-{
- uchar s[2] = {SCesc1, 0};
-
- if(sc == 0x41){
- kbdebug += 2;
- return;
- }
- if(sc == 0x42){
- kbdebug = 0;
- return;
- }
- if(kbdebug)
- fprint(2, "sc: %x %x\n", (esc? SCesc1: 0), sc);
- s[1] = sc;
- if(esc && sc != 0)
- write(kbinfd, s, 2);
- else if(sc != 0)
- write(kbinfd, s+1, 1);
-}
-
-static void
-repeatproc(void* a)
-{
- KDev *f;
- Channel *repeatc;
- int kbdinfd;
- ulong l, t, i;
- uchar esc1, sc;
-
- /*
- * too many jumps here.
- * Rewrite instead of debug, if needed.
- */
- f = a;
- repeatc = f->repeatc;
- kbdinfd = f->in->fd;
- l = Awakemsg;
-Repeat:
- if(l == Diemsg)
- goto Abort;
- while(l == Awakemsg)
- l = recvul(repeatc);
- if(l == Diemsg)
- goto Abort;
- esc1 = l >> 8;
- sc = l;
- t = 160;
- for(;;){
- for(i = 0; i < t; i += 5){
- if(l = nbrecvul(repeatc))
- goto Repeat;
- sleep(5);
- }
- putscan(kbdinfd, esc1, sc);
- t = 30;
- }
-Abort:
- chanfree(repeatc);
- threadexits("aborted");
-
-}
-
-
-#define hasesc1(sc) (((sc) > 0x47) || ((sc) == 0x38))
-
-static void
-putmod(int fd, uchar mods, uchar omods, uchar mask, uchar esc, uchar sc)
-{
- /* BUG: Should be a single write */
- if((mods&mask) && !(omods&mask))
- putscan(fd, esc, sc);
- if(!(mods&mask) && (omods&mask))
- putscan(fd, esc, Keyup|sc);
-}
-
-/*
- * This routine diffs the state with the last known state
- * and invents the scan codes that would have been sent
- * by a non-usb keyboard in that case. This also requires supplying
- * the extra esc1 byte as well as keyup flags.
- * The aim is to allow future addition of other keycode pages
- * for other keyboards.
- */
-static uchar
-putkeys(KDev *f, uchar buf[], uchar obuf[], int n, uchar dk)
-{
- int i, j;
- uchar uk;
- int fd;
-
- fd = f->in->fd;
- putmod(fd, buf[0], obuf[0], Mctrl, 0, SCctrl);
- putmod(fd, buf[0], obuf[0], (1<<Mlshift), 0, SClshift);
- putmod(fd, buf[0], obuf[0], (1<<Mrshift), 0, SCrshift);
- putmod(fd, buf[0], obuf[0], Mcompose, 0, SCcompose);
- putmod(fd, buf[0], obuf[0], Maltgr, 1, SCcompose);
-
- /* Report key downs */
- for(i = 2; i < n; i++){
- for(j = 2; j < n; j++)
- if(buf[i] == obuf[j])
- break;
- if(j == n && buf[i] != 0){
- dk = sctab[buf[i]];
- putscan(fd, hasesc1(dk), dk);
- startrepeat(f, hasesc1(dk), dk);
- }
- }
-
- /* Report key ups */
- uk = 0;
- for(i = 2; i < n; i++){
- for(j = 2; j < n; j++)
- if(obuf[i] == buf[j])
- break;
- if(j == n && obuf[i] != 0){
- uk = sctab[obuf[i]];
- putscan(fd, hasesc1(uk), uk|Keyup);
- }
- }
- if(uk && (dk == 0 || dk == uk)){
- stoprepeat(f);
- dk = 0;
- }
- return dk;
-}
-
-static int
-kbdbusy(uchar* buf, int n)
-{
- int i;
-
- for(i = 1; i < n; i++)
- if(buf[i] == 0 || buf[i] != buf[0])
- return 0;
- return 1;
-}
-
-static void
-kbdwork(void *a)
-{
- int c, i, kbdfd, nerrs;
- uchar dk, buf[64], lbuf[64];
- char err[128];
- KDev *f = a;
-
- kbdfd = f->ep->dfd;
-
- if(f->ep->maxpkt < 3 || f->ep->maxpkt > sizeof buf)
- kbfatal(f, "weird maxpkt");
-
- f->repeatc = chancreate(sizeof(ulong), 0);
- if(f->repeatc == nil)
- kbfatal(f, "chancreate failed");
-
- proccreate(repeatproc, f, Stack);
- memset(lbuf, 0, sizeof lbuf);
- dk = nerrs = 0;
- for(;;){
- memset(buf, 0, sizeof buf);
- c = read(kbdfd, buf, f->ep->maxpkt);
- assert(f->dev != nil);
- assert(f->ep != nil);
- if(c < 0){
- rerrstr(err, sizeof(err));
- fprint(2, "kb: %s: read: %s\n", f->ep->dir, err);
- if(strstr(err, "babble") != 0 && ++nerrs < 3){
- recoverkb(f);
- continue;
- }
- }
- if(c <= 0)
- kbfatal(f, nil);
- if(c < 3)
- continue;
- if(kbdbusy(buf + 2, c - 2))
- continue;
- if(usbdebug > 2 || kbdebug > 1){
- fprint(2, "kbd mod %x: ", buf[0]);
- for(i = 2; i < c; i++)
- fprint(2, "kc %x ", buf[i]);
- fprint(2, "\n");
- }
- dk = putkeys(f, buf, lbuf, f->ep->maxpkt, dk);
- memmove(lbuf, buf, c);
- nerrs = 0;
- }
-}
-
-static void
-freekdev(void *a)
-{
- KDev *kd;
-
- kd = a;
- if(kd->in != nil){
- qlock(&inlck);
- if(--kd->in->ref == 0){
- close(kd->in->fd);
- kd->in->fd = -1;
- }
- qunlock(&inlck);
- }
- dprint(2, "freekdev\n");
- free(kd);
-}
-
-static void
-kbstart(Dev *d, Ep *ep, Kin *in, void (*f)(void*), int accel)
-{
- KDev *kd;
-
- qlock(&inlck);
- if(in->fd < 0){
- in->fd = open(in->name, OWRITE);
- if(in->fd < 0){
- fprint(2, "kb: %s: %r\n", in->name);
- qunlock(&inlck);
- return;
- }
- }
- in->ref++; /* for kd->in = in */
- qunlock(&inlck);
- kd = d->aux = emallocz(sizeof(KDev), 1);
- d->free = freekdev;
- kd->in = in;
- kd->dev = d;
- if(setbootproto(kd, ep->id) < 0){
- fprint(2, "kb: %s: bootproto: %r\n", d->dir);
- return;
- }
- kd->accel = accel;
- kd->ep = openep(d, ep->id);
- if(kd->ep == nil){
- fprint(2, "kb: %s: openep %d: %r\n", d->dir, ep->id);
- return;
- }
- if(opendevdata(kd->ep, OREAD) < 0){
- fprint(2, "kb: %s: opendevdata: %r\n", kd->ep->dir);
- closedev(kd->ep);
- kd->ep = nil;
- return;
- }
- if(setleds(kd, ep->id, 0) < 0){
- fprint(2, "kb: %s: setleds: %r\n", d->dir);
- return;
- }
- incref(d);
- proccreate(f, kd, Stack);
-}
-
-static int
-usage(void)
-{
- werrstr("usage: usb/kb [-dkm] [-a n] [-N nb]");
- return -1;
-}
-
-int
-kbmain(Dev *d, int argc, char* argv[])
-{
- int i, kena, pena, accel, devid;
- Usbdev *ud;
- Ep *ep;
-
- kena = pena = 1;
- accel = 0;
- devid = d->id;
- ARGBEGIN{
- case 'a':
- accel = strtol(EARGF(usage()), nil, 0);
- break;
- case 'd':
- kbdebug++;
- break;
- case 'k':
- kena = 1;
- pena = 0;
- break;
- case 'm':
- kena = 0;
- pena = 1;
- break;
- case 'N':
- devid = atoi(EARGF(usage())); /* ignore dev number */
- break;
- default:
- return usage();
- }ARGEND;
- if(argc != 0){
- return usage();
- }
- USED(devid);
- ud = d->usb;
- d->aux = nil;
- dprint(2, "kb: main: dev %s ref %ld\n", d->dir, d->ref);
- for(i = 0; i < nelem(ud->ep); i++){
- if((ep = ud->ep[i]) == nil)
- break;
- if(kena && ep->type == Eintr && ep->dir == Ein)
- if(ep->iface->csp == KbdCSP)
- kbstart(d, ep, &kbdin, kbdwork, accel);
- if(pena && ep->type == Eintr && ep->dir == Ein)
- if(ep->iface->csp == PtrCSP)
- kbstart(d, ep, &ptrin, ptrwork, accel);
- }
- return 0;
-}
diff --git a/sys/src/cmd/usb/kb/main.c b/sys/src/cmd/usb/kb/main.c
deleted file mode 100644
index 50a7bdaf4..000000000
--- a/sys/src/cmd/usb/kb/main.c
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-#include "hid.h"
-
-typedef struct Parg Parg;
-
-enum
-{
- Ndevs = 10,
- Arglen = 80,
- Nargs = 10,
-};
-
-static void
-usage(void)
-{
- fprint(2, "usage: %s [-dkm] [-a n] [-N nb] [dev...]\n", argv0);
- threadexitsall("usage");
-}
-
-void
-threadmain(int argc, char **argv)
-{
- char args[Arglen];
- char *as, *ae;
- int accel, pena, devid;
- int csps[] = { KbdCSP, PtrCSP, 0 };
-
- quotefmtinstall();
- pena = 1;
- ae = args+sizeof(args);
- as = seprint(args, ae, "kb");
- ARGBEGIN{
- case 'a':
- accel = strtol(EARGF(usage()), nil, 0);
- as = seprint(as, ae, " -a %d", accel);
- break;
- case 'd':
- usbdebug++;
- as = seprint(as, ae, " -d");
- break;
- case 'k':
- as = seprint(as, ae, " -k");
- pena = 0;
- break;
- case 'm':
- as = seprint(as, ae, " -m");
- pena = 1;
- break;
- case 'N':
- devid = atoi(EARGF(usage())); /* ignore dev number */
- USED(devid);
- break;
- default:
- usage();
- }ARGEND;
-
- rfork(RFNOTEG);
- fmtinstall('U', Ufmt);
- threadsetgrp(threadid());
- if(pena == 0)
- csps[1] = 0;
- startdevs(args, argv, argc, matchdevcsp, csps, kbmain);
- threadexits(nil);
-}
diff --git a/sys/src/cmd/usb/kb/mkfile b/sys/src/cmd/usb/kb/mkfile
deleted file mode 100644
index 510d7b899..000000000
--- a/sys/src/cmd/usb/kb/mkfile
+++ /dev/null
@@ -1,35 +0,0 @@
-</$objtype/mkfile
-
-TARG=kb
-OFILES=main.$O
-LIBDOFILES=kb.$O
-HFILES=\
- ../lib/usb.h\
- hid.h\
-
-LIBD=../lib/usbdev.a$O
-LIBU=../lib/usb.a$O
-LIB=\
- $LIBD\
- $LIBU\
-
-BIN=/$objtype/bin/usb
-
-
-UPDATE=\
- mkfile\
- $HFILES\
- ${OFILES:%.$O=%.c}\
-
-</sys/src/cmd/mkone
-CFLAGS=-I../lib $CFLAGS
-
-$LIBU:
- cd ../lib
- mk install
- mk clean
-
-$LIBD:V: $LIBDOFILES
- ar vu $LIBD $newprereq
- rm $newprereq
-
diff --git a/sys/src/cmd/usb/lib/dev.c b/sys/src/cmd/usb/lib/dev.c
deleted file mode 100644
index 675cc6908..000000000
--- a/sys/src/cmd/usb/lib/dev.c
+++ /dev/null
@@ -1,493 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-
-/*
- * epN.M -> N
- */
-static int
-nameid(char *s)
-{
- char *r;
- char nm[20];
-
- r = strrchr(s, 'p');
- if(r == nil)
- return -1;
- strecpy(nm, nm+sizeof(nm), r+1);
- r = strchr(nm, '.');
- if(r == nil)
- return -1;
- *r = 0;
- return atoi(nm);
-}
-
-Dev*
-openep(Dev *d, int id)
-{
- char *mode; /* How many modes? */
- Ep *ep;
- Altc *ac;
- Dev *epd;
- Usbdev *ud;
- char name[40];
-
- if(access("/dev/usb", AEXIST) < 0 && bind("#u", "/dev", MBEFORE) < 0)
- return nil;
- if(d->cfd < 0 || d->usb == nil){
- werrstr("device not configured");
- return nil;
- }
- ud = d->usb;
- if(id < 0 || id >= nelem(ud->ep) || ud->ep[id] == nil){
- werrstr("bad enpoint number");
- return nil;
- }
- ep = ud->ep[id];
- mode = "rw";
- if(ep->dir == Ein)
- mode = "r";
- if(ep->dir == Eout)
- mode = "w";
- snprint(name, sizeof(name), "/dev/usb/ep%d.%d", d->id, id);
- if(access(name, AEXIST) == 0){
- dprint(2, "%s: %s already exists; trying to open\n", argv0, name);
- epd = opendev(name);
- if(epd != nil)
- epd->maxpkt = ep->maxpkt; /* guess */
- return epd;
- }
- if(devctl(d, "new %d %d %s", id, ep->type, mode) < 0){
- dprint(2, "%s: %s: new: %r\n", argv0, d->dir);
- return nil;
- }
- epd = opendev(name);
- if(epd == nil)
- return nil;
- epd->id = id;
- if(devctl(epd, "maxpkt %d", ep->maxpkt) < 0)
- fprint(2, "%s: %s: openep: maxpkt: %r\n", argv0, epd->dir);
- else
- dprint(2, "%s: %s: maxpkt %d\n", argv0, epd->dir, ep->maxpkt);
- epd->maxpkt = ep->maxpkt;
- ac = ep->iface->altc[0];
- if(ep->ntds > 1 && devctl(epd, "ntds %d", ep->ntds) < 0)
- fprint(2, "%s: %s: openep: ntds: %r\n", argv0, epd->dir);
- else
- dprint(2, "%s: %s: ntds %d\n", argv0, epd->dir, ep->ntds);
-
- /*
- * For iso endpoints and high speed interrupt endpoints the pollival is
- * actually 2ⁿ and not n.
- * The kernel usb driver must take that into account.
- * It's simpler this way.
- */
-
- if(ac != nil && (ep->type == Eintr || ep->type == Eiso) && ac->interval != 0)
- if(devctl(epd, "pollival %d", ac->interval) < 0)
- fprint(2, "%s: %s: openep: pollival: %r\n", argv0, epd->dir);
- return epd;
-}
-
-Dev*
-opendev(char *fn)
-{
- Dev *d;
- int l;
-
- if(access("/dev/usb", AEXIST) < 0 && bind("#u", "/dev", MBEFORE) < 0)
- return nil;
- d = emallocz(sizeof(Dev), 1);
- incref(d);
-
- l = strlen(fn);
- d->dfd = -1;
- /*
- * +30 to allocate extra size to concat "/<epfilename>"
- * we should probably remove that feature from the manual
- * and from the code after checking out that nobody relies on
- * that.
- */
- d->dir = emallocz(l + 30, 0);
- strcpy(d->dir, fn);
- strcpy(d->dir+l, "/ctl");
- d->cfd = open(d->dir, ORDWR|OCEXEC);
- d->dir[l] = 0;
- d->id = nameid(fn);
- if(d->cfd < 0){
- werrstr("can't open endpoint %s: %r", d->dir);
- free(d->dir);
- free(d);
- return nil;
- }
- dprint(2, "%s: opendev %#p %s\n", argv0, d, fn);
- return d;
-}
-
-int
-opendevdata(Dev *d, int mode)
-{
- char buf[80]; /* more than enough for a usb path */
-
- seprint(buf, buf+sizeof(buf), "%s/data", d->dir);
- d->dfd = open(buf, mode|OCEXEC);
- return d->dfd;
-}
-
-enum
-{
- /*
- * Max device conf is also limited by max control request size as
- * limited by Maxctllen in the kernel usb.h (both limits are arbitrary).
- */
- Maxdevconf = 4 * 1024, /* asking for 16K kills Newsham's disk */
-};
-
-int
-loaddevconf(Dev *d, int n)
-{
- uchar *buf;
- int nr;
- int type;
-
- if(n >= nelem(d->usb->conf)){
- werrstr("loaddevconf: bug: out of configurations in device");
- fprint(2, "%s: %r\n", argv0);
- return -1;
- }
- buf = emallocz(Maxdevconf, 0);
- type = Rd2h|Rstd|Rdev;
- nr = usbcmd(d, type, Rgetdesc, Dconf<<8|n, 0, buf, Maxdevconf);
- if(nr < Dconflen){
- free(buf);
- return -1;
- }
- if(d->usb->conf[n] == nil)
- d->usb->conf[n] = emallocz(sizeof(Conf), 1);
- nr = parseconf(d->usb, d->usb->conf[n], buf, nr);
- free(buf);
- return nr;
-}
-
-Ep*
-mkep(Usbdev *d, int id)
-{
- Ep *ep;
-
- d->ep[id] = ep = emallocz(sizeof(Ep), 1);
- ep->id = id;
- return ep;
-}
-
-static char*
-mkstr(uchar *b, int n)
-{
- Rune r;
- char *us;
- char *s;
- char *e;
-
- if(n <= 2 || (n & 1) != 0)
- return strdup("none");
- n = (n - 2)/2;
- b += 2;
- us = s = emallocz(n*UTFmax+1, 0);
- e = s + n*UTFmax+1;
- for(; --n >= 0; b += 2){
- r = GET2(b);
- s = seprint(s, e, "%C", r);
- }
- return us;
-}
-
-char*
-loaddevstr(Dev *d, int sid)
-{
- uchar buf[128];
- int type;
- int nr;
-
- if(sid == 0)
- return estrdup("none");
- type = Rd2h|Rstd|Rdev;
- nr=usbcmd(d, type, Rgetdesc, Dstr<<8|sid, 0, buf, sizeof(buf));
- return mkstr(buf, nr);
-}
-
-int
-loaddevdesc(Dev *d)
-{
- uchar buf[Ddevlen+255];
- int nr;
- int type;
- Ep *ep0;
-
- type = Rd2h|Rstd|Rdev;
- nr = sizeof(buf);
- memset(buf, 0, Ddevlen);
- if((nr=usbcmd(d, type, Rgetdesc, Ddev<<8|0, 0, buf, nr)) < 0)
- return -1;
- /*
- * Several hubs are returning descriptors of 17 bytes, not 18.
- * We accept them and leave number of configurations as zero.
- * (a get configuration descriptor also fails for them!)
- */
- if(nr < Ddevlen){
- print("%s: %s: warning: device with short descriptor\n",
- argv0, d->dir);
- if(nr < Ddevlen-1){
- werrstr("short device descriptor (%d bytes)", nr);
- return -1;
- }
- }
- d->usb = emallocz(sizeof(Usbdev), 1);
- ep0 = mkep(d->usb, 0);
- ep0->dir = Eboth;
- ep0->type = Econtrol;
- ep0->maxpkt = d->maxpkt = 8; /* a default */
- nr = parsedev(d, buf, nr);
- if(nr >= 0){
- d->usb->vendor = loaddevstr(d, d->usb->vsid);
- if(strcmp(d->usb->vendor, "none") != 0){
- d->usb->product = loaddevstr(d, d->usb->psid);
- d->usb->serial = loaddevstr(d, d->usb->ssid);
- }
- }
- return nr;
-}
-
-int
-configdev(Dev *d)
-{
- int i;
-
- if(d->dfd < 0)
- opendevdata(d, ORDWR);
- if(loaddevdesc(d) < 0)
- return -1;
- for(i = 0; i < d->usb->nconf; i++)
- if(loaddevconf(d, i) < 0)
- return -1;
- return 0;
-}
-
-static void
-closeconf(Conf *c)
-{
- int i;
- int a;
-
- if(c == nil)
- return;
- for(i = 0; i < nelem(c->iface); i++)
- if(c->iface[i] != nil){
- for(a = 0; a < nelem(c->iface[i]->altc); a++)
- free(c->iface[i]->altc[a]);
- free(c->iface[i]);
- }
- free(c);
-}
-
-void
-closedev(Dev *d)
-{
- int i;
- Usbdev *ud;
-
- if(d==nil || decref(d) != 0)
- return;
- dprint(2, "%s: closedev %#p %s\n", argv0, d, d->dir);
- if(d->free != nil)
- d->free(d->aux);
- if(d->cfd >= 0)
- close(d->cfd);
- if(d->dfd >= 0)
- close(d->dfd);
- d->cfd = d->dfd = -1;
- free(d->dir);
- d->dir = nil;
- ud = d->usb;
- d->usb = nil;
- if(ud != nil){
- free(ud->vendor);
- free(ud->product);
- free(ud->serial);
- for(i = 0; i < nelem(ud->ep); i++)
- free(ud->ep[i]);
- for(i = 0; i < nelem(ud->ddesc); i++)
- free(ud->ddesc[i]);
-
- for(i = 0; i < nelem(ud->conf); i++)
- closeconf(ud->conf[i]);
- free(ud);
- }
- free(d);
-}
-
-static char*
-reqstr(int type, int req)
-{
- char *s;
- static char* ds[] = { "dev", "if", "ep", "oth" };
- static char buf[40];
-
- if(type&Rd2h)
- s = seprint(buf, buf+sizeof(buf), "d2h");
- else
- s = seprint(buf, buf+sizeof(buf), "h2d");
- if(type&Rclass)
- s = seprint(s, buf+sizeof(buf), "|cls");
- else if(type&Rvendor)
- s = seprint(s, buf+sizeof(buf), "|vnd");
- else
- s = seprint(s, buf+sizeof(buf), "|std");
- s = seprint(s, buf+sizeof(buf), "|%s", ds[type&3]);
-
- switch(req){
- case Rgetstatus: s = seprint(s, buf+sizeof(buf), " getsts"); break;
- case Rclearfeature: s = seprint(s, buf+sizeof(buf), " clrfeat"); break;
- case Rsetfeature: s = seprint(s, buf+sizeof(buf), " setfeat"); break;
- case Rsetaddress: s = seprint(s, buf+sizeof(buf), " setaddr"); break;
- case Rgetdesc: s = seprint(s, buf+sizeof(buf), " getdesc"); break;
- case Rsetdesc: s = seprint(s, buf+sizeof(buf), " setdesc"); break;
- case Rgetconf: s = seprint(s, buf+sizeof(buf), " getcnf"); break;
- case Rsetconf: s = seprint(s, buf+sizeof(buf), " setcnf"); break;
- case Rgetiface: s = seprint(s, buf+sizeof(buf), " getif"); break;
- case Rsetiface: s = seprint(s, buf+sizeof(buf), " setif"); break;
- }
- USED(s);
- return buf;
-}
-
-static int
-cmdreq(Dev *d, int type, int req, int value, int index, uchar *data, int count)
-{
- int ndata, n;
- uchar *wp;
- uchar buf[8];
- char *hd, *rs;
-
- assert(d != nil);
- if(data == nil){
- wp = buf;
- ndata = 0;
- }else{
- ndata = count;
- wp = emallocz(8+ndata, 0);
- }
- wp[0] = type;
- wp[1] = req;
- PUT2(wp+2, value);
- PUT2(wp+4, index);
- PUT2(wp+6, count);
- if(data != nil)
- memmove(wp+8, data, ndata);
- if(usbdebug>2){
- hd = hexstr(wp, ndata+8);
- rs = reqstr(type, req);
- fprint(2, "%s: %s val %d|%d idx %d cnt %d out[%d] %s\n",
- d->dir, rs, value>>8, value&0xFF,
- index, count, ndata+8, hd);
- free(hd);
- }
- n = write(d->dfd, wp, 8+ndata);
- if(wp != buf)
- free(wp);
- if(n < 0)
- return -1;
- if(n != 8+ndata){
- dprint(2, "%s: cmd: short write: %d\n", argv0, n);
- return -1;
- }
- return n;
-}
-
-static int
-cmdrep(Dev *d, void *buf, int nb)
-{
- char *hd;
-
- nb = read(d->dfd, buf, nb);
- if(nb >0 && usbdebug > 2){
- hd = hexstr(buf, nb);
- fprint(2, "%s: in[%d] %s\n", d->dir, nb, hd);
- free(hd);
- }
- return nb;
-}
-
-int
-usbcmd(Dev *d, int type, int req, int value, int index, uchar *data, int count)
-{
- int i, r, nerr;
- char err[64];
-
- /*
- * Some devices do not respond to commands some times.
- * Others even report errors but later work just fine. Retry.
- */
- r = -1;
- *err = 0;
- for(i = nerr = 0; i < Uctries; i++){
- if(type & Rd2h)
- r = cmdreq(d, type, req, value, index, nil, count);
- else
- r = cmdreq(d, type, req, value, index, data, count);
- if(r > 0){
- if((type & Rd2h) == 0)
- break;
- r = cmdrep(d, data, count);
- if(r > 0)
- break;
- if(r == 0)
- werrstr("no data from device");
- }
- nerr++;
- if(*err == 0)
- rerrstr(err, sizeof(err));
- sleep(Ucdelay);
- }
- if(r > 0 && i >= 2)
- /* let the user know the device is not in good shape */
- fprint(2, "%s: usbcmd: %s: required %d attempts (%s)\n",
- argv0, d->dir, i, err);
- return r;
-}
-
-int
-unstall(Dev *dev, Dev *ep, int dir)
-{
- int r;
-
- if(dir == Ein)
- dir = 0x80;
- else
- dir = 0;
- r = Rh2d|Rstd|Rep;
- if(usbcmd(dev, r, Rclearfeature, Fhalt, ep->id|dir, nil, 0)<0){
- werrstr("unstall: %s: %r", ep->dir);
- return -1;
- }
- if(devctl(ep, "clrhalt") < 0){
- werrstr("clrhalt: %s: %r", ep->dir);
- return -1;
- }
- return 0;
-}
-
-/*
- * To be sure it uses a single write.
- */
-int
-devctl(Dev *dev, char *fmt, ...)
-{
- char buf[128];
- va_list arg;
- char *e;
-
- va_start(arg, fmt);
- e = vseprint(buf, buf+sizeof(buf), fmt, arg);
- va_end(arg);
- return write(dev->cfd, buf, e-buf);
-}
diff --git a/sys/src/cmd/usb/lib/devs.c b/sys/src/cmd/usb/lib/devs.c
deleted file mode 100644
index 3e11495aa..000000000
--- a/sys/src/cmd/usb/lib/devs.c
+++ /dev/null
@@ -1,159 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-
-typedef struct Parg Parg;
-
-enum {
- Ndevs = 32,
- Arglen = 500,
- Nargs = 64,
- Stack = 16 * 1024,
-};
-
-struct Parg {
- char* args;
- Dev* dev;
- int (*f)(Dev*,int,char**);
- Channel*rc;
-};
-
-static void
-workproc(void *a)
-{
- Parg *pa;
- char args[Arglen];
- char *argv[Nargs];
- int argc;
- Channel *rc;
- Dev *d;
- int (*f)(Dev*,int,char**);
-
- pa = a;
- strecpy(args, args+sizeof(args), pa->args); /* don't leak */
- d = pa->dev;
- f = pa->f;
- rc = pa->rc;
- free(pa->args);
- free(pa);
- argc = tokenize(args, argv, nelem(argv)-1);
- argv[argc] = nil;
- if(f(d, argc, argv) < 0){
- closedev(d);
- fprint(2, "%s: devmain: %r\n", argv0);
- sendul(rc, -1);
- threadexits("devmain: %r");
- }
- sendul(rc, 0);
- threadexits(nil);
-
-}
-
-int
-matchdevcsp(char *info, void *a)
-{
- char sbuf[40];
- int *csps;
-
- csps = a;
- for(; *csps != 0; csps++){
- snprint(sbuf, sizeof(sbuf), "csp %#08ux", *csps);
- if(strstr(info, sbuf) != nil)
- return 0;
- }
- return -1;
-}
-
-int
-finddevs(int (*matchf)(char*,void*), void *farg, char** dirs, int ndirs)
-{
- int fd, i, n, nd, nr;
- char *nm;
- char dbuf[512], fbuf[40];
- Dir *d;
-
- fd = open("/dev/usb", OREAD);
- if(fd < 0)
- sysfatal("/dev/usb: %r");
- nd = dirreadall(fd, &d);
- close(fd);
- if(nd < 2)
- sysfatal("/dev/usb: no devs");
- for(i = n = 0; i < nd && n < ndirs; i++){
- nm = d[i].name;
- if(strcmp(nm, "ctl") == 0 || strstr(nm, ".0") == nil)
- continue;
- snprint(fbuf, sizeof(fbuf), "/dev/usb/%s/ctl", nm);
- fd = open(fbuf, OREAD);
- if(fd < 0)
- continue; /* may be gone */
- nr = read(fd, dbuf, sizeof(dbuf)-1);
- close(fd);
- if(nr < 0)
- continue;
- dbuf[nr] = 0;
- if(strstr(dbuf, "enabled ") != nil && strstr(dbuf, " busy") == nil)
- if(matchf(dbuf, farg) == 0)
- dirs[n++] = smprint("/dev/usb/%s", nm);
- }
- free(d);
- if(usbdebug > 1)
- for(nd = 0; nd < n; nd++)
- fprint(2, "finddevs: %s\n", dirs[nd]);
- return n;
-}
-
-void
-startdevs(char *args, char *argv[], int argc, int (*mf)(char*, void*),
- void *ma, int (*df)(Dev*, int, char**))
-{
- int i, ndirs, ndevs;
- char *dirs[Ndevs];
- char **dp;
- Parg *parg;
- Dev *dev;
- Channel *rc;
-
- if(access("/dev/usb", AEXIST) < 0 && bind("#u", "/dev", MBEFORE) < 0)
- sysfatal("#u: %r");
-
- if(argc > 0){
- ndirs = argc;
- dp = argv;
- }else{
- dp = dirs;
- ndirs = finddevs(mf, ma, dp, Ndevs);
- if(ndirs == nelem(dirs))
- fprint(2, "%s: too many devices\n", argv0);
- }
- ndevs = 0;
- rc = chancreate(sizeof(ulong), 0);
- if(rc == nil)
- sysfatal("no memory");
- for(i = 0; i < ndirs; i++){
- fprint(2, "%s: startdevs: opening #%d %s\n", argv0, i, dp[i]);
- dev = opendev(dp[i]);
- if(dev == nil)
- fprint(2, "%s: %s: %r\n", argv0, dp[i]);
- else if(configdev(dev) < 0){
- fprint(2, "%s: %s: config: %r\n", argv0, dp[i]);
- closedev(dev);
- }else{
- dprint(2, "%s: %U", argv0, dev);
- parg = emallocz(sizeof(Parg), 0);
- parg->args = estrdup(args);
- parg->dev = dev;
- parg->rc = rc;
- parg->f = df;
- proccreate(workproc, parg, Stack);
- if(recvul(rc) == 0)
- ndevs++;
- }
- if(dp != argv)
- free(dirs[i]);
- }
- chanfree(rc);
- if(ndevs == 0)
- sysfatal("no unhandled devices found");
-}
diff --git a/sys/src/cmd/usb/lib/dump.c b/sys/src/cmd/usb/lib/dump.c
deleted file mode 100644
index 8ba766b62..000000000
--- a/sys/src/cmd/usb/lib/dump.c
+++ /dev/null
@@ -1,176 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include <bio.h>
-#include "usb.h"
-
-int usbdebug;
-
-static char *edir[] = {"in", "out", "inout"};
-static char *etype[] = {"ctl", "iso", "bulk", "intr"};
-static char* cnames[] =
-{
- "none", "audio", "comms", "hid", "",
- "", "", "printer", "storage", "hub", "data"
-};
-static char* devstates[] =
-{
- "detached", "attached", "enabled", "assigned", "configured"
-};
-
-char*
-classname(int c)
-{
- static char buf[30];
-
- if(c >= 0 && c < nelem(cnames))
- return cnames[c];
- else{
- seprint(buf, buf+30, "%d", c);
- return buf;
- }
-}
-
-char *
-hexstr(void *a, int n)
-{
- int i;
- char *dbuff, *s, *e;
- uchar *b;
-
- b = a;
- dbuff = s = emallocz(1024, 0);
- *s = 0;
- e = s + 1024;
- for(i = 0; i < n; i++)
- s = seprint(s, e, " %.2ux", b[i]);
- if(s == e)
- fprint(2, "%s: usb/lib: hexdump: bug: small buffer\n", argv0);
- return dbuff;
-}
-
-static char *
-seprintiface(char *s, char *e, Iface *i)
-{
- int j;
- Altc *a;
- Ep *ep;
- char *eds, *ets;
-
- s = seprint(s, e, "\t\tiface csp %s.%uld.%uld\n",
- classname(Class(i->csp)), Subclass(i->csp), Proto(i->csp));
- for(j = 0; j < Naltc; j++){
- a=i->altc[j];
- if(a == nil)
- break;
- s = seprint(s, e, "\t\t alt %d attr %d ival %d",
- j, a->attrib, a->interval);
- if(a->aux != nil)
- s = seprint(s, e, " devspec %p\n", a->aux);
- else
- s = seprint(s, e, "\n");
- }
- for(j = 0; j < Nep; j++){
- ep = i->ep[j];
- if(ep == nil)
- break;
- eds = ets = "";
- if(ep->dir <= nelem(edir))
- eds = edir[ep->dir];
- if(ep->type <= nelem(etype))
- ets = etype[ep->type];
- s = seprint(s, e, "\t\t ep id %d addr %d dir %s type %s"
- " itype %d maxpkt %d ntds %d\n",
- ep->id, ep->addr, eds, ets, ep->isotype,
- ep->maxpkt, ep->ntds);
- }
- return s;
-}
-
-static char*
-seprintconf(char *s, char *e, Usbdev *d, int ci)
-{
- int i;
- Conf *c;
- char *hd;
-
- c = d->conf[ci];
- s = seprint(s, e, "\tconf: cval %d attrib %x %d mA\n",
- c->cval, c->attrib, c->milliamps);
- for(i = 0; i < Niface; i++)
- if(c->iface[i] == nil)
- break;
- else
- s = seprintiface(s, e, c->iface[i]);
- for(i = 0; i < Nddesc; i++)
- if(d->ddesc[i] == nil)
- break;
- else if(d->ddesc[i]->conf == c){
- hd = hexstr((uchar*)&d->ddesc[i]->data,
- d->ddesc[i]->data.bLength);
- s = seprint(s, e, "\t\tdev desc %x[%d]: %s\n",
- d->ddesc[i]->data.bDescriptorType,
- d->ddesc[i]->data.bLength, hd);
- free(hd);
- }
- return s;
-}
-
-int
-Ufmt(Fmt *f)
-{
- int i;
- Dev *d;
- Usbdev *ud;
- char buf[1024];
- char *s, *e;
-
- s = buf;
- e = buf+sizeof(buf);
- d = va_arg(f->args, Dev*);
- if(d == nil)
- return fmtprint(f, "<nildev>\n");
- s = seprint(s, e, "%s", d->dir);
- ud = d->usb;
- if(ud == nil)
- return fmtprint(f, "%s %ld refs\n", buf, d->ref);
- s = seprint(s, e, " csp %s.%uld.%uld",
- classname(Class(ud->csp)), Subclass(ud->csp), Proto(ud->csp));
- s = seprint(s, e, " vid %#ux did %#ux", ud->vid, ud->did);
- s = seprint(s, e, " refs %ld\n", d->ref);
- s = seprint(s, e, "\t%s %s %s\n", ud->vendor, ud->product, ud->serial);
- for(i = 0; i < Nconf; i++){
- if(ud->conf[i] == nil)
- break;
- else
- s = seprintconf(s, e, ud, i);
- }
- return fmtprint(f, "%s", buf);
-}
-
-char*
-estrdup(char *s)
-{
- char *d;
-
- d = strdup(s);
- if(d == nil)
- sysfatal("strdup: %r");
- setmalloctag(d, getcallerpc(&s));
- return d;
-}
-
-void*
-emallocz(ulong size, int zero)
-{
- void *x;
-
- x = malloc(size);
- if(x == nil)
- sysfatal("malloc: %r");
- if(zero)
- memset(x, 0, size);
- setmalloctag(x, getcallerpc(&size));
- return x;
-}
-
diff --git a/sys/src/cmd/usb/lib/fs.c b/sys/src/cmd/usb/lib/fs.c
deleted file mode 100644
index ffb142aa6..000000000
--- a/sys/src/cmd/usb/lib/fs.c
+++ /dev/null
@@ -1,673 +0,0 @@
-/*
- * Framework for USB devices that provide a file tree.
- * The main process (usbd or the driver's main proc)
- * calls fsinit() to start FS operation.
- *
- * One or more drivers call fsstart/fsend to register
- * or unregister their operations for their subtrees.
- *
- * root dir has qids with 0 in high 32 bits.
- * for other files we keep the device id in there.
- * The low 32 bits for directories at / must be 0.
- */
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include <fcall.h>
-#include "usb.h"
-#include "usbfs.h"
-
-#undef dprint
-#define dprint if(usbfsdebug)fprint
-
-typedef struct Rpc Rpc;
-
-enum
-{
- Nproc = 3, /* max nb. of cached FS procs */
-
- Nofid = ~0, /* null value for fid number */
- Notag = ~0, /* null value for tags */
- Dietag = 0xdead, /* fake tag to ask outproc to die */
-
- Stack = 16 * 1024,
-
- /* Fsproc requests */
- Run = 0, /* call f(r) */
- Exit, /* terminate */
-
-};
-
-struct Rpc
-{
- Fcall t;
- Fcall r;
- Fid* fid;
- int flushed;
- Rpc* next;
- char data[Bufsize];
-};
-
-int usbfsdebug;
-
-char Enotfound[] = "file not found";
-char Etoosmall[] = "parameter too small";
-char Eio[] = "i/o error";
-char Eperm[] = "permission denied";
-char Ebadcall[] = "unknown fs call";
-char Ebadfid[] = "fid not found";
-char Einuse[] = "fid already in use";
-char Eisopen[] = "it is already open";
-char Ebadctl[] = "unknown control request";
-
-static char *user;
-static ulong epoch;
-static ulong msgsize = Msgsize;
-static int fsfd = -1;
-static Channel *outc; /* of Rpc* */
-
-static QLock rpclck; /* protect vars in this block */
-static Fid *freefids;
-static Fid *fids;
-static Rpc *freerpcs;
-static Rpc *rpcs;
-
-static Channel*procc;
-static Channel*endc;
-
-static Usbfs* fsops;
-
-static void fsioproc(void*);
-
-static void
-schedproc(void*)
-{
- Channel *proc[Nproc];
- int nproc;
- Channel *p;
-
- Alt a[] =
- {
- {procc, &proc[0], CHANSND},
- {endc, &p, CHANRCV},
- {nil, nil, CHANEND}
- };
- memset(proc, 0, sizeof(proc));
- nproc = 0;
- for(;;){
- if(nproc == 0){
- proc[0] = chancreate(sizeof(Rpc*), 0);
- proccreate(fsioproc, proc[0], Stack);
- nproc++;
- }
- switch(alt(a)){
- case 0:
- proc[0] = nil;
- if(nproc > 1){
- proc[0] = proc[nproc-1];
- proc[nproc-1] = nil;
- }
- nproc--;
- break;
- case 1:
- if(nproc < nelem(proc))
- proc[nproc++] = p;
- else
- sendp(p, nil);
- break;
- default:
- sysfatal("alt");
- }
- }
-}
-
-static void
-dump(void)
-{
- Rpc *rpc;
- Fid *fid;
-
- qlock(&rpclck);
- fprint(2, "dump:\n");
- for(rpc = rpcs; rpc != nil; rpc = rpc->next)
- fprint(2, "rpc %#p %F next %#p\n", rpc, &rpc->t, rpc->next);
- for(fid = fids; fid != nil; fid = fid->next)
- fprint(2, "fid %d qid %#llux omode %d aux %#p\n",
- fid->fid, fid->qid.path, fid->omode, fid->aux);
- fprint(2, "\n");
- qunlock(&rpclck);
-}
-
-static Rpc*
-newrpc(void)
-{
- Rpc *r;
-
- qlock(&rpclck);
- r = freerpcs;
- if(r != nil)
- freerpcs = r->next;
- else
- r = emallocz(sizeof(Rpc), 0);
- r->next = rpcs;
- rpcs = r;
- r->t.tag = r->r.tag = Notag;
- r->t.fid = r->r.fid = Nofid;
- r->t.type = r->r.type = 0;
- r->flushed = 0;
- r->fid = nil;
- r->r.data = (char*)r->data;
- qunlock(&rpclck);
- return r;
-}
-
-static void
-freerpc(Rpc *r)
-{
- Rpc **l;
- if(r == nil)
- return;
- qlock(&rpclck);
- for(l = &rpcs; *l != nil && *l != r; l = &(*l)->next)
- ;
- assert(*l == r);
- *l = r->next;
- r->next = freerpcs;
- freerpcs = r;
- r->t.type = 0;
- r->t.tag = 0x77777777;
- qunlock(&rpclck);
-}
-
-static void
-flushrpc(int tag)
-{
- Rpc *r;
-
- qlock(&rpclck);
- for(r = rpcs; r != nil; r = r->next)
- if(r->t.tag == tag){
- r->flushed = 1;
- break;
- }
- qunlock(&rpclck);
-}
-
-static Fid*
-getfid(int fid, int alloc)
-{
- Fid *f;
-
- qlock(&rpclck);
- for(f = fids; f != nil && f->fid != fid; f = f->next)
- ;
- if(f != nil && alloc != 0){ /* fid in use */
- qunlock(&rpclck);
- return nil;
- }
- if(f == nil && alloc != 0){
- if(freefids != nil){
- f = freefids;
- freefids = freefids->next;
- }else
- f = emallocz(sizeof(Fid), 1);
- f->fid = fid;
- f->aux = nil;
- f->omode = ONONE;
- f->next = fids;
- fids = f;
- }
- qunlock(&rpclck);
- return f;
-}
-
-static void
-freefid(Fid *f)
-{
- Fid **l;
-
- if(f == nil)
- return;
- if(fsops->clunk != nil)
- fsops->clunk(fsops, f);
- qlock(&rpclck);
- for(l = &fids; *l != nil && *l != f; l = &(*l)->next)
- ;
- assert(*l == f);
- *l = f->next;
- f->next = freefids;
- freefids = f;
- qunlock(&rpclck);
-}
-
-static Rpc*
-fserror(Rpc *rpc, char* fmt, ...)
-{
- va_list arg;
- char *c;
-
- va_start(arg, fmt);
- c = (char*)rpc->data;
- vseprint(c, c+sizeof(rpc->data), fmt, arg);
- va_end(arg);
- rpc->r.type = Rerror;
- rpc->r.ename = (char*)rpc->data;
- return rpc;
-}
-
-static Rpc*
-fsversion(Rpc *r)
-{
- if(r->t.msize < 256)
- return fserror(r, Etoosmall);
- if(strncmp(r->t.version, "9P2000", 6) != 0)
- return fserror(r, "wrong version");
- if(r->t.msize < msgsize)
- msgsize = r->t.msize;
- r->r.msize = msgsize;
- r->r.version = "9P2000";
- return r;
-}
-
-static Rpc*
-fsattach(Rpc *r)
-{
- static int already;
-
- /* Reload user because at boot it could be still none */
- user=getuser();
- if(already++ > 0 && strcmp(r->t.uname, user) != 0)
- return fserror(r, Eperm);
- if(r->fid == nil)
- return fserror(r, Einuse);
-
- r->r.qid.type = QTDIR;
- r->r.qid.path = fsops->qid;
- r->r.qid.vers = 0;
- r->fid->qid = r->r.qid;
- return r;
-}
-
-static Rpc*
-fswalk(Rpc *r)
-{
- int i;
- Fid *nfid, *ofid;
-
- if(r->fid->omode != ONONE)
- return fserror(r, Eisopen);
-
- nfid = nil;
- ofid = r->fid;
- if(r->t.newfid != r->t.fid){
- nfid = getfid(r->t.newfid, 1);
- if(nfid == nil)
- return fserror(r, Einuse);
- nfid->qid = r->fid->qid;
- if(fsops->clone != nil)
- fsops->clone(fsops, ofid, nfid);
- else
- nfid->aux = r->fid->aux;
- r->fid = nfid;
- }
- r->r.nwqid = 0;
- for(i = 0; i < r->t.nwname; i++)
- if(fsops->walk(fsops, r->fid, r->t.wname[i]) < 0)
- break;
- else
- r->r.wqid[i] = r->fid->qid;
- r->r.nwqid = i;
- if(i != r->t.nwname && r->t.nwname > 0){
- if(nfid != nil)
- freefid(nfid);
- r->fid = ofid;
- }
- if(i == 0 && r->t.nwname > 0)
- return fserror(r, "%r");
- return r;
-}
-
-static void
-fsioproc(void* a)
-{
- long rc;
- Channel *p = a;
- Rpc *rpc;
- Fcall *t, *r;
- Fid *fid;
-
- dprint(2, "%s: fsioproc pid %d\n", argv0, getpid());
- while((rpc = recvp(p)) != nil){
- t = &rpc->t;
- r = &rpc->r;
- fid = rpc->fid;
- rc = -1;
- dprint(2, "%s: fsioproc pid %d: req %d\n", argv0, getpid(), t->type);
- switch(t->type){
- case Topen:
- rc = fsops->open(fsops, fid, t->mode);
- if(rc >= 0){
- r->iounit = 0;
- r->qid = fid->qid;
- fid->omode = t->mode & 3;
- }
- break;
- case Tread:
- rc = fsops->read(fsops, fid, r->data, t->count, t->offset);
- if(rc >= 0){
- if(rc > t->count)
- print("%s: bug: read %ld bytes > %ud wanted\n",
- argv0, rc, t->count);
- r->count = rc;
- }
- /*
- * TODO: if we encounter a long run of continuous read
- * errors, we should do something more drastic so that
- * our caller doesn't just spin its wheels forever.
- */
- break;
- case Twrite:
- rc = fsops->write(fsops, fid, t->data, t->count, t->offset);
- r->count = rc;
- break;
- default:
- sysfatal("fsioproc: bad type");
- }
- if(rc < 0)
- sendp(outc, fserror(rpc, "%r"));
- else
- sendp(outc, rpc);
- sendp(endc, p);
- }
- chanfree(p);
- dprint(2, "%s: fsioproc %d exiting\n", argv0, getpid());
- threadexits(nil);
-}
-
-static Rpc*
-fsopen(Rpc *r)
-{
- Channel *p;
-
- if(r->fid->omode != ONONE)
- return fserror(r, Eisopen);
- if((r->t.mode & 3) != OREAD && (r->fid->qid.type & QTDIR) != 0)
- return fserror(r, Eperm);
- p = recvp(procc);
- sendp(p, r);
- return nil;
-}
-
-int
-usbdirread(Usbfs*f, Qid q, char *data, long cnt, vlong off, Dirgen gen, void *arg)
-{
- int i, n, nd;
- char name[Namesz];
- Dir d;
-
- memset(&d, 0, sizeof(d));
- d.name = name;
- d.uid = d.gid = d.muid = user;
- d.atime = time(nil);
- d.mtime = epoch;
- d.length = 0;
- for(i = n = 0; gen(f, q, i, &d, arg) >= 0; i++){
- if(usbfsdebug > 1)
- fprint(2, "%s: dir %d q %#llux: %D\n", argv0, i, q.path, &d);
- nd = convD2M(&d, (uchar*)data+n, cnt-n);
- if(nd <= BIT16SZ)
- break;
- if(off > 0)
- off -= nd;
- else
- n += nd;
- d.name = name;
- d.uid = d.gid = d.muid = user;
- d.atime = time(nil);
- d.mtime = epoch;
- d.length = 0;
- }
- return n;
-}
-
-long
-usbreadbuf(void *data, long count, vlong offset, void *buf, long n)
-{
- if(offset >= n)
- return 0;
- if(offset + count > n)
- count = n - offset;
- memmove(data, (char*)buf + offset, count);
- return count;
-}
-
-static Rpc*
-fsread(Rpc *r)
-{
- Channel *p;
-
- if(r->fid->omode != OREAD && r->fid->omode != ORDWR)
- return fserror(r, Eperm);
- p = recvp(procc);
- sendp(p, r);
- return nil;
-}
-
-static Rpc*
-fswrite(Rpc *r)
-{
- Channel *p;
-
- if(r->fid->omode != OWRITE && r->fid->omode != ORDWR)
- return fserror(r, Eperm);
- p = recvp(procc);
- sendp(p, r);
- return nil;
-}
-
-static Rpc*
-fsclunk(Rpc *r)
-{
- freefid(r->fid);
- return r;
-}
-
-static Rpc*
-fsno(Rpc *r)
-{
- return fserror(r, Eperm);
-}
-
-static Rpc*
-fsstat(Rpc *r)
-{
- Dir d;
- char name[Namesz];
-
- memset(&d, 0, sizeof(d));
- d.name = name;
- d.uid = d.gid = d.muid = user;
- d.atime = time(nil);
- d.mtime = epoch;
- d.length = 0;
- if(fsops->stat(fsops, r->fid->qid, &d) < 0)
- return fserror(r, "%r");
- r->r.stat = (uchar*)r->data;
- r->r.nstat = convD2M(&d, (uchar*)r->data, msgsize);
- return r;
-}
-
-static Rpc*
-fsflush(Rpc *r)
-{
- /*
- * Flag it as flushed and respond.
- * Either outproc will reply to the flushed request
- * before responding to flush, or it will never reply to it.
- * Note that we do NOT abort the ongoing I/O.
- * That might leave the affected endpoints in a failed
- * state. Instead, we pretend the request is aborted.
- *
- * Only open, read, and write are processed
- * by auxiliary processes and other requests wil never be
- * flushed in practice.
- */
- flushrpc(r->t.oldtag);
- return r;
-}
-
-Rpc* (*fscalls[])(Rpc*) = {
- [Tversion] fsversion,
- [Tauth] fsno,
- [Tattach] fsattach,
- [Twalk] fswalk,
- [Topen] fsopen,
- [Tcreate] fsno,
- [Tread] fsread,
- [Twrite] fswrite,
- [Tclunk] fsclunk,
- [Tremove] fsno,
- [Tstat] fsstat,
- [Twstat] fsno,
- [Tflush] fsflush,
-};
-
-static void
-outproc(void*)
-{
- static uchar buf[Bufsize];
- Rpc *rpc;
- int nw;
- static int once = 0;
-
- if(once++ != 0)
- sysfatal("more than one outproc");
- for(;;){
- do
- rpc = recvp(outc);
- while(rpc == nil); /* a delayed reply */
- if(rpc->t.tag == Dietag)
- break;
- if(rpc->flushed){
- dprint(2, "outproc: tag %d flushed\n", rpc->t.tag);
- freerpc(rpc);
- continue;
- }
- dprint(2, "-> %F\n", &rpc->r);
- nw = convS2M(&rpc->r, buf, sizeof(buf));
- if(nw == sizeof(buf))
- fprint(2, "%s: outproc: buffer is too small\n", argv0);
- if(nw <= BIT16SZ)
- fprint(2, "%s: conS2M failed\n", argv0);
- else if(write(fsfd, buf, nw) != nw){
- fprint(2, "%s: outproc: write: %r", argv0);
- /* continue and let the reader abort us */
- }
- if(usbfsdebug > 1)
- dump();
- freerpc(rpc);
- }
- dprint(2, "%s: outproc: exiting\n", argv0);
-}
-
-static void
-usbfs(void*)
-{
- Rpc *rpc;
- int nr;
- static int once = 0;
-
- if(once++ != 0)
- sysfatal("more than one usbfs proc");
-
- outc = chancreate(sizeof(Rpc*), 1);
- procc = chancreate(sizeof(Channel*), 0);
- endc = chancreate(sizeof(Channel*), 0);
- if(outc == nil || procc == nil || endc == nil)
- sysfatal("chancreate: %r");
- threadcreate(schedproc, nil, Stack);
- proccreate(outproc, nil, Stack);
- for(;;){
- rpc = newrpc();
- do{
- nr = read9pmsg(fsfd, rpc->data, sizeof(rpc->data));
- }while(nr == 0);
- if(nr < 0){
- dprint(2, "%s: usbfs: read: '%r'", argv0);
- if(fsops->end != nil)
- fsops->end(fsops);
- else
- closedev(fsops->dev);
- rpc->t.tag = Dietag;
- sendp(outc, rpc);
- break;
- }
- if(convM2S((uchar*)rpc->data, nr, &rpc->t) <=0){
- dprint(2, "%s: convM2S failed\n", argv0);
- freerpc(rpc);
- continue;
- }
- dprint(2, "<- %F\n", &rpc->t);
- rpc->r.tag = rpc->t.tag;
- rpc->r.type = rpc->t.type + 1;
- rpc->r.fid = rpc->t.fid;
- if(fscalls[rpc->t.type] == nil){
- sendp(outc, fserror(rpc, Ebadcall));
- continue;
- }
- if(rpc->t.fid != Nofid){
- if(rpc->t.type == Tattach)
- rpc->fid = getfid(rpc->t.fid, 1);
- else
- rpc->fid = getfid(rpc->t.fid, 0);
- if(rpc->fid == nil){
- sendp(outc, fserror(rpc, Ebadfid));
- continue;
- }
- }
- sendp(outc, fscalls[rpc->t.type](rpc));
- }
- dprint(2, "%s: ubfs: eof: exiting\n", argv0);
-}
-
-void
-usbfsinit(char* srv, char *mnt, Usbfs *f, int flag)
-{
- int fd[2];
- int sfd;
- int afd;
- char sfile[40];
-
- fsops = f;
- if(pipe(fd) < 0)
- sysfatal("pipe: %r");
- user = getuser();
- epoch = time(nil);
-
- fmtinstall('D', dirfmt);
- fmtinstall('M', dirmodefmt);
- fmtinstall('F', fcallfmt);
- fsfd = fd[1];
- procrfork(usbfs, nil, Stack, RFNAMEG); /* no RFFDG */
- if(srv != nil){
- snprint(sfile, sizeof(sfile), "#s/%s", srv);
- remove(sfile);
- sfd = create(sfile, OWRITE, 0660);
- if(sfd < 0)
- sysfatal("post: %r");
- snprint(sfile, sizeof(sfile), "%d", fd[0]);
- if(write(sfd, sfile, strlen(sfile)) != strlen(sfile))
- sysfatal("post: %r");
- close(sfd);
- }
- if(mnt != nil){
- sfd = dup(fd[0], -1); /* debug */
- afd = fauth(sfd, "");
- if(afd >= 0)
- sysfatal("authentication required??");
- if(mount(sfd, -1, mnt, flag, "") < 0)
- sysfatal("mount: %r");
- }
- close(fd[0]);
-}
-
diff --git a/sys/src/cmd/usb/lib/fsdir.c b/sys/src/cmd/usb/lib/fsdir.c
deleted file mode 100644
index 96e972ba5..000000000
--- a/sys/src/cmd/usb/lib/fsdir.c
+++ /dev/null
@@ -1,420 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include <fcall.h>
-#include "usb.h"
-#include "usbfs.h"
-
-typedef struct Rpc Rpc;
-
-enum
-{
- Incr = 3, /* increments for fs array */
- Dtop = 0, /* high 32 bits for / */
- Qdir = 0, /* low 32 bits for /devdir */
-};
-
-QLock fslck;
-static Usbfs** fs;
-static int nfs;
-static int fsused;
-static int exitonclose = 1;
-
-void
-usbfsexits(int y)
-{
- exitonclose = y;
-}
-
-static int
-qiddev(uvlong path)
-{
- return (int)(path>>32) & 0xFF;
-}
-
-static int
-qidfile(uvlong path)
-{
- return (int)(path & 0xFFFFFFFFULL);
-}
-
-static uvlong
-mkqid(int qd, int qf)
-{
- return ((uvlong)qd << 32) | (uvlong)qf;
-}
-
-void
-usbfsdirdump(void)
-{
- int i;
-
- qlock(&fslck);
- fprint(2, "%s: fs list: (%d used %d total)\n", argv0, fsused, nfs);
- for(i = 1; i < nfs; i++)
- if(fs[i] != nil)
- if(fs[i]->dev != nil)
- fprint(2, "%s\t%s dev %#p refs %ld\n",
- argv0, fs[i]->name, fs[i]->dev, fs[i]->dev->ref);
- else
- fprint(2, "%s:\t%s\n", argv0, fs[i]->name);
- qunlock(&fslck);
-}
-
-void
-usbfsadd(Usbfs *dfs)
-{
- int i, j;
-
- dprint(2, "%s: fsadd %s\n", argv0, dfs->name);
- qlock(&fslck);
- for(i = 1; i < nfs; i++)
- if(fs[i] == nil)
- break;
- if(i >= nfs){
- if((nfs%Incr) == 0){
- fs = realloc(fs, sizeof(Usbfs*) * (nfs+Incr));
- if(fs == nil)
- sysfatal("realloc: %r");
- for(j = nfs; j < nfs+Incr; j++)
- fs[j] = nil;
- }
- if(nfs == 0) /* do not use entry 0 */
- nfs++;
- fs[nfs++] = dfs;
- }else
- fs[i] = dfs;
- dfs->qid = mkqid(i, 0);
- fsused++;
- qunlock(&fslck);
-}
-
-static void
-usbfsdelnth(int i)
-{
- if(fs[i] != nil){
- dprint(2, "%s: fsdel %s", argv0, fs[i]->name);
- if(fs[i]->dev != nil){
- dprint(2, " dev %#p ref %ld\n",
- fs[i]->dev, fs[i]->dev->ref);
- }else
- dprint(2, "no dev\n");
- if(fs[i]->end != nil)
- fs[i]->end(fs[i]);
- closedev(fs[i]->dev);
- fsused--;
- }
- fs[i] = nil;
- if(fsused == 0 && exitonclose != 0){
- fprint(2, "%s: all file systems gone: exiting\n", argv0);
- threadexitsall(nil);
- }
-}
-
-void
-usbfsdel(Usbfs *dfs)
-{
- int i;
-
- qlock(&fslck);
- for(i = 0; i < nfs; i++)
- if(dfs == nil || fs[i] == dfs){
- usbfsdelnth(i);
- if(dfs != nil)
- break;
- }
- qunlock(&fslck);
-}
-
-static void
-fsend(Usbfs*)
-{
- dprint(2, "%s: fsend\n", argv0);
- usbfsdel(nil);
-}
-
-void
-usbfsgone(char *dir)
-{
- int i;
-
- qlock(&fslck);
- /* devices may have more than one fs */
- for(i = 0; i < nfs; i++)
- if(fs[i] != nil && fs[i]->dev != nil)
- if(strcmp(fs[i]->dev->dir, dir) == 0)
- usbfsdelnth(i);
- qunlock(&fslck);
-}
-
-static void
-fsclone(Usbfs*, Fid *o, Fid *n)
-{
- int qd;
- Dev *dev;
- void (*xfsclone)(Usbfs *fs, Fid *of, Fid *nf);
-
- xfsclone = nil;
- dev = nil;
- qd = qiddev(o->qid.path);
- qlock(&fslck);
- if(qd != Dtop && fs[qd] != nil && fs[qd]->clone != nil){
- dev = fs[qd]->dev;
- if(dev != nil)
- incref(dev);
- xfsclone = fs[qd]->clone;
- }
- qunlock(&fslck);
- if(xfsclone != nil){
- xfsclone(fs[qd], o, n);
- }
- if(dev != nil)
- closedev(dev);
-}
-
-static int
-fswalk(Usbfs*, Fid *fid, char *name)
-{
- Qid q;
- int qd, qf;
- int i;
- int rc;
- Dev *dev;
- Dir d;
- char dname[Namesz];
-
- int (*xfswalk)(Usbfs *fs, Fid *f, char *name);
-
- q = fid->qid;
- qd = qiddev(q.path);
- qf = qidfile(q.path);
-
- q.type = QTDIR;
- q.vers = 0;
- if(strcmp(name, "..") == 0)
- if(qd == Dtop || qf == Qdir){
- q.path = mkqid(Dtop, Qdir);
- fid->qid = q;
- return 0;
- }
- if(qd != 0){
- qlock(&fslck);
- if(fs[qd] == nil){
- qunlock(&fslck);
- werrstr(Eio);
- return -1;
- }
- dev = fs[qd]->dev;
- if(dev != nil)
- incref(dev);
- xfswalk = fs[qd]->walk;
- qunlock(&fslck);
- rc = xfswalk(fs[qd], fid, name);
- if(dev != nil)
- closedev(dev);
- return rc;
- }
- qlock(&fslck);
- for(i = 0; i < nfs; i++)
- if(fs[i] != nil && strcmp(name, fs[i]->name) == 0){
- q.path = mkqid(i, Qdir);
- d.name = dname;
- fs[i]->stat(fs[i], q, &d); /* may be a file */
- fid->qid = d.qid;
- qunlock(&fslck);
- return 0;
- }
- qunlock(&fslck);
- werrstr(Enotfound);
- return -1;
-}
-
-static int
-fsopen(Usbfs*, Fid *fid, int mode)
-{
- int qd;
- int rc;
- Dev *dev;
- int (*xfsopen)(Usbfs *fs, Fid *f, int mode);
-
- qd = qiddev(fid->qid.path);
- if(qd == Dtop)
- return 0;
- qlock(&fslck);
- if(fs[qd] == nil){
- qunlock(&fslck);
- werrstr(Eio);
- return -1;
- }
- dev = fs[qd]->dev;
- if(dev != nil)
- incref(dev);
- xfsopen = fs[qd]->open;
- qunlock(&fslck);
- if(xfsopen != nil)
- rc = xfsopen(fs[qd], fid, mode);
- else
- rc = 0;
- if(dev != nil)
- closedev(dev);
- return rc;
-}
-
-static int
-dirgen(Usbfs*, Qid, int n, Dir *d, void *)
-{
- int i;
- Dev *dev;
- char *nm;
-
- qlock(&fslck);
- for(i = 0; i < nfs; i++)
- if(fs[i] != nil && n-- == 0){
- d->qid.type = QTDIR;
- d->qid.path = mkqid(i, Qdir);
- d->qid.vers = 0;
- dev = fs[i]->dev;
- if(dev != nil)
- incref(dev);
- nm = d->name;
- fs[i]->stat(fs[i], d->qid, d);
- d->name = nm;
- strncpy(d->name, fs[i]->name, Namesz);
- if(dev != nil)
- closedev(dev);
- qunlock(&fslck);
- return 0;
- }
- qunlock(&fslck);
- return -1;
-}
-
-static long
-fsread(Usbfs*, Fid *fid, void *data, long cnt, vlong off)
-{
- int qd;
- int rc;
- Dev *dev;
- Qid q;
- long (*xfsread)(Usbfs *fs, Fid *f, void *data, long count, vlong );
-
- q = fid->qid;
- qd = qiddev(q.path);
- if(qd == Dtop)
- return usbdirread(nil, q, data, cnt, off, dirgen, nil);
- qlock(&fslck);
- if(fs[qd] == nil){
- qunlock(&fslck);
- werrstr(Eio);
- return -1;
- }
- dev = fs[qd]->dev;
- if(dev != nil)
- incref(dev);
- xfsread = fs[qd]->read;
- qunlock(&fslck);
- rc = xfsread(fs[qd], fid, data, cnt, off);
- if(dev != nil)
- closedev(dev);
- return rc;
-}
-
-static long
-fswrite(Usbfs*, Fid *fid, void *data, long cnt, vlong off)
-{
- int qd;
- int rc;
- Dev *dev;
- long (*xfswrite)(Usbfs *fs, Fid *f, void *data, long count, vlong );
-
- qd = qiddev(fid->qid.path);
- if(qd == Dtop)
- sysfatal("fswrite: not for usbd /");
- qlock(&fslck);
- if(fs[qd] == nil){
- qunlock(&fslck);
- werrstr(Eio);
- return -1;
- }
- dev = fs[qd]->dev;
- if(dev != nil)
- incref(dev);
- xfswrite = fs[qd]->write;
- qunlock(&fslck);
- rc = xfswrite(fs[qd], fid, data, cnt, off);
- if(dev != nil)
- closedev(dev);
- return rc;
-}
-
-
-static void
-fsclunk(Usbfs*, Fid* fid)
-{
- int qd;
- Dev *dev;
- void (*xfsclunk)(Usbfs *fs, Fid *f);
-
- dev = nil;
- qd = qiddev(fid->qid.path);
- qlock(&fslck);
- if(qd != Dtop && fs[qd] != nil){
- dev=fs[qd]->dev;
- if(dev != nil)
- incref(dev);
- xfsclunk = fs[qd]->clunk;
- }else
- xfsclunk = nil;
- qunlock(&fslck);
- if(xfsclunk != nil){
- xfsclunk(fs[qd], fid);
- }
- if(dev != nil)
- closedev(dev);
-}
-
-static int
-fsstat(Usbfs*, Qid qid, Dir *d)
-{
- int qd;
- int rc;
- Dev *dev;
- int (*xfsstat)(Usbfs *fs, Qid q, Dir *d);
-
- qd = qiddev(qid.path);
- if(qd == Dtop){
- d->qid = qid;
- d->name = "usb";
- d->length = 0;
- d->mode = 0555|DMDIR;
- return 0;
- }
- qlock(&fslck);
- if(fs[qd] == nil){
- qunlock(&fslck);
- werrstr(Eio);
- return -1;
- }
- xfsstat = fs[qd]->stat;
- dev = fs[qd]->dev;
- if(dev != nil)
- incref(dev);
- qunlock(&fslck);
- rc = xfsstat(fs[qd], qid, d);
- if(dev != nil)
- closedev(dev);
- return rc;
-}
-
-Usbfs usbdirfs =
-{
- .walk = fswalk,
- .clone = fsclone,
- .clunk = fsclunk,
- .open = fsopen,
- .read = fsread,
- .write = fswrite,
- .stat = fsstat,
- .end = fsend,
-};
-
diff --git a/sys/src/cmd/usb/lib/mkfile b/sys/src/cmd/usb/lib/mkfile
deleted file mode 100644
index b92610d43..000000000
--- a/sys/src/cmd/usb/lib/mkfile
+++ /dev/null
@@ -1,29 +0,0 @@
-</$objtype/mkfile
-
-LIB=usb.a$O
-OFILES=\
- dev.$O\
- devs.$O\
- dump.$O\
- parse.$O\
- fs.$O\
- fsdir.$O\
-
-HFILES=\
- usb.h\
- usbfs.h\
-
-
-UPDATE=\
- $HFILES\
- ${OFILES:%.$O=%.c}\
- mkfile\
-
-</sys/src/cmd/mklib
-
-install:V: $LIB
- date
-safeinstall:V: install
-safeinstallall:V: installall
-nuke:V:
- rm -f *.[$OS] y.tab.? y.output y.error *.a[$OS]
diff --git a/sys/src/cmd/usb/lib/parse.c b/sys/src/cmd/usb/lib/parse.c
deleted file mode 100644
index 642c427a2..000000000
--- a/sys/src/cmd/usb/lib/parse.c
+++ /dev/null
@@ -1,270 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include <bio.h>
-#include "usb.h"
-
-int
-parsedev(Dev *xd, uchar *b, int n)
-{
- Usbdev *d;
- DDev *dd;
- char *hd;
-
- d = xd->usb;
- assert(d != nil);
- dd = (DDev*)b;
- if(usbdebug>1){
- hd = hexstr(b, Ddevlen);
- fprint(2, "%s: parsedev %s: %s\n", argv0, xd->dir, hd);
- free(hd);
- }
- if(dd->bLength < Ddevlen){
- werrstr("short dev descr. (%d < %d)", dd->bLength, Ddevlen);
- return -1;
- }
- if(dd->bDescriptorType != Ddev){
- werrstr("%d is not a dev descriptor", dd->bDescriptorType);
- return -1;
- }
- d->csp = CSP(dd->bDevClass, dd->bDevSubClass, dd->bDevProtocol);
- d->ep[0]->maxpkt = xd->maxpkt = dd->bMaxPacketSize0;
- d->class = dd->bDevClass;
- d->nconf = dd->bNumConfigurations;
- if(d->nconf == 0)
- dprint(2, "%s: %s: no configurations\n", argv0, xd->dir);
- d->vid = GET2(dd->idVendor);
- d->did = GET2(dd->idProduct);
- d->dno = GET2(dd->bcdDev);
- d->vsid = dd->iManufacturer;
- d->psid = dd->iProduct;
- d->ssid = dd->iSerialNumber;
- if(n > Ddevlen && usbdebug>1)
- fprint(2, "%s: %s: parsedev: %d bytes left",
- argv0, xd->dir, n - Ddevlen);
- return Ddevlen;
-}
-
-static int
-parseiface(Usbdev *d, Conf *c, uchar *b, int n, Iface **ipp, Altc **app)
-{
- int class, subclass, proto;
- int ifid, altid;
- DIface *dip;
- Iface *ip;
-
- assert(d != nil && c != nil);
- if(n < Difacelen){
- werrstr("short interface descriptor");
- return -1;
- }
- dip = (DIface *)b;
- ifid = dip->bInterfaceNumber;
- if(ifid < 0 || ifid >= nelem(c->iface)){
- werrstr("bad interface number %d", ifid);
- return -1;
- }
- if(c->iface[ifid] == nil)
- c->iface[ifid] = emallocz(sizeof(Iface), 1);
- ip = c->iface[ifid];
- class = dip->bInterfaceClass;
- subclass = dip->bInterfaceSubClass;
- proto = dip->bInterfaceProtocol;
- ip->csp = CSP(class, subclass, proto);
- if(d->csp == 0) /* use csp from 1st iface */
- d->csp = ip->csp; /* if device has none */
- if(d->class == 0)
- d->class = class;
- ip->id = ifid;
- if(c == d->conf[0] && ifid == 0) /* ep0 was already there */
- d->ep[0]->iface = ip;
- altid = dip->bAlternateSetting;
- if(altid < 0 || altid >= nelem(ip->altc)){
- werrstr("bad alternate conf. number %d", altid);
- return -1;
- }
- if(ip->altc[altid] == nil)
- ip->altc[altid] = emallocz(sizeof(Altc), 1);
- *ipp = ip;
- *app = ip->altc[altid];
- return Difacelen;
-}
-
-extern Ep* mkep(Usbdev *, int);
-
-static int
-parseendpt(Usbdev *d, Conf *c, Iface *ip, Altc *altc, uchar *b, int n, Ep **epp)
-{
- int i, dir, epid;
- Ep *ep;
- DEp *dep;
-
- assert(d != nil && c != nil && ip != nil && altc != nil);
- if(n < Deplen){
- werrstr("short endpoint descriptor");
- return -1;
- }
- dep = (DEp *)b;
- altc->attrib = dep->bmAttributes; /* here? */
- altc->interval = dep->bInterval;
-
- epid = dep->bEndpointAddress & 0xF;
- assert(epid < nelem(d->ep));
- if(dep->bEndpointAddress & 0x80)
- dir = Ein;
- else
- dir = Eout;
- ep = d->ep[epid];
- if(ep == nil){
- ep = mkep(d, epid);
- ep->dir = dir;
- }else if((ep->addr & 0x80) != (dep->bEndpointAddress & 0x80))
- ep->dir = Eboth;
- ep->maxpkt = GET2(dep->wMaxPacketSize);
- ep->ntds = 1 + ((ep->maxpkt >> 11) & 3);
- ep->maxpkt &= 0x7FF;
- ep->addr = dep->bEndpointAddress;
- ep->type = dep->bmAttributes & 0x03;
- ep->isotype = (dep->bmAttributes>>2) & 0x03;
- ep->conf = c;
- ep->iface = ip;
- for(i = 0; i < nelem(ip->ep); i++)
- if(ip->ep[i] == nil)
- break;
- if(i == nelem(ip->ep)){
- werrstr("parseendpt: bug: too many end points on interface "
- "with csp %#lux", ip->csp);
- fprint(2, "%s: %r\n", argv0);
- return -1;
- }
- *epp = ip->ep[i] = ep;
- return Dep;
-}
-
-static char*
-dname(int dtype)
-{
- switch(dtype){
- case Ddev: return "device";
- case Dconf: return "config";
- case Dstr: return "string";
- case Diface: return "interface";
- case Dep: return "endpoint";
- case Dreport: return "report";
- case Dphysical: return "phys";
- default: return "desc";
- }
-}
-
-int
-parsedesc(Usbdev *d, Conf *c, uchar *b, int n)
-{
- int len, nd, tot;
- Iface *ip;
- Ep *ep;
- Altc *altc;
- char *hd;
-
- assert(d != nil && c != nil);
- tot = 0;
- ip = nil;
- ep = nil;
- altc = nil;
- for(nd = 0; nd < nelem(d->ddesc); nd++)
- if(d->ddesc[nd] == nil)
- break;
-
- while(n > 2 && b[0] != 0 && b[0] <= n){
- len = b[0];
- if(usbdebug>1){
- hd = hexstr(b, len);
- fprint(2, "%s:\t\tparsedesc %s %x[%d] %s\n",
- argv0, dname(b[1]), b[1], b[0], hd);
- free(hd);
- }
- switch(b[1]){
- case Ddev:
- case Dconf:
- werrstr("unexpected descriptor %d", b[1]);
- ddprint(2, "%s\tparsedesc: %r", argv0);
- break;
- case Diface:
- if(parseiface(d, c, b, n, &ip, &altc) < 0){
- ddprint(2, "%s\tparsedesc: %r\n", argv0);
- return -1;
- }
- break;
- case Dep:
- if(ip == nil || altc == nil){
- werrstr("unexpected endpoint descriptor");
- break;
- }
- if(parseendpt(d, c, ip, altc, b, n, &ep) < 0){
- ddprint(2, "%s\tparsedesc: %r\n", argv0);
- return -1;
- }
- break;
- default:
- if(nd == nelem(d->ddesc)){
- fprint(2, "%s: parsedesc: too many "
- "device-specific descriptors for device"
- " %s %s\n",
- argv0, d->vendor, d->product);
- break;
- }
- d->ddesc[nd] = emallocz(sizeof(Desc)+b[0], 0);
- d->ddesc[nd]->iface = ip;
- d->ddesc[nd]->ep = ep;
- d->ddesc[nd]->altc = altc;
- d->ddesc[nd]->conf = c;
- memmove(&d->ddesc[nd]->data, b, len);
- ++nd;
- }
- n -= len;
- b += len;
- tot += len;
- }
- return tot;
-}
-
-int
-parseconf(Usbdev *d, Conf *c, uchar *b, int n)
-{
- DConf* dc;
- int l;
- int nr;
- char *hd;
-
- assert(d != nil && c != nil);
- dc = (DConf*)b;
- if(usbdebug>1){
- hd = hexstr(b, Dconflen);
- fprint(2, "%s:\tparseconf %s\n", argv0, hd);
- free(hd);
- }
- if(dc->bLength < Dconflen){
- werrstr("short configuration descriptor");
- return -1;
- }
- if(dc->bDescriptorType != Dconf){
- werrstr("not a configuration descriptor");
- return -1;
- }
- c->cval = dc->bConfigurationValue;
- c->attrib = dc->bmAttributes;
- c->milliamps = dc->MaxPower*2;
- l = GET2(dc->wTotalLength);
- if(n < l){
- werrstr("truncated configuration info");
- return -1;
- }
- n -= Dconflen;
- b += Dconflen;
- nr = 0;
- if(n > 0 && (nr=parsedesc(d, c, b, n)) < 0)
- return -1;
- n -= nr;
- if(n > 0 && usbdebug>1)
- fprint(2, "%s:\tparseconf: %d bytes left\n", argv0, n);
- return l;
-}
diff --git a/sys/src/cmd/usb/lib/usb.h b/sys/src/cmd/usb/lib/usb.h
deleted file mode 100644
index 072f6e030..000000000
--- a/sys/src/cmd/usb/lib/usb.h
+++ /dev/null
@@ -1,361 +0,0 @@
-typedef struct Altc Altc;
-typedef struct Conf Conf;
-typedef struct DConf DConf;
-typedef struct DDesc DDesc;
-typedef struct DDev DDev;
-typedef struct DEp DEp;
-typedef struct DIface DIface;
-typedef struct Desc Desc;
-typedef struct Dev Dev;
-typedef struct Ep Ep;
-typedef struct Iface Iface;
-typedef struct Usbdev Usbdev;
-
-enum {
- /* fundamental constants */
- Nep = 256, /* max. endpoints per usb device & per interface */
-
- /* tunable parameters */
- Nconf = 16, /* max. configurations per usb device */
- Nddesc = 8*Nep, /* max. device-specific descriptors per usb device */
- Niface = 16, /* max. interfaces per configuration */
- Naltc = 256, /* max. alt configurations per interface */
- Uctries = 4, /* no. of tries for usbcmd */
- Ucdelay = 50, /* delay before retrying */
-
- /* request type */
- Rh2d = 0<<7, /* host to device */
- Rd2h = 1<<7, /* device to host */
-
- Rstd = 0<<5, /* types */
- Rclass = 1<<5,
- Rvendor = 2<<5,
-
- Rdev = 0, /* recipients */
- Riface = 1,
- Rep = 2, /* endpoint */
- Rother = 3,
-
- /* standard requests */
- Rgetstatus = 0,
- Rclearfeature = 1,
- Rsetfeature = 3,
- Rsetaddress = 5,
- Rgetdesc = 6,
- Rsetdesc = 7,
- Rgetconf = 8,
- Rsetconf = 9,
- Rgetiface = 10,
- Rsetiface = 11,
- Rsynchframe = 12,
-
- Rgetcur = 0x81,
- Rgetmin = 0x82,
- Rgetmax = 0x83,
- Rgetres = 0x84,
- Rsetcur = 0x01,
- Rsetmin = 0x02,
- Rsetmax = 0x03,
- Rsetres = 0x04,
-
- /* dev classes */
- Clnone = 0, /* not in usb */
- Claudio = 1,
- Clcomms = 2,
- Clhid = 3,
- Clprinter = 7,
- Clstorage = 8,
- Clhub = 9,
- Cldata = 10,
-
- /* standard descriptor sizes */
- Ddevlen = 18,
- Dconflen = 9,
- Difacelen = 9,
- Deplen = 7,
-
- /* descriptor types */
- Ddev = 1,
- Dconf = 2,
- Dstr = 3,
- Diface = 4,
- Dep = 5,
- Dreport = 0x22,
- Dfunction = 0x24,
- Dphysical = 0x23,
-
- /* feature selectors */
- Fdevremotewakeup = 1,
- Fhalt = 0,
-
- /* device state */
- Detached = 0,
- Attached,
- Enabled,
- Assigned,
- Configured,
-
- /* endpoint direction */
- Ein = 0,
- Eout,
- Eboth,
-
- /* endpoint type */
- Econtrol = 0,
- Eiso = 1,
- Ebulk = 2,
- Eintr = 3,
-
- /* endpoint isotype */
- Eunknown = 0,
- Easync = 1,
- Eadapt = 2,
- Esync = 3,
-
- /* config attrib */
- Cbuspowered = 1<<7,
- Cselfpowered = 1<<6,
- Cremotewakeup = 1<<5,
-
- /* report types */
- Tmtype = 3<<2,
- Tmitem = 0xF0,
- Tmain = 0<<2,
- Tinput = 0x80,
- Toutput = 0x90,
- Tfeature = 0xB0,
- Tcoll = 0xA0,
- Tecoll = 0xC0,
- Tglobal = 1<<2,
- Tusagepage = 0x00,
- Tlmin = 0x10,
- Tlmax = 0x20,
- Tpmin = 0x30,
- Tpmax = 0x40,
- Tunitexp = 0x50,
- Tunit = 0x60,
- Trepsize = 0x70,
- TrepID = 0x80,
- Trepcount = 0x90,
- Tpush = 0xA0,
- Tpop = 0xB0,
- Tlocal = 2<<2,
- Tusage = 0x00,
- Tumin = 0x10,
- Tumax = 0x20,
- Tdindex = 0x30,
- Tdmin = 0x40,
- Tdmax = 0x50,
- Tsindex = 0x70,
- Tsmin = 0x80,
- Tsmax = 0x90,
- Tsetdelim = 0xA0,
- Treserved = 3<<2,
- Tlong = 0xFE,
-
-};
-
-/*
- * Usb device (when used for ep0s) or endpoint.
- * RC: One ref because of existing, another one per ogoing I/O.
- * per-driver resources (including FS if any) are released by aux
- * once the last ref is gone. This may include other Devs using
- * to access endpoints for actual I/O.
- */
-struct Dev
-{
- Ref;
- char* dir; /* path for the endpoint dir */
- int id; /* usb id for device or ep. number */
- int dfd; /* descriptor for the data file */
- int cfd; /* descriptor for the control file */
- int maxpkt; /* cached from usb description */
- Ref nerrs; /* number of errors in requests */
- Usbdev* usb; /* USB description */
- void* aux; /* for the device driver */
- void (*free)(void*); /* idem. to release aux */
-};
-
-/*
- * device description as reported by USB (unpacked).
- */
-struct Usbdev
-{
- ulong csp; /* USB class/subclass/proto */
- int vid; /* vendor id */
- int did; /* product (device) id */
- int dno; /* device release number */
- char* vendor;
- char* product;
- char* serial;
- int vsid;
- int psid;
- int ssid;
- int class; /* from descriptor */
- int nconf; /* from descriptor */
- Conf* conf[Nconf]; /* configurations */
- Ep* ep[Nep]; /* all endpoints in device */
- Desc* ddesc[Nddesc]; /* (raw) device specific descriptors */
-};
-
-struct Ep
-{
- uchar addr; /* endpt address, 0-15 (|0x80 if Ein) */
- uchar dir; /* direction, Ein/Eout */
- uchar type; /* Econtrol, Eiso, Ebulk, Eintr */
- uchar isotype; /* Eunknown, Easync, Eadapt, Esync */
- int id;
- int maxpkt; /* max. packet size */
- int ntds; /* nb. of Tds per µframe */
- Conf* conf; /* the endpoint belongs to */
- Iface* iface; /* the endpoint belongs to */
-};
-
-struct Altc
-{
- int attrib;
- int interval;
- void* aux; /* for the driver program */
-};
-
-struct Iface
-{
- int id; /* interface number */
- ulong csp; /* USB class/subclass/proto */
- Altc* altc[Naltc];
- Ep* ep[Nep];
- void* aux; /* for the driver program */
-};
-
-struct Conf
-{
- int cval; /* value for set configuration */
- int attrib;
- int milliamps; /* maximum power in this config. */
- Iface* iface[Niface];
-};
-
-/*
- * Device-specific descriptors.
- * They show up mixed with other descriptors
- * within a configuration.
- * These are unknown to the library but handed to the driver.
- */
-struct DDesc
-{
- uchar bLength;
- uchar bDescriptorType;
- uchar bbytes[1];
- /* extra bytes allocated here to keep the rest of it */
-};
-
-struct Desc
-{
- Conf* conf; /* where this descriptor was read */
- Iface* iface; /* last iface before desc in conf. */
- Ep* ep; /* last endpt before desc in conf. */
- Altc* altc; /* last alt.c. before desc in conf. */
- DDesc data; /* unparsed standard USB descriptor */
-};
-
-/*
- * layout of standard descriptor types
- */
-struct DDev
-{
- uchar bLength;
- uchar bDescriptorType;
- uchar bcdUSB[2];
- uchar bDevClass;
- uchar bDevSubClass;
- uchar bDevProtocol;
- uchar bMaxPacketSize0;
- uchar idVendor[2];
- uchar idProduct[2];
- uchar bcdDev[2];
- uchar iManufacturer;
- uchar iProduct;
- uchar iSerialNumber;
- uchar bNumConfigurations;
-};
-
-struct DConf
-{
- uchar bLength;
- uchar bDescriptorType;
- uchar wTotalLength[2];
- uchar bNumInterfaces;
- uchar bConfigurationValue;
- uchar iConfiguration;
- uchar bmAttributes;
- uchar MaxPower;
-};
-
-struct DIface
-{
- uchar bLength;
- uchar bDescriptorType;
- uchar bInterfaceNumber;
- uchar bAlternateSetting;
- uchar bNumEndpoints;
- uchar bInterfaceClass;
- uchar bInterfaceSubClass;
- uchar bInterfaceProtocol;
- uchar iInterface;
-};
-
-struct DEp
-{
- uchar bLength;
- uchar bDescriptorType;
- uchar bEndpointAddress;
- uchar bmAttributes;
- uchar wMaxPacketSize[2];
- uchar bInterval;
-};
-
-#define Class(csp) ((csp) & 0xff)
-#define Subclass(csp) (((csp)>>8) & 0xff)
-#define Proto(csp) (((csp)>>16) & 0xff)
-#define CSP(c, s, p) ((c) | (s)<<8 | (p)<<16)
-
-#define GET2(p) (((p)[1] & 0xFF)<<8 | ((p)[0] & 0xFF))
-#define PUT2(p,v) {(p)[0] = (v); (p)[1] = (v)>>8;}
-#define GET4(p) (((p)[3]&0xFF)<<24 | ((p)[2]&0xFF)<<16 | \
- ((p)[1]&0xFF)<<8 | ((p)[0]&0xFF))
-#define PUT4(p,v) {(p)[0] = (v); (p)[1] = (v)>>8; \
- (p)[2] = (v)>>16; (p)[3] = (v)>>24;}
-
-#define dprint if(usbdebug)fprint
-#define ddprint if(usbdebug > 1)fprint
-
-#pragma varargck type "U" Dev*
-#pragma varargck argpos devctl 2
-
-int Ufmt(Fmt *f);
-char* classname(int c);
-void closedev(Dev *d);
-int configdev(Dev *d);
-int devctl(Dev *dev, char *fmt, ...);
-void* emallocz(ulong size, int zero);
-char* estrdup(char *s);
-int matchdevcsp(char *info, void *a);
-int finddevs(int (*matchf)(char*,void*), void *farg, char** dirs, int ndirs);
-char* hexstr(void *a, int n);
-int loaddevconf(Dev *d, int n);
-int loaddevdesc(Dev *d);
-char* loaddevstr(Dev *d, int sid);
-Dev* opendev(char *fn);
-int opendevdata(Dev *d, int mode);
-Dev* openep(Dev *d, int id);
-int parseconf(Usbdev *d, Conf *c, uchar *b, int n);
-int parsedesc(Usbdev *d, Conf *c, uchar *b, int n);
-int parsedev(Dev *xd, uchar *b, int n);
-void startdevs(char *args, char *argv[], int argc, int (*mf)(char*,void*), void*ma, int (*df)(Dev*,int,char**));
-int unstall(Dev *dev, Dev *ep, int dir);
-int usbcmd(Dev *d, int type, int req, int value, int index, uchar *data, int count);
-
-
-extern int usbdebug; /* more messages for bigger values */
-
-
diff --git a/sys/src/cmd/usb/lib/usbfs.h b/sys/src/cmd/usb/lib/usbfs.h
deleted file mode 100644
index ebb3c6cc5..000000000
--- a/sys/src/cmd/usb/lib/usbfs.h
+++ /dev/null
@@ -1,61 +0,0 @@
-typedef struct Usbfs Usbfs;
-typedef struct Fid Fid;
-
-enum
-{
- Hdrsize = 128, /* plenty of room for headers */
- Msgsize = 8216, /* our preferred iounit (also devmnt's) */
- Bufsize = Hdrsize + Msgsize,
- Namesz = 40,
- Errmax = 128,
- ONONE = ~0, /* omode in Fid when not open */
-};
-
-struct Fid
-{
- int fid;
- Qid qid;
- int omode;
- Fid* next;
- void* aux;
-};
-
-struct Usbfs
-{
- char name[Namesz];
- uvlong qid;
- Dev* dev;
- void* aux;
-
- int (*walk)(Usbfs *fs, Fid *f, char *name);
- void (*clone)(Usbfs *fs, Fid *of, Fid *nf);
- void (*clunk)(Usbfs *fs, Fid *f);
- int (*open)(Usbfs *fs, Fid *f, int mode);
- long (*read)(Usbfs *fs, Fid *f, void *data, long count, vlong offset);
- long (*write)(Usbfs *fs, Fid*f, void *data, long count, vlong offset);
- int (*stat)(Usbfs *fs, Qid q, Dir *d);
- void (*end)(Usbfs *fs);
-};
-
-typedef int (*Dirgen)(Usbfs*, Qid, int, Dir*, void*);
-
-long usbreadbuf(void *data, long count, vlong offset, void *buf, long n);
-void usbfsadd(Usbfs *dfs);
-void usbfsdel(Usbfs *dfs);
-int usbdirread(Usbfs*f, Qid q, char *data, long cnt, vlong off, Dirgen gen, void *arg);
-void usbfsinit(char* srv, char *mnt, Usbfs *f, int flag);
-
-void usbfsdirdump(void);
-
-extern char Enotfound[];
-extern char Etoosmall[];
-extern char Eio[];
-extern char Eperm[];
-extern char Ebadcall[];
-extern char Ebadfid[];
-extern char Einuse[];
-extern char Eisopen[];
-extern char Ebadctl[];
-
-extern Usbfs usbdirfs;
-extern int usbfsdebug;
diff --git a/sys/src/cmd/usb/mkfile b/sys/src/cmd/usb/mkfile
deleted file mode 100644
index e2a10c2ea..000000000
--- a/sys/src/cmd/usb/mkfile
+++ /dev/null
@@ -1,38 +0,0 @@
-</$objtype/mkfile
-
-# order matters here. build lib first and usbd last.
-DIRS=\
- lib\
- audio\
- disk\
- ether\
- kb\
- print\
- serial\
- usbd\
-
-UPDATE=\
- mkfile\
-
-default:V: all
-
-none:VQ:
- echo mk all, install, installall, safeinstall, safeinstallall, clean, nuke, or update
-
-all clean nuke:VQ:
- for (i in $DIRS) @{
- cd $i && echo $i: && mk $target
- }
-
-install installall safeinstall safeinstallall:V:
- for (i in $DIRS) @{
- cd $i && mk $target
- }
- cp probe /$objtype/bin/usb/probe
-
-update:V:
- update $UPDATEFLAGS $UPDATE
- for (i in $DIRS) @{
- echo update $i
- cd $i && mk 'UPDATEFLAGS='$"UPDATEFLAGS update
- }
diff --git a/sys/src/cmd/usb/print/main.c b/sys/src/cmd/usb/print/main.c
deleted file mode 100644
index 49113b667..000000000
--- a/sys/src/cmd/usb/print/main.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * usb/print - usb printer
- */
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-
-enum
-{
- Arglen = 80,
-};
-
-static void
-usage(void)
-{
- fprint(2, "usage: %s [-d] [-N nb] [dev...]\n", argv0);
- threadexitsall("usage");
-}
-
-static int csps[] = { 0x020107, 0 };
-
-extern int printmain(Dev*, int, char**);
-
-void
-threadmain(int argc, char **argv)
-{
- char args[Arglen];
- char *as;
- char *ae;
-
- quotefmtinstall();
- ae = args+sizeof(args);
- as = seprint(args, ae, "print");
- ARGBEGIN{
- case 'd':
- usbdebug++;
- break;
- case 'N':
- as = seprint(as, ae, " -N %s", EARGF(usage()));
- break;
- default:
- usage();
- }ARGEND
-
- rfork(RFNOTEG);
- threadsetgrp(threadid());
- fmtinstall('U', Ufmt);
- startdevs(args, argv, argc, matchdevcsp, csps, printmain);
- threadexits(nil);
-}
diff --git a/sys/src/cmd/usb/print/mkfile b/sys/src/cmd/usb/print/mkfile
deleted file mode 100644
index 2cc983de2..000000000
--- a/sys/src/cmd/usb/print/mkfile
+++ /dev/null
@@ -1,22 +0,0 @@
-</$objtype/mkfile
-
-TARG=print
-LIB=../lib/usb.a$O
-
-HFILES=\
- ../lib/usb.h\
- ../lib/usbfs.h\
-
-OFILES=\
- main.$O\
- print.$O\
-
-BIN=/$objtype/bin/usb
-</sys/src/cmd/mkone
-CFLAGS=-I../lib $CFLAGS
-
-$LIB:
- cd ../lib
- mk install
- mk clean
-
diff --git a/sys/src/cmd/usb/print/print.c b/sys/src/cmd/usb/print/print.c
deleted file mode 100644
index 48906a5f8..000000000
--- a/sys/src/cmd/usb/print/print.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * usb/print - usb printer file server
- * BUG: Assumes the printer will be always connected and
- * not hot-plugged. (Otherwise should stay running and
- * listen to errors to keep the device there as long as it has
- * not failed). Also, this is untested and done ad-hoc to
- * replace the print script.
- */
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-
-enum
-{
- Qdir = 0,
- Qctl,
- Qraw,
- Qdata,
- Qmax,
-};
-
-int
-findendpoints(Dev *dev, int devid)
-{
- Ep *ep;
- Dev *d;
- Usbdev *ud;
- int i, epout;
-
- epout = -1;
- ud = dev->usb;
- for(i = 0; i < nelem(ud->ep); i++){
- if((ep = ud->ep[i]) == nil)
- break;
- if(ep->iface->csp != 0x020107)
- continue;
- if(ep->type == Ebulk && (ep->dir == Eboth || ep->dir == Eout))
- if(epout == -1)
- epout = ep->id;
- }
- dprint(2, "print: ep ids: out %d\n", epout);
- if(epout == -1)
- return -1;
- d = openep(dev, epout);
- if(d == nil){
- fprint(2, "print: openep %d: %r\n", epout);
- return -1;
- }
- opendevdata(d, OWRITE);
- if(d->dfd < 0){
- fprint(2, "print: open i/o ep data: %r\n");
- closedev(d);
- return -1;
- }
- dprint(2, "print: ep out %s\n", d->dir);
- if(usbdebug > 1)
- devctl(d, "debug 1");
- devctl(d, "name lp%d", devid);
- return 0;
-}
-
-static int
-usage(void)
-{
- werrstr("usage: usb/print [-N id]");
- return -1;
-}
-
-int
-printmain(Dev *dev, int argc, char **argv)
-{
- int devid;
-
- devid = dev->id;
- ARGBEGIN{
- case 'N':
- devid = atoi(EARGF(usage()));
- break;
- default:
- return usage();
- }ARGEND
- if(argc != 0)
- return usage();
-
- if(findendpoints(dev, devid) < 0){
- werrstr("print: endpoints not found");
- return -1;
- }
- return 0;
-}
diff --git a/sys/src/cmd/usb/probe b/sys/src/cmd/usb/probe
deleted file mode 100644
index 7dbbc11d0..000000000
--- a/sys/src/cmd/usb/probe
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/rc
-# usb/probe [-h] - list all usb devices, including hubs
-rfork e
-test -e /dev/usb || bind -a '#u' /dev || {
- echo no '#u/usb' >[1=2]
- exit nousb
-}
-
-filter = cat
-if (~ $1 -h)
- filter = (grep -v ' (root)?hub ')
-
-awk 'BEGIN { ep = "" }
-$1 ~ /ep[0-9]+\.0/ && $2 == "enabled" && $NF ~ /busy|idle/ {
- ep=$1
- next
-}
-{
- if(ep != ""){
- printf "%s %s\n", ep, $0
- ep = ""
- }
-}
-' /dev/usb/ctl | $filter
-
-exit ''
diff --git a/sys/src/cmd/usb/serial/ftdi.c b/sys/src/cmd/usb/serial/ftdi.c
deleted file mode 100644
index ffed32fd3..000000000
--- a/sys/src/cmd/usb/serial/ftdi.c
+++ /dev/null
@@ -1,961 +0,0 @@
-/* Future Technology Devices International serial ports */
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-#include "usbfs.h"
-#include "serial.h"
-#include "ftdi.h"
-
-/*
- * BUG: This keeps growing, there has to be a better way, but without
- * devices to try it... We can probably simply look for FTDI in the
- * string, or use regular expressions somehow.
- */
-Cinfo ftinfo[] = {
- { FTVid, FTACTZWAVEDid },
- { FTSheevaVid, FTSheevaDid },
- { FTVid, FTOpenRDUltDid},
- { FTVid, FTIRTRANSDid },
- { FTVid, FTIPLUSDid },
- { FTVid, FTSIODid },
- { FTVid, FT8U232AMDid },
- { FTVid, FT8U232AMALTDid },
- { FTVid, FT8U2232CDid },
- { FTVid, FTRELAISDid },
- { INTERBIOMVid, INTERBIOMIOBRDDid },
- { INTERBIOMVid, INTERBIOMMINIIOBRDDid },
- { FTVid, FTXF632Did },
- { FTVid, FTXF634Did },
- { FTVid, FTXF547Did },
- { FTVid, FTXF633Did },
- { FTVid, FTXF631Did },
- { FTVid, FTXF635Did },
- { FTVid, FTXF640Did },
- { FTVid, FTXF642Did },
- { FTVid, FTDSS20Did },
- { FTNFRICVid, FTNFRICDid },
- { FTVid, FTVNHCPCUSBDDid },
- { FTVid, FTMTXORB0Did },
- { FTVid, FTMTXORB1Did },
- { FTVid, FTMTXORB2Did },
- { FTVid, FTMTXORB3Did },
- { FTVid, FTMTXORB4Did },
- { FTVid, FTMTXORB5Did },
- { FTVid, FTMTXORB6Did },
- { FTVid, FTPERLEULTRAPORTDid },
- { FTVid, FTPIEGROUPDid },
- { SEALEVELVid, SEALEVEL2101Did },
- { SEALEVELVid, SEALEVEL2102Did },
- { SEALEVELVid, SEALEVEL2103Did },
- { SEALEVELVid, SEALEVEL2104Did },
- { SEALEVELVid, SEALEVEL22011Did },
- { SEALEVELVid, SEALEVEL22012Did },
- { SEALEVELVid, SEALEVEL22021Did },
- { SEALEVELVid, SEALEVEL22022Did },
- { SEALEVELVid, SEALEVEL22031Did },
- { SEALEVELVid, SEALEVEL22032Did },
- { SEALEVELVid, SEALEVEL24011Did },
- { SEALEVELVid, SEALEVEL24012Did },
- { SEALEVELVid, SEALEVEL24013Did },
- { SEALEVELVid, SEALEVEL24014Did },
- { SEALEVELVid, SEALEVEL24021Did },
- { SEALEVELVid, SEALEVEL24022Did },
- { SEALEVELVid, SEALEVEL24023Did },
- { SEALEVELVid, SEALEVEL24024Did },
- { SEALEVELVid, SEALEVEL24031Did },
- { SEALEVELVid, SEALEVEL24032Did },
- { SEALEVELVid, SEALEVEL24033Did },
- { SEALEVELVid, SEALEVEL24034Did },
- { SEALEVELVid, SEALEVEL28011Did },
- { SEALEVELVid, SEALEVEL28012Did },
- { SEALEVELVid, SEALEVEL28013Did },
- { SEALEVELVid, SEALEVEL28014Did },
- { SEALEVELVid, SEALEVEL28015Did },
- { SEALEVELVid, SEALEVEL28016Did },
- { SEALEVELVid, SEALEVEL28017Did },
- { SEALEVELVid, SEALEVEL28018Did },
- { SEALEVELVid, SEALEVEL28021Did },
- { SEALEVELVid, SEALEVEL28022Did },
- { SEALEVELVid, SEALEVEL28023Did },
- { SEALEVELVid, SEALEVEL28024Did },
- { SEALEVELVid, SEALEVEL28025Did },
- { SEALEVELVid, SEALEVEL28026Did },
- { SEALEVELVid, SEALEVEL28027Did },
- { SEALEVELVid, SEALEVEL28028Did },
- { SEALEVELVid, SEALEVEL28031Did },
- { SEALEVELVid, SEALEVEL28032Did },
- { SEALEVELVid, SEALEVEL28033Did },
- { SEALEVELVid, SEALEVEL28034Did },
- { SEALEVELVid, SEALEVEL28035Did },
- { SEALEVELVid, SEALEVEL28036Did },
- { SEALEVELVid, SEALEVEL28037Did },
- { SEALEVELVid, SEALEVEL28038Did },
- { IDTECHVid, IDTECHIDT1221UDid },
- { OCTVid, OCTUS101Did },
- { FTVid, FTHETIRA1Did }, /* special quirk div = 240 baud = B38400 rtscts = 1 */
- { FTVid, FTUSBUIRTDid }, /* special quirk div = 77, baud = B38400 */
- { FTVid, PROTEGOSPECIAL1 },
- { FTVid, PROTEGOR2X0 },
- { FTVid, PROTEGOSPECIAL3 },
- { FTVid, PROTEGOSPECIAL4 },
- { FTVid, FTGUDEADSE808Did },
- { FTVid, FTGUDEADSE809Did },
- { FTVid, FTGUDEADSE80ADid },
- { FTVid, FTGUDEADSE80BDid },
- { FTVid, FTGUDEADSE80CDid },
- { FTVid, FTGUDEADSE80DDid },
- { FTVid, FTGUDEADSE80EDid },
- { FTVid, FTGUDEADSE80FDid },
- { FTVid, FTGUDEADSE888Did },
- { FTVid, FTGUDEADSE889Did },
- { FTVid, FTGUDEADSE88ADid },
- { FTVid, FTGUDEADSE88BDid },
- { FTVid, FTGUDEADSE88CDid },
- { FTVid, FTGUDEADSE88DDid },
- { FTVid, FTGUDEADSE88EDid },
- { FTVid, FTGUDEADSE88FDid },
- { FTVid, FTELVUO100Did },
- { FTVid, FTELVUM100Did },
- { FTVid, FTELVUR100Did },
- { FTVid, FTELVALC8500Did },
- { FTVid, FTPYRAMIDDid },
- { FTVid, FTELVFHZ1000PCDid },
- { FTVid, FTELVCLI7000Did },
- { FTVid, FTELVPPS7330Did },
- { FTVid, FTELVTFM100Did },
- { FTVid, FTELVUDF77Did },
- { FTVid, FTELVUIO88Did },
- { FTVid, FTELVUAD8Did },
- { FTVid, FTELVUDA7Did },
- { FTVid, FTELVUSI2Did },
- { FTVid, FTELVT1100Did },
- { FTVid, FTELVPCD200Did },
- { FTVid, FTELVULA200Did },
- { FTVid, FTELVCSI8Did },
- { FTVid, FTELVEM1000DLDid },
- { FTVid, FTELVPCK100Did },
- { FTVid, FTELVRFP500Did },
- { FTVid, FTELVFS20SIGDid },
- { FTVid, FTELVWS300PCDid },
- { FTVid, FTELVFHZ1300PCDid },
- { FTVid, FTELVWS500Did },
- { FTVid, LINXSDMUSBQSSDid },
- { FTVid, LINXMASTERDEVEL2Did },
- { FTVid, LINXFUTURE0Did },
- { FTVid, LINXFUTURE1Did },
- { FTVid, LINXFUTURE2Did },
- { FTVid, FTCCSICDU200Did },
- { FTVid, FTCCSICDU401Did },
- { FTVid, INSIDEACCESSO },
- { INTREDidVid, INTREDidVALUECANDid },
- { INTREDidVid, INTREDidNEOVIDid },
- { FALCOMVid, FALCOMTWISTDid },
- { FALCOMVid, FALCOMSAMBADid },
- { FTVid, FTSUUNTOSPORTSDid },
- { FTVid, FTRMCANVIEWDid },
- { BANDBVid, BANDBUSOTL4Did },
- { BANDBVid, BANDBUSTL4Did },
- { BANDBVid, BANDBUSO9ML2Did },
- { FTVid, EVERECOPROCDSDid },
- { FTVid, FT4NGALAXYDE0Did },
- { FTVid, FT4NGALAXYDE1Did },
- { FTVid, FT4NGALAXYDE2Did },
- { FTVid, XSENSCONVERTER0Did },
- { FTVid, XSENSCONVERTER1Did },
- { FTVid, XSENSCONVERTER2Did },
- { FTVid, XSENSCONVERTER3Did },
- { FTVid, XSENSCONVERTER4Did },
- { FTVid, XSENSCONVERTER5Did },
- { FTVid, XSENSCONVERTER6Did },
- { FTVid, XSENSCONVERTER7Did },
- { MOBILITYVid, MOBILITYUSBSERIALDid },
- { FTVid, FTACTIVEROBOTSDid },
- { FTVid, FTMHAMKWDid },
- { FTVid, FTMHAMYSDid },
- { FTVid, FTMHAMY6Did },
- { FTVid, FTMHAMY8Did },
- { FTVid, FTMHAMICDid },
- { FTVid, FTMHAMDB9Did },
- { FTVid, FTMHAMRS232Did },
- { FTVid, FTMHAMY9Did },
- { FTVid, FTTERATRONIKVCPDid },
- { FTVid, FTTERATRONIKD2XXDid },
- { EVOLUTIONVid, EVOLUTIONER1Did },
- { FTVid, FTARTEMISDid },
- { FTVid, FTATIKATK16Did },
- { FTVid, FTATIKATK16CDid },
- { FTVid, FTATIKATK16HRDid },
- { FTVid, FTATIKATK16HRCDid },
- { KOBILVid, KOBILCONVB1Did },
- { KOBILVid, KOBILCONVKAANDid },
- { POSIFLEXVid, POSIFLEXPP7000Did },
- { FTVid, FTTTUSBDid },
- { FTVid, FTECLOCOM1WIREDid },
- { FTVid, FTWESTREXMODEL777Did },
- { FTVid, FTWESTREXMODEL8900FDid },
- { FTVid, FTPCDJDAC2Did },
- { FTVid, FTRRCIRKITSLOCOBUFFERDid },
- { FTVid, FTASKRDR400Did },
- { ICOMID1Vid, ICOMID1Did },
- { PAPOUCHVid, PAPOUCHTMUDid },
- { FTVid, FTACGHFDUALDid },
- { FT8U232AMDid, FT4232HDid },
- { 0, 0 },
-};
-
-enum {
- Packsz = 64, /* default size */
- Maxpacksz = 512,
- Bufsiz = 4 * 1024,
-};
-
-static int
-ftdiread(Serialport *p, int index, int req, uchar *buf, int len)
-{
- int res;
- Serial *ser;
-
- ser = p->s;
-
- if(req != FTGETE2READ)
- index |= p->interfc + 1;
- dsprint(2, "serial: ftdiread %#p [%d] req: %#x val: %#x idx:%d buf:%p len:%d\n",
- p, p->interfc, req, 0, index, buf, len);
- res = usbcmd(ser->dev, Rd2h | Rftdireq | Rdev, req, 0, index, buf, len);
- dsprint(2, "serial: ftdiread res:%d\n", res);
- return res;
-}
-
-static int
-ftdiwrite(Serialport *p, int val, int index, int req)
-{
- int res;
- Serial *ser;
-
- ser = p->s;
-
- if(req != FTGETE2READ || req != FTSETE2ERASE || req != FTSETBAUDRATE)
- index |= p->interfc + 1;
- dsprint(2, "serial: ftdiwrite %#p [%d] req: %#x val: %#x idx:%d\n",
- p, p->interfc, req, val, index);
- res = usbcmd(ser->dev, Rh2d | Rftdireq | Rdev, req, val, index, nil, 0);
- dsprint(2, "serial: ftdiwrite res:%d\n", res);
- return res;
-}
-
-static int
-ftmodemctl(Serialport *p, int set)
-{
- if(set == 0){
- p->mctl = 0;
- ftdiwrite(p, 0, 0, FTSETMODEMCTRL);
- return 0;
- }
- p->mctl = 1;
- ftdiwrite(p, 0, FTRTSCTSHS, FTSETFLOWCTRL);
- return 0;
-}
-
-static ushort
-ft232ambaudbase2div(int baud, int base)
-{
- int divisor3;
- ushort divisor;
-
- divisor3 = (base / 2) / baud;
- if((divisor3 & 7) == 7)
- divisor3++; /* round x.7/8 up to x+1 */
- divisor = divisor3 >> 3;
- divisor3 &= 7;
-
- if(divisor3 == 1)
- divisor |= 0xc000; /* 0.125 */
- else if(divisor3 >= 4)
- divisor |= 0x4000; /* 0.5 */
- else if(divisor3 != 0)
- divisor |= 0x8000; /* 0.25 */
- if( divisor == 1)
- divisor = 0; /* special case for maximum baud rate */
- return divisor;
-}
-
-enum{
- ClockNew = 48000000,
- ClockOld = 12000000 / 16,
- HetiraDiv = 240,
- UirtDiv = 77,
-};
-
-static ushort
-ft232ambaud2div(int baud)
-{
- return ft232ambaudbase2div(baud, ClockNew);
-}
-
-static ulong divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7};
-
-static ulong
-ft232bmbaudbase2div(int baud, int base)
-{
- int divisor3;
- u32int divisor;
-
- divisor3 = (base / 2) / baud;
- divisor = divisor3 >> 3 | divfrac[divisor3 & 7] << 14;
-
- /* Deal with special cases for highest baud rates. */
- if( divisor == 1)
- divisor = 0; /* 1.0 */
- else if( divisor == 0x4001)
- divisor = 1; /* 1.5 */
- return divisor;
-}
-
-static ulong
-ft232bmbaud2div (int baud)
-{
- return ft232bmbaudbase2div (baud, ClockNew);
-}
-
-static int
-customdiv(Serial *ser)
-{
- if(ser->dev->usb->vid == FTVid && ser->dev->usb->did == FTHETIRA1Did)
- return HetiraDiv;
- else if(ser->dev->usb->vid == FTVid && ser->dev->usb->did == FTUSBUIRTDid)
- return UirtDiv;
-
- fprint(2, "serial: weird custom divisor\n");
- return 0; /* shouldn't happen, break as much as I can */
-}
-
-static ulong
-ftbaudcalcdiv(Serial *ser, int baud)
-{
- int cusdiv;
- ulong divval;
-
- if(baud == 38400 && (cusdiv = customdiv(ser)) != 0)
- baud = ser->baudbase / cusdiv;
-
- if(baud == 0)
- baud = 9600;
-
- switch(ser->type) {
- case SIO:
- switch(baud) {
- case 300:
- divval = FTb300;
- break;
- case 600:
- divval = FTb600;
- break;
- case 1200:
- divval = FTb1200;
- break;
- case 2400:
- divval = FTb2400;
- break;
- case 4800:
- divval = FTb4800;
- break;
- case 9600:
- divval = FTb9600;
- break;
- case 19200:
- divval = FTb19200;
- break;
- case 38400:
- divval = FTb38400;
- break;
- case 57600:
- divval = FTb57600;
- break;
- case 115200:
- divval = FTb115200;
- break;
- default:
- divval = FTb9600;
- break;
- }
- break;
- case FT8U232AM:
- if(baud <= 3000000)
- divval = ft232ambaud2div(baud);
- else
- divval = ft232ambaud2div(9600);
- break;
- case FT232BM:
- case FT2232C:
- case FTKINDR:
- case FT2232H:
- case FT4232H:
- if(baud <= 3000000)
- divval = ft232bmbaud2div(baud);
- else
- divval = ft232bmbaud2div(9600);
- break;
- default:
- divval = ft232bmbaud2div(9600);
- break;
- }
- return divval;
-}
-
-static int
-ftsetparam(Serialport *p)
-{
- int res;
- ushort val;
- ulong bauddiv;
-
- val = 0;
- if(p->stop == 1)
- val |= FTSETDATASTOPBITS1;
- else if(p->stop == 2)
- val |= FTSETDATASTOPBITS2;
- else if(p->stop == 15)
- val |= FTSETDATASTOPBITS15;
- switch(p->parity){
- case 0:
- val |= FTSETDATAParNONE;
- break;
- case 1:
- val |= FTSETDATAParODD;
- break;
- case 2:
- val |= FTSETDATAParEVEN;
- break;
- case 3:
- val |= FTSETDATAParMARK;
- break;
- case 4:
- val |= FTSETDATAParSPACE;
- break;
- };
-
- dsprint(2, "serial: setparam\n");
-
- res = ftdiwrite(p, val, 0, FTSETDATA);
- if(res < 0)
- return res;
-
- res = ftmodemctl(p, p->mctl);
- if(res < 0)
- return res;
-
- bauddiv = ftbaudcalcdiv(p->s, p->baud);
- res = ftdiwrite(p, bauddiv, (bauddiv>>16) & 1, FTSETBAUDRATE);
-
- dsprint(2, "serial: setparam res: %d\n", res);
- return res;
-}
-
-static int
-hasjtag(Usbdev *udev)
-{
- /* no string, for now, by default we detect no jtag */
- if(udev->product != nil && cistrstr(udev->product, "jtag") != nil)
- return 1;
- return 0;
-}
-
-/* ser locked */
-static void
-ftgettype(Serial *ser)
-{
- int i, outhdrsz, dno, pksz;
- ulong baudbase;
- Conf *cnf;
-
- pksz = Packsz;
- /* Assume it is not the original SIO device for now. */
- baudbase = ClockNew / 2;
- outhdrsz = 0;
- dno = ser->dev->usb->dno;
- cnf = ser->dev->usb->conf[0];
- ser->nifcs = 0;
- for(i = 0; i < Niface; i++)
- if(cnf->iface[i] != nil)
- ser->nifcs++;
- if(ser->nifcs > 1) {
- /*
- * Multiple interfaces. default assume FT2232C,
- */
- if(dno == 0x500)
- ser->type = FT2232C;
- else if(dno == 0x600)
- ser->type = FTKINDR;
- else if(dno == 0x700){
- ser->type = FT2232H;
- pksz = Maxpacksz;
- } else if(dno == 0x800){
- ser->type = FT4232H;
- pksz = Maxpacksz;
- } else
- ser->type = FT2232C;
-
- if(hasjtag(ser->dev->usb))
- ser->jtag = 0;
-
- /*
- * BM-type devices have a bug where dno gets set
- * to 0x200 when serial is 0.
- */
- if(dno < 0x500)
- fprint(2, "serial: warning: dno %d too low for "
- "multi-interface device\n", dno);
- } else if(dno < 0x200) {
- /* Old device. Assume it is the original SIO. */
- ser->type = SIO;
- baudbase = ClockOld/16;
- outhdrsz = 1;
- } else if(dno < 0x400)
- /*
- * Assume its an FT8U232AM (or FT8U245AM)
- * (It might be a BM because of the iSerialNumber bug,
- * but it will still work as an AM device.)
- */
- ser->type = FT8U232AM;
- else /* Assume it is an FT232BM (or FT245BM) */
- ser->type = FT232BM;
-
- ser->maxrtrans = ser->maxwtrans = pksz;
- ser->baudbase = baudbase;
- ser->outhdrsz = outhdrsz;
- ser->inhdrsz = 2;
-
- dsprint (2, "serial: detected type: %#x\n", ser->type);
-}
-
-int
-ftmatch(Serial *ser, char *info)
-{
- Cinfo *ip;
- char buf[50];
-
- for(ip = ftinfo; ip->vid != 0; ip++){
- snprint(buf, sizeof buf, "vid %#06x did %#06x", ip->vid, ip->did);
- dsprint(2, "serial: %s %s\n", buf, info);
- if(strstr(info, buf) != nil){
- if(ser != nil){
- qlock(ser);
- ftgettype(ser);
- qunlock(ser);
- }
- return 0;
- }
- }
- return -1;
-}
-
-static int
-ftuseinhdr(Serialport *p, uchar *b)
-{
- if(b[0] & FTICTS)
- p->cts = 1;
- else
- p->cts = 0;
- if(b[0] & FTIDSR)
- p->dsr = 1;
- else
- p->dsr = 0;
- if(b[0] & FTIRI)
- p->ring = 1;
- else
- p->ring = 0;
- if(b[0] & FTIRLSD)
- p->rlsd = 1;
- else
- p->rlsd = 0;
-
- if(b[1] & FTIOE)
- p->novererr++;
- if(b[1] & FTIPE)
- p->nparityerr++;
- if(b[1] & FTIFE)
- p->nframeerr++;
- if(b[1] & FTIBI)
- p->nbreakerr++;
- return 0;
-}
-
-static int
-ftsetouthdr(Serialport *p, uchar *b, int len)
-{
- if(p->s->outhdrsz != 0)
- b[0] = FTOPORT | (FTOLENMSK & len);
- return p->s->outhdrsz;
-}
-
-static int
-wait4data(Serialport *p, uchar *data, int count)
-{
- int d;
- Serial *ser;
-
- ser = p->s;
-
- qunlock(ser);
- d = sendul(p->w4data, 1);
- qlock(ser);
- if(d <= 0)
- return -1;
- if(p->ndata >= count)
- p->ndata -= count;
- else{
- count = p->ndata;
- p->ndata = 0;
- }
- assert(count >= 0);
- assert(p->ndata >= 0);
- memmove(data, p->data, count);
- if(p->ndata != 0)
- memmove(p->data, p->data+count, p->ndata);
-
- recvul(p->gotdata);
- return count;
-}
-
-static int
-wait4write(Serialport *p, uchar *data, int count)
-{
- int off, fd;
- uchar *b;
- Serial *ser;
-
- ser = p->s;
-
- b = emallocz(count+ser->outhdrsz, 1);
- off = ftsetouthdr(p, b, count);
- memmove(b+off, data, count);
-
- fd = p->epout->dfd;
- qunlock(ser);
- count = write(fd, b, count+off);
- qlock(ser);
- free(b);
- return count;
-}
-
-typedef struct Packser Packser;
-struct Packser{
- int nb;
- uchar b[Bufsiz];
-};
-
-typedef struct Areader Areader;
-struct Areader{
- Serialport *p;
- Channel *c;
-};
-
-static void
-shutdownchan(Channel *c)
-{
- Packser *bp;
-
- while((bp=nbrecvp(c)) != nil)
- free(bp);
- chanfree(c);
-}
-
-int
-cpdata(Serial *ser, Serialport *port, uchar *out, uchar *in, int sz)
-{
- int i, ncp, ntotcp, pksz;
-
- pksz = ser->maxrtrans;
- ntotcp = 0;
-
- for(i = 0; i < sz; i+= pksz){
- ftuseinhdr(port, in + i);
- if(sz - i > pksz)
- ncp = pksz - ser->inhdrsz;
- else
- ncp = sz - i - ser->inhdrsz;
- memmove(out, in + i + ser->inhdrsz, ncp);
- out += ncp;
- ntotcp += ncp;
- }
- return ntotcp;
-}
-
-static void
-epreader(void *u)
-{
- int dfd, rcount, cl, ntries, recov;
- char err[40];
- Areader *a;
- Channel *c;
- Packser *pk;
- Serial *ser;
- Serialport *p;
-
- threadsetname("epreader proc");
- a = u;
- p = a->p;
- ser = p->s;
- c = a->c;
- free(a);
-
- qlock(ser); /* this makes the reader wait end of initialization too */
- dfd = p->epin->dfd;
- qunlock(ser);
-
- ntries = 0;
- pk = nil;
- do {
- if (pk == nil)
- pk = emallocz(sizeof(Packser), 1);
-Eagain:
- rcount = read(dfd, pk->b, sizeof pk->b);
- if(serialdebug > 5)
- dsprint(2, "%d %#ux%#ux ", rcount, p->data[0],
- p->data[1]);
-
- if(rcount < 0){
- if(ntries++ > 100)
- break;
- qlock(ser);
- recov = serialrecover(ser, p, nil, "epreader: bulkin error");
- qunlock(ser);
- if(recov >= 0)
- goto Eagain;
- }
- if(rcount == 0)
- continue;
- if(rcount >= ser->inhdrsz){
- rcount = cpdata(ser, p, pk->b, pk->b, rcount);
- if(rcount != 0){
- pk->nb = rcount;
- cl = sendp(c, pk);
- if(cl < 0){
- /*
- * if it was a time-out, I don't want
- * to give back an error.
- */
- rcount = 0;
- break;
- }
- }else
- free(pk);
- qlock(ser);
- ser->recover = 0;
- qunlock(ser);
- ntries = 0;
- pk = nil;
- }
- } while(rcount >= 0 || (rcount < 0 && strstr(err, "timed out") != nil));
-
- if(rcount < 0)
- fprint(2, "%s: error reading %s: %r\n", argv0, p->fs.name);
- free(pk);
- nbsendp(c, nil);
- if(p->w4data != nil)
- chanclose(p->w4data);
- if(p->gotdata != nil)
- chanclose(p->gotdata);
- devctl(ser->dev, "detach");
- closedev(ser->dev);
- usbfsdel(&p->fs);
-}
-
-static void
-statusreader(void *u)
-{
- Areader *a;
- Channel *c;
- Packser *pk;
- Serialport *p;
- Serial *ser;
- int cl;
-
- p = u;
- ser = p->s;
- threadsetname("statusreader thread");
- /* big buffering, fewer bytes lost */
- c = chancreate(sizeof(Packser *), 128);
- a = emallocz(sizeof(Areader), 1);
- a->p = p;
- a->c = c;
- incref(ser->dev);
- proccreate(epreader, a, 16*1024);
-
- while((pk = recvp(c)) != nil){
- memmove(p->data, pk->b, pk->nb);
- p->ndata = pk->nb;
- free(pk);
- dsprint(2, "serial %p: status reader %d \n", p, p->ndata);
- /* consume it all */
- while(p->ndata != 0){
- dsprint(2, "serial %p: status reader to consume: %d\n",
- p, p->ndata);
- cl = recvul(p->w4data);
- if(cl < 0)
- break;
- cl = sendul(p->gotdata, 1);
- if(cl < 0)
- break;
- }
- }
-
- shutdownchan(c);
- devctl(ser->dev, "detach");
- closedev(ser->dev);
- usbfsdel(&p->fs);
-}
-
-static int
-ftreset(Serial *ser, Serialport *p)
-{
- int i;
-
- if(p != nil){
- ftdiwrite(p, FTRESETCTLVAL, 0, FTRESET);
- return 0;
- }
- p = ser->p;
- for(i = 0; i < Maxifc; i++)
- if(p[i].s != nil)
- ftdiwrite(&p[i], FTRESETCTLVAL, 0, FTRESET);
- return 0;
-}
-
-static int
-ftinit(Serialport *p)
-{
- Serial *ser;
- uint timerval;
- int res;
-
- ser = p->s;
- if(p->isjtag){
- res = ftdiwrite(p, FTSETFLOWCTRL, 0, FTDISABLEFLOWCTRL);
- if(res < 0)
- return -1;
- res = ftdiread(p, FTSETLATENCYTIMER, 0, (uchar *)&timerval,
- FTLATENCYTIMERSZ);
- if(res < 0)
- return -1;
- dsprint(2, "serial: jtag latency timer is %d\n", timerval);
- timerval = 2;
- ftdiwrite(p, FTLATENCYDEFAULT, 0, FTSETLATENCYTIMER);
- res = ftdiread(p, FTSETLATENCYTIMER, 0, (uchar *)&timerval,
- FTLATENCYTIMERSZ);
- if(res < 0)
- return -1;
-
- dsprint(2, "serial: jtag latency timer set to %d\n", timerval);
- /* may be unnecessary */
- devctl(p->epin, "timeout 5000");
- devctl(p->epout, "timeout 5000");
- /* 0xb is the mask for lines. plug dependant? */
- ftdiwrite(p, BMMPSSE|0x0b, 0, FTSETBITMODE);
- }
- incref(ser->dev);
- threadcreate(statusreader, p, 8*1024);
- return 0;
-}
-
-static int
-ftsetbreak(Serialport *p, int val)
-{
- return ftdiwrite(p, (val != 0? FTSETBREAK: 0), 0, FTSETDATA);
-}
-
-static int
-ftclearpipes(Serialport *p)
-{
- /* maybe can be done in one... */
- ftdiwrite(p, FTRESETCTLVALPURGETX, 0, FTRESET);
- ftdiwrite(p, FTRESETCTLVALPURGERX, 0, FTRESET);
- return 0;
-}
-
-static int
-setctlline(Serialport *p, uchar val)
-{
- return ftdiwrite(p, val | (val << 8), 0, FTSETMODEMCTRL);
-}
-
-static void
-updatectlst(Serialport *p, int val)
-{
- if(p->rts)
- p->ctlstate |= val;
- else
- p->ctlstate &= ~val;
-}
-
-static int
-setctl(Serialport *p)
-{
- int res;
- Serial *ser;
-
- ser = p->s;
-
- if(ser->dev->usb->vid == FTVid && ser->dev->usb->did == FTHETIRA1Did){
- fprint(2, "serial: cannot set lines for this device\n");
- updatectlst(p, CtlRTS|CtlDTR);
- p->rts = p->dtr = 1;
- return -1;
- }
-
- /* NB: you can not set DTR and RTS with one control message */
- updatectlst(p, CtlRTS);
- res = setctlline(p, (CtlRTS<<8)|p->ctlstate);
- if(res < 0)
- return res;
-
- updatectlst(p, CtlDTR);
- res = setctlline(p, (CtlDTR<<8)|p->ctlstate);
- if(res < 0)
- return res;
-
- return 0;
-}
-
-static int
-ftsendlines(Serialport *p)
-{
- int res;
-
- dsprint(2, "serial: sendlines: %#2.2x\n", p->ctlstate);
- res = setctl(p);
- dsprint(2, "serial: sendlines res: %d\n", res);
- return 0;
-}
-
-static int
-ftseteps(Serialport *p)
-{
- char *s;
- Serial *ser;
-
- ser = p->s;
-
- s = smprint("maxpkt %d", ser->maxrtrans);
- devctl(p->epin, s);
- free(s);
-
- s = smprint("maxpkt %d", ser->maxwtrans);
- devctl(p->epout, s);
- free(s);
- return 0;
-}
-
-Serialops ftops = {
- .init = ftinit,
- .seteps = ftseteps,
- .setparam = ftsetparam,
- .clearpipes = ftclearpipes,
- .reset = ftreset,
- .sendlines = ftsendlines,
- .modemctl = ftmodemctl,
- .setbreak = ftsetbreak,
- .wait4data = wait4data,
- .wait4write = wait4write,
-};
diff --git a/sys/src/cmd/usb/serial/ftdi.h b/sys/src/cmd/usb/serial/ftdi.h
deleted file mode 100644
index 7abb63847..000000000
--- a/sys/src/cmd/usb/serial/ftdi.h
+++ /dev/null
@@ -1,632 +0,0 @@
-enum {
- /* used by devices which don't provide their own Vid */
- FTVid = 0x0403,
-
- FTSheevaVid = 0x9E88,
- FTSheevaDid = 0x9E8F,
- FTOpenRDUltDid = 0x9E90,
-
- FTSIODid = 0x8372, /* Product Id SIO appl'n of 8U100AX */
- FT8U232AMDid = 0x6001, /* Similar device to SIO above */
- FT8U232AMALTDid = 0x6006, /* FT's alternate Did for above*/
- FT8U2232CDid = 0x6010, /* Dual channel device */
- FTRELAISDid = 0xFA10, /* Relais device */
-
- /* NF reader */
- FTNFRICVid = 0x0DCD,
- FTNFRICDid = 0x0001,
-
- FTACTZWAVEDid = 0xF2D0, /* www.irtrans.de device */
-
- /*
- * ACT Solutions HomePro ZWave interface
- * http://www.act-solutions.com/HomePro.htm)
- */
- FTIRTRANSDid = 0xFC60,
-
- /*
- * www.thoughttechnology.com/ TT-USB
- */
- FTTTUSBDid = 0xFF20,
-
- /* iPlus device */
- FTIPLUSDid = 0xD070,
-
- /* www.crystalfontz.com devices */
- FTXF632Did = 0xFC08, /* 632: 16x2 Character Display */
- FTXF634Did = 0xFC09, /* 634: 20x4 Character Display */
- FTXF547Did = 0xFC0A, /* 547: Two line Display */
- FTXF633Did = 0xFC0B, /* 633: 16x2 Character Display with Keys */
- FTXF631Did = 0xFC0C, /* 631: 20x2 Character Display */
- FTXF635Did = 0xFC0D, /* 635: 20x4 Character Display */
- FTXF640Did = 0xFC0E, /* 640: Two line Display */
- FTXF642Did = 0xFC0F, /* 642: Two line Display */
-
- /*
- * Video Networks Limited / Homechoice in the UK
- * use an ftdi-based device for their 1Mb broadband
- */
- FTVNHCPCUSBDDid = 0xfe38,
-
- /*
- * PCDJ use ftdi based dj-controllers
- * DAC-2 device http://www.pcdjhardware.com/DAC2.asp
- */
- FTPCDJDAC2Did = 0xFA88,
-
- /*
- * Matrix Orbital LCD displays,
- * which are the FT232BM (similar to the 8U232AM)
- */
- FTMTXORB0Did = 0xFA00,
- FTMTXORB1Did = 0xFA01,
- FTMTXORB2Did = 0xFA02,
- FTMTXORB3Did = 0xFA03,
- FTMTXORB4Did = 0xFA04,
- FTMTXORB5Did = 0xFA05,
- FTMTXORB6Did = 0xFA06,
-
- /* Interbiometrics USB I/O Board */
- INTERBIOMVid = 0x1209,
- INTERBIOMIOBRDDid = 0x1002,
- INTERBIOMMINIIOBRDDid = 0x1006,
-
- /*
- * The following are the values for the Perle Systems
- * UltraPort USB serial converters
- */
- FTPERLEULTRAPORTDid = 0xF0C0,
-
- /*
- * Sealevel SeaLINK+ adapters.
- */
-
- SEALEVELVid = 0x0c52,
-
- SEALEVEL2101Did = 0x2101, /* SeaLINK+232 (2101/2105) */
- SEALEVEL2102Did = 0x2102, /* SeaLINK+485 (2102) */
- SEALEVEL2103Did = 0x2103, /* SeaLINK+232I (2103) */
- SEALEVEL2104Did = 0x2104, /* SeaLINK+485I (2104) */
- SEALEVEL22011Did = 0x2211, /* SeaPORT+2/232 (2201) Port 1 */
- SEALEVEL22012Did = 0x2221, /* SeaPORT+2/232 (2201) Port 2 */
- SEALEVEL22021Did = 0x2212, /* SeaPORT+2/485 (2202) Port 1 */
- SEALEVEL22022Did = 0x2222, /* SeaPORT+2/485 (2202) Port 2 */
- SEALEVEL22031Did = 0x2213, /* SeaPORT+2 (2203) Port 1 */
- SEALEVEL22032Did = 0x2223, /* SeaPORT+2 (2203) Port 2 */
- SEALEVEL24011Did = 0x2411, /* SeaPORT+4/232 (2401) Port 1 */
- SEALEVEL24012Did = 0x2421, /* SeaPORT+4/232 (2401) Port 2 */
- SEALEVEL24013Did = 0x2431, /* SeaPORT+4/232 (2401) Port 3 */
- SEALEVEL24014Did = 0x2441, /* SeaPORT+4/232 (2401) Port 4 */
- SEALEVEL24021Did = 0x2412, /* SeaPORT+4/485 (2402) Port 1 */
- SEALEVEL24022Did = 0x2422, /* SeaPORT+4/485 (2402) Port 2 */
- SEALEVEL24023Did = 0x2432, /* SeaPORT+4/485 (2402) Port 3 */
- SEALEVEL24024Did = 0x2442, /* SeaPORT+4/485 (2402) Port 4 */
- SEALEVEL24031Did = 0x2413, /* SeaPORT+4 (2403) Port 1 */
- SEALEVEL24032Did = 0x2423, /* SeaPORT+4 (2403) Port 2 */
- SEALEVEL24033Did = 0x2433, /* SeaPORT+4 (2403) Port 3 */
- SEALEVEL24034Did = 0x2443, /* SeaPORT+4 (2403) Port 4 */
- SEALEVEL28011Did = 0x2811, /* SeaLINK+8/232 (2801) Port 1 */
- SEALEVEL28012Did = 0x2821, /* SeaLINK+8/232 (2801) Port 2 */
- SEALEVEL28013Did = 0x2831, /* SeaLINK+8/232 (2801) Port 3 */
- SEALEVEL28014Did = 0x2841, /* SeaLINK+8/232 (2801) Port 4 */
- SEALEVEL28015Did = 0x2851, /* SeaLINK+8/232 (2801) Port 5 */
- SEALEVEL28016Did = 0x2861, /* SeaLINK+8/232 (2801) Port 6 */
- SEALEVEL28017Did = 0x2871, /* SeaLINK+8/232 (2801) Port 7 */
- SEALEVEL28018Did = 0x2881, /* SeaLINK+8/232 (2801) Port 8 */
- SEALEVEL28021Did = 0x2812, /* SeaLINK+8/485 (2802) Port 1 */
- SEALEVEL28022Did = 0x2822, /* SeaLINK+8/485 (2802) Port 2 */
- SEALEVEL28023Did = 0x2832, /* SeaLINK+8/485 (2802) Port 3 */
- SEALEVEL28024Did = 0x2842, /* SeaLINK+8/485 (2802) Port 4 */
- SEALEVEL28025Did = 0x2852, /* SeaLINK+8/485 (2802) Port 5 */
- SEALEVEL28026Did = 0x2862, /* SeaLINK+8/485 (2802) Port 6 */
- SEALEVEL28027Did = 0x2872, /* SeaLINK+8/485 (2802) Port 7 */
- SEALEVEL28028Did = 0x2882, /* SeaLINK+8/485 (2802) Port 8 */
- SEALEVEL28031Did = 0x2813, /* SeaLINK+8 (2803) Port 1 */
- SEALEVEL28032Did = 0x2823, /* SeaLINK+8 (2803) Port 2 */
- SEALEVEL28033Did = 0x2833, /* SeaLINK+8 (2803) Port 3 */
- SEALEVEL28034Did = 0x2843, /* SeaLINK+8 (2803) Port 4 */
- SEALEVEL28035Did = 0x2853, /* SeaLINK+8 (2803) Port 5 */
- SEALEVEL28036Did = 0x2863, /* SeaLINK+8 (2803) Port 6 */
- SEALEVEL28037Did = 0x2873, /* SeaLINK+8 (2803) Port 7 */
- SEALEVEL28038Did = 0x2883, /* SeaLINK+8 (2803) Port 8 */
-
- /* KOBIL Vendor ID chipcard terminals */
- KOBILVid = 0x0d46,
- KOBILCONVB1Did = 0x2020, /* KOBIL Konverter for B1 */
- KOBILCONVKAANDid = 0x2021, /* KOBILKonverter for KAAN */
-
- /* Icom ID-1 digital transceiver */
- ICOMID1Vid = 0x0C26,
- ICOMID1Did = 0x0004,
-
- FTASKRDR400Did = 0xC991, /* ASK RDR 400 series card reader */
- FTDSS20Did = 0xFC82, /* DSS-20 Sync Station for Sony Ericsson P800 */
-
- /*
- * Home Electronics (www.home-electro.com) USB gadgets
- */
- FTHETIRA1Did = 0xFA78, /* Tira-1 IR transceiver */
-
- /*
- * An infrared receiver and transmitter using the 8U232AM chip
- * http://www.usbuirt.com
- */
- FTUSBUIRTDid = 0xF850,
-
- FTELVUR100Did = 0xFB58, /* USB-RS232-Umsetzer (UR 100) */
- FTELVUM100Did = 0xFB5A, /* USB-Modul UM 100 */
- FTELVUO100Did = 0xFB5B, /* USB-Modul UO 100 */
- FTELVALC8500Did = 0xF06E, /* ALC 8500 Expert */
- FTELVCLI7000Did = 0xFB59, /* Computer-Light-Interface */
- FTELVPPS7330Did = 0xFB5C, /* Processor-Power-Supply (PPS 7330) */
- FTELVTFM100Did = 0xFB5D, /* Temperartur-Feuchte Messgeraet (TFM 100) */
- FTELVUDF77Did = 0xFB5E, /* USB DCF Funkurh (UDF 77) */
- FTELVUIO88Did = 0xFB5F, /* USB-I/O Interface (UIO 88) */
- FTELVUAD8Did = 0xF068, /* USB-AD-Wandler (UAD 8) */
- FTELVUDA7Did = 0xF069, /* USB-DA-Wandler (UDA 7) */
- FTELVUSI2Did = 0xF06A, /* USB-Schrittmotoren-Interface (USI 2) */
- FTELVT1100Did = 0xF06B, /* Thermometer (T 1100) */
- FTELVPCD200Did = 0xF06C, /* PC-Datenlogger (PCD 200) */
- FTELVULA200Did = 0xF06D, /* USB-LCD-Ansteuerung (ULA 200) */
- FTELVFHZ1000PCDid= 0xF06F, /* FHZ 1000 PC */
- FTELVCSI8Did = 0xE0F0, /* Computer-Schalt-Interface (CSI 8) */
- FTELVEM1000DLDid= 0xE0F1, /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */
- FTELVPCK100Did = 0xE0F2, /* PC-Kabeltester (PCK 100) */
- FTELVRFP500Did = 0xE0F3, /* HF-Leistungsmesser (RFP 500) */
- FTELVFS20SIGDid = 0xE0F4, /* Signalgeber (FS 20 SIG) */
- FTELVWS300PCDid = 0xE0F6, /* PC-Wetterstation (WS 300 PC) */
- FTELVFHZ1300PCDid= 0xE0E8, /* FHZ 1300 PC */
- FTELVWS500Did = 0xE0E9, /* PC-Wetterstation (WS 500) */
-
- /*
- * Definitions for ID TECH (http://www.idt-net.com) devices
- */
- IDTECHVid = 0x0ACD, /* ID TECH Vendor ID */
- IDTECHIDT1221UDid= 0x0300, /* IDT1221U USB to RS-232 */
-
- /*
- * Definitions for Omnidirectional Control Technology, Inc. devices
- */
- OCTVid = 0x0B39, /* OCT vendor ID */
-
- /*
- * Note: OCT US101 is also rebadged as Dick Smith Electronics
- * (NZ) XH6381, Dick Smith Electronics (Aus) XH6451, and SIIG
- * Inc. model US2308 hardware version 1.
- */
- OCTUS101Did = 0x0421, /* OCT US101 USB to RS-232 */
-
- /*
- * infrared receiver for access control with IR tags
- */
- FTPIEGROUPDid = 0xF208,
-
- /*
- * Definitions for Artemis astronomical USB based cameras
- * http://www.artemisccd.co.uk/
- */
-
- FTARTEMISDid = 0xDF28, /* All Artemis Cameras */
-
- FTATIKATK16Did = 0xDF30, /* ATIK ATK-16 Grayscale Camera */
- FTATIKATK16CDid = 0xDF32, /* ATIK ATK-16C Colour Camera */
- FTATIKATK16HRDid= 0xDF31, /* ATIK ATK-16HR Grayscale */
- FTATIKATK16HRCDid= 0xDF33, /* ATIK ATK-16HRC Colour Camera */
-
- /*
- * Protego products
- */
- PROTEGOSPECIAL1 = 0xFC70, /* special/unknown device */
- PROTEGOR2X0 = 0xFC71, /* R200-USB TRNG unit (R210, R220, and R230) */
- PROTEGOSPECIAL3 = 0xFC72, /* special/unknown device */
- PROTEGOSPECIAL4 = 0xFC73, /* special/unknown device */
-
- /*
- * Gude Analog- und Digitalsysteme GmbH
- */
- FTGUDEADSE808Did = 0xE808,
- FTGUDEADSE809Did = 0xE809,
- FTGUDEADSE80ADid = 0xE80A,
- FTGUDEADSE80BDid = 0xE80B,
- FTGUDEADSE80CDid = 0xE80C,
- FTGUDEADSE80DDid = 0xE80D,
- FTGUDEADSE80EDid = 0xE80E,
- FTGUDEADSE80FDid = 0xE80F,
- FTGUDEADSE888Did = 0xE888, /* Expert ISDN Control USB */
- FTGUDEADSE889Did = 0xE889, /* USB RS-232 OptoBridge */
- FTGUDEADSE88ADid = 0xE88A,
- FTGUDEADSE88BDid = 0xE88B,
- FTGUDEADSE88CDid = 0xE88C,
- FTGUDEADSE88DDid = 0xE88D,
- FTGUDEADSE88EDid = 0xE88E,
- FTGUDEADSE88FDid = 0xE88F,
-
- /*
- * Linx Technologies
- */
- LINXSDMUSBQSSDid= 0xF448, /* Linx SDM-USB-QS-S */
- LINXMASTERDEVEL2Did= 0xF449, /* Linx Master Development.0 */
- LINXFUTURE0Did = 0xF44A, /* Linx future device */
- LINXFUTURE1Did = 0xF44B, /* Linx future device */
- LINXFUTURE2Did = 0xF44C, /* Linx future device */
-
- /*
- * CCS Inc. ICDU/ICDU40 - the FT232BM used in a in-circuit-debugger
- * unit for PIC16's/PIC18's
- */
- FTCCSICDU200Did = 0xF9D0,
- FTCCSICDU401Did = 0xF9D1,
-
- /* Inside Accesso contactless reader (http://www.insidefr.com) */
- INSIDEACCESSO = 0xFAD0,
-
- /*
- * Intrepid Control Systems (http://www.intrepidcs.com/)
- * ValueCAN and NeoVI
- */
- INTREDidVid = 0x093C,
- INTREDidVALUECANDid= 0x0601,
- INTREDidNEOVIDid= 0x0701,
-
- /*
- * Falcom Wireless Communications GmbH
- */
- FALCOMVid = 0x0F94,
- FALCOMTWISTDid = 0x0001, /* Falcom Twist USB GPRS modem */
- FALCOMSAMBADid = 0x0005, /* Falcom Samba USB GPRS modem */
-
- /*
- * SUUNTO
- */
- FTSUUNTOSPORTSDid= 0xF680, /* Suunto Sports instrument */
-
- /*
- * B&B Electronics
- */
- BANDBVid = 0x0856, /* B&B Electronics Vendor ID */
- BANDBUSOTL4Did = 0xAC01, /* USOTL4 Isolated RS-485 */
- BANDBUSTL4Did = 0xAC02, /* USTL4 RS-485 Converter */
- BANDBUSO9ML2Did = 0xAC03, /* USO9ML2 Isolated RS-232 */
-
- /*
- * RM Michaelides CANview USB (http://www.rmcan.com)
- * CAN fieldbus interface adapter
- */
- FTRMCANVIEWDid = 0xfd60,
-
- /*
- * EVER Eco Pro UPS (http://www.ever.com.pl/)
- */
- EVERECOPROCDSDid = 0xe520, /* RS-232 converter */
-
- /*
- * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485,
- * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices
- */
- FT4NGALAXYDE0Did = 0x8372,
- FT4NGALAXYDE1Did = 0xF3C0,
- FT4NGALAXYDE2Did = 0xF3C1,
-
- /*
- * Mobility Electronics products.
- */
- MOBILITYVid = 0x1342,
- MOBILITYUSBSERIALDid= 0x0202, /* EasiDock USB 200 serial */
-
- /*
- * microHAM product IDs (http://www.microham.com)
- */
- FTMHAMKWDid = 0xEEE8, /* USB-KW interface */
- FTMHAMYSDid = 0xEEE9, /* USB-YS interface */
- FTMHAMY6Did = 0xEEEA, /* USB-Y6 interface */
- FTMHAMY8Did = 0xEEEB, /* USB-Y8 interface */
- FTMHAMICDid = 0xEEEC, /* USB-IC interface */
- FTMHAMDB9Did = 0xEEED, /* USB-DB9 interface */
- FTMHAMRS232Did = 0xEEEE, /* USB-RS232 interface */
- FTMHAMY9Did = 0xEEEF, /* USB-Y9 interface */
-
- /*
- * Active Robots product ids.
- */
- FTACTIVEROBOTSDid = 0xE548, /* USB comms board */
- XSENSCONVERTER0Did = 0xD388,
- XSENSCONVERTER1Did = 0xD389,
- XSENSCONVERTER2Did = 0xD38A,
- XSENSCONVERTER3Did = 0xD38B,
- XSENSCONVERTER4Did = 0xD38C,
- XSENSCONVERTER5Did = 0xD38D,
- XSENSCONVERTER6Did = 0xD38E,
- XSENSCONVERTER7Did = 0xD38F,
-
- /*
- * Xsens Technologies BV products (http://www.xsens.com).
- */
- FTTERATRONIKVCPDid = 0xEC88, /* Teratronik device */
- FTTERATRONIKD2XXDid = 0xEC89, /* Teratronik device */
-
- /*
- * Evolution Robotics products (http://www.evolution.com/).
- */
- EVOLUTIONVid = 0xDEEE,
- EVOLUTIONER1Did = 0x0300, /* ER1 Control Module */
-
- /* Pyramid Computer GmbH */
- FTPYRAMIDDid = 0xE6C8, /* Pyramid Appliance Display */
-
- /*
- * Posiflex inc retail equipment (http://www.posiflex.com.tw)
- */
- POSIFLEXVid = 0x0d3a,
- POSIFLEXPP7000Did= 0x0300, /* PP-7000II thermal printer */
-
- /*
- * Westrex International devices
- */
- FTWESTREXMODEL777Did = 0xDC00, /* Model 777 */
- FTWESTREXMODEL8900FDid = 0xDC01, /* Model 8900F */
-
- /*
- * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com)
- */
- FTRRCIRKITSLOCOBUFFERDid= 0xc7d0, /* LocoBuffer USB */
- FTECLOCOM1WIREDid = 0xEA90, /* COM to 1-Wire USB */
-
- /*
- * Papouch products (http://www.papouch.com/)
- */
- PAPOUCHVid = 0x5050,
- PAPOUCHTMUDid = 0x0400, /* TMU USB Thermometer */
-
- /*
- * ACG Identification Technologies GmbH products http://www.acg.de/
- */
- FTACGHFDUALDid = 0xDD20, /* HF Dual ISO Reader (RFID) */
- /*
- * new high speed devices
- */
- FT4232HDid = 0x6011, /* FTDI FT4232H based device */
-
-};
-
-/* Commands */
-enum {
- FTRESET = 0, /* Reset the port */
- FTSETMODEMCTRL, /* Set the modem control register */
- FTSETFLOWCTRL, /* Set flow control register */
- FTSETBAUDRATE, /* Set baud rate */
- FTSETDATA, /* Set the parameters, parity */
- FTGETMODEMSTATUS, /* Retrieve current value of modem ctl */
- FTSETEVENTCHAR, /* Set the event character */
- FTSETERRORCHAR, /* Set the error character */
- FTUNKNOWN,
- FTSETLATENCYTIMER, /* Set the latency timer */
- FTGETLATENCYTIMER, /* Get the latency timer */
- FTSETBITMODE, /* Set bit mode */
- FTGETPINS, /* Read pins state */
- FTGETE2READ = 0x90, /* Read address from 128-byte I2C EEPROM */
- FTSETE2WRITE, /* Write to address on 128-byte I2C EEPROM */
- FTSETE2ERASE, /* Erase address on 128-byte I2C EEPROM */
-};
-
-/* Port Identifier Table, index for interfaces */
-enum {
- PITDEFAULT = 0, /* SIOA */
- PITA, /* SIOA jtag if there is one */
-};
-
-enum {
- Rftdireq = 1<<6, /* bit for type of request */
-};
-
-/*
- * Commands Data size
- * Sets have wLength = 0
- * Gets have wValue = 0
- */
-enum {
- FTMODEMSTATUSSZ = 1,
- FTLATENCYTIMERSZ= 1,
- FTPINSSZ = 1,
- FTE2READSZ = 2,
-};
-
-/*
- * bRequest: FTGETE2READ
- * wIndex: Address of word to read
- * Data: Will return a word (2 bytes) of data from E2Address
- * Results put in the I2C 128 byte EEPROM string eeprom+(2*index)
- */
-
-/*
- * bRequest: FTSETE2WRITE
- * wIndex: Address of word to read
- * wValue: Value of the word
- * Data: Will return a word (2 bytes) of data from E2Address
- */
-
-/*
- * bRequest: FTSETE2ERASE
- * Erases the EEPROM
- * wIndex: 0
- */
-
-/*
- * bRequest: FTRESET
- * wValue: Ctl Val
- * wIndex: Port
- */
-enum {
- FTRESETCTLVAL = 0,
- FTRESETCTLVALPURGERX = 1,
- FTRESETCTLVALPURGETX = 2,
-};
-
-/*
- * BmRequestType: SET
- * bRequest: FTSETBAUDRATE
- * wValue: BaudDivisor value - see below
- * Bits 15 to 0 of the 17-bit divisor are placed in the request value.
- * Bit 16 is placed in bit 0 of the request index.
- */
-
-/* chip type */
-enum {
- SIO = 1,
- FT8U232AM = 2,
- FT232BM = 3,
- FT2232C = 4,
- FTKINDR = 5,
- FT2232H = 6,
- FT4232H = 7,
-};
-
-enum {
- FTb300 = 0,
- FTb600 = 1,
- FTb1200 = 2,
- FTb2400 = 3,
- FTb4800 = 4,
- FTb9600 = 5,
- FTb19200 = 6,
- FTb38400 = 7,
- FTb57600 = 8,
- FTb115200 = 9,
-};
-
-/*
- * bRequest: FTSETDATA
- * wValue: Data characteristics
- * bits 0-7 number of data bits
- * wIndex: Port
- */
-enum {
- FTSETDATAParNONE = 0 << 8,
- FTSETDATAParODD = 1 << 8,
- FTSETDATAParEVEN = 2 << 8,
- FTSETDATAParMARK = 3 << 8,
- FTSETDATAParSPACE = 4 << 8,
- FTSETDATASTOPBITS1 = 0 << 11,
- FTSETDATASTOPBITS15 = 1 << 11,
- FTSETDATASTOPBITS2 = 2 << 11,
- FTSETBREAK = 1 << 14,
-};
-
-/*
- * bRequest: FTSETMODEMCTRL
- * wValue: ControlValue (see below)
- * wIndex: Port
- */
-
-/*
- * bRequest: FTSETFLOWCTRL
- * wValue: Xoff/Xon
- * wIndex: Protocol/Port - hIndex is protocol; lIndex is port
- */
-enum {
- FTDISABLEFLOWCTRL= 0,
- FTRTSCTSHS = 1 << 8,
- FTDTRDSRHS = 2 << 8,
- FTXONXOFFHS = 4 << 8,
-};
-
-/*
- * bRequest: FTGETLATENCYTIMER
- * wIndex: Port
- * wLength: 0
- * Data: latency (on return)
- */
-
-/*
- * bRequest: FTSETBITMODE
- * wIndex: Port
- * either it is big bang mode, in which case
- * wValue: 1 byte L is the big bang mode BIG*
- * or BM is
- * wValue: 1 byte bitbang mode H, 1 byte bitmask for lines L
- */
-enum {
- BMSERIAL = 0, /* reset, turn off bit-bang mode */
-
- BIGBMNORMAL = 1, /* normal bit-bang mode */
- BIGBMSPI = 2, /* spi bit-bang mode */
-
- BMABM = 1<<8, /* async mode */
- BMMPSSE = 2<<8,
- BMSYNCBB = 4<<8, /* sync bit-bang -- 2232x and R-type */
- BMMCU = 8<<8, /* MCU Host Bus -- 2232x */
- BMOPTO = 0x10<<8, /* opto-isolated<<8, 2232x */
- BMCBUS = 0x20<<8, /* CBUS pins of R-type chips */
- BMSYNCFF = 0x40<<8, /* Single Channel Sync FIFO, 2232H only */
-};
-
-/*
- * bRequest: FTSETLATENCYTIMER
- * wValue: Latency (milliseconds 1-255)
- * wIndex: Port
- */
-enum {
- FTLATENCYDEFAULT = 2,
-};
-
-/*
- * BmRequestType: SET
- * bRequest: FTSETEVENTCHAR
- * wValue: EventChar
- * wIndex: Port
- * 0-7 lower bits event char
- * 8 enable
- */
-enum {
- FTEVCHARENAB = 1<<8,
-};
-
-/*
- * BmRequestType: SET
- * bRequest: FTSETERRORCHAR
- * wValue: Error Char
- * wIndex: Port
- * 0-7 lower bits event char
- * 8 enable
- */
-enum {
- FTERRCHARENAB = 1<<8,
-};
-/*
- * BmRequestType: GET
- * bRequest: FTGETMODEMSTATUS
- * wIndex: Port
- * wLength: 1
- * Data: Status
- */
-enum {
- FTCTSMASK = 0x10,
- FTDSRMASK = 0x20,
- FTRIMASK = 0x40,
- FTRLSDMASK = 0x80,
-};
-
-enum {
- /* byte 0 of in data hdr */
- FTICTS = 1 << 4,
- FTIDSR = 1 << 5,
- FTIRI = 1 << 6,
- FTIRLSD = 1 << 7, /* receive line signal detect */
-
- /* byte 1 of in data hdr */
- FTIDR = 1<<0, /* data ready */
- FTIOE = 1<<1, /* overrun error */
- FTIPE = 1<<2, /* parity error */
- FTIFE = 1<<3, /* framing error */
- FTIBI = 1<<4, /* break interrupt */
- FTITHRE = 1<<5, /* xmitter holding register */
- FTITEMT = 1<<6, /* xmitter empty */
- FTIFIFO = 1<<7, /* error in rcv fifo */
-
- /* byte 0 of out data hdr len does not include byte 0 */
- FTOLENMSK= 0x3F,
- FTOPORT = 0x80, /* must be set */
-};
-
-extern Serialops ftops;
-
-int ftmatch(Serial *ser, char *info);
diff --git a/sys/src/cmd/usb/serial/main.c b/sys/src/cmd/usb/serial/main.c
deleted file mode 100644
index 4404497d1..000000000
--- a/sys/src/cmd/usb/serial/main.c
+++ /dev/null
@@ -1,75 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-#include "usbfs.h"
-#include "serial.h"
-#include "ucons.h"
-#include "prolific.h"
-#include "ftdi.h"
-
-enum {
- Arglen = 80,
-};
-
-typedef struct Parg Parg;
-
-/* keep in sync with serial.c */
-static void
-usage(void)
-{
- fprint(2, "usage: %s [-dD] [-N nb] [-m mtpt] [-s srv] [dev...]\n", argv0);
- threadexitsall("usage");
-}
-
-static int
-matchserial(char *info, void*)
-{
- if(uconsmatch(info) == 0 || plmatch(info) == 0 ||
- ftmatch(nil, info) == 0)
- return 0;
- return -1;
-}
-
-void
-threadmain(int argc, char **argv)
-{
- char *mnt, *srv, *as, *ae;
- char args[Arglen];
-
- mnt = "/dev";
- srv = nil;
-
- quotefmtinstall();
- ae = args + sizeof args;
- as = seprint(args, ae, "serial");
- ARGBEGIN{
- case 'D':
- usbfsdebug++;
- break;
- case 'd':
- usbdebug++;
- as = seprint(as, ae, " -d");
- break;
- case 'N':
- as = seprint(as, ae, " -N %s", EARGF(usage()));
- break;
- case 'm':
- mnt = EARGF(usage());
- break;
- case 's':
- srv = EARGF(usage());
- break;
- default:
- usage();
- break;
- }ARGEND;
-
- rfork(RFNOTEG);
- fmtinstall('U', Ufmt);
- threadsetgrp(threadid());
-
- usbfsinit(srv, mnt, &usbdirfs, MAFTER|MCREATE);
- startdevs(args, argv, argc, matchserial, nil, serialmain);
- threadexits(nil);
-}
diff --git a/sys/src/cmd/usb/serial/mkfile b/sys/src/cmd/usb/serial/mkfile
deleted file mode 100644
index 5a01de9e7..000000000
--- a/sys/src/cmd/usb/serial/mkfile
+++ /dev/null
@@ -1,37 +0,0 @@
-</$objtype/mkfile
-
-TARG=serial
-OFILES=main.$O
-LIBDOFILES=ftdi.$O serial.$O prolific.$O ucons.$O
-HFILES=\
- ../lib/usb.h\
- ftdi.h\
- prolific.h\
- serial.h\
- ucons.h\
-
-LIBD=../lib/usbdev.a$O
-LIBU=../lib/usb.a$O
-LIB=\
- $LIBD\
- $LIBU\
-
-BIN=/$objtype/bin/usb
-
-UPDATE=\
- mkfile\
- $HFILES\
- ${OFILES:%.$O=%.c}\
-
-</sys/src/cmd/mkone
-
-CFLAGS=-I../lib $CFLAGS
-
-$LIBU:
- cd ../lib
- mk install
- mk clean
-
-$LIBD:V: $LIBDOFILES
- ar vu $LIBD $newprereq
- rm $newprereq
diff --git a/sys/src/cmd/usb/serial/prolific.c b/sys/src/cmd/usb/serial/prolific.c
deleted file mode 100644
index ad4db7f97..000000000
--- a/sys/src/cmd/usb/serial/prolific.c
+++ /dev/null
@@ -1,438 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-#include "usbfs.h"
-#include "serial.h"
-#include "prolific.h"
-
-Cinfo plinfo[] = {
- { PL2303Vid, PL2303Did },
- { PL2303Vid, PL2303DidRSAQ2 },
- { PL2303Vid, PL2303DidDCU11 },
- { PL2303Vid, PL2303DidRSAQ3 },
- { PL2303Vid, PL2303DidPHAROS },
- { PL2303Vid, PL2303DidALDIGA },
- { PL2303Vid, PL2303DidMMX },
- { PL2303Vid, PL2303DidGPRS },
- { IODATAVid, IODATADid },
- { IODATAVid, IODATADidRSAQ5 },
- { ATENVid, ATENDid },
- { ATENVid2, ATENDid },
- { ELCOMVid, ELCOMDid },
- { ELCOMVid, ELCOMDidUCSGT },
- { ITEGNOVid, ITEGNODid },
- { ITEGNOVid, ITEGNODid2080 },
- { MA620Vid, MA620Did },
- { RATOCVid, RATOCDid },
- { TRIPPVid, TRIPPDid },
- { RADIOSHACKVid,RADIOSHACKDid },
- { DCU10Vid, DCU10Did },
- { SITECOMVid, SITECOMDid },
- { ALCATELVid, ALCATELDid },
- { SAMSUNGVid, SAMSUNGDid },
- { SIEMENSVid, SIEMENSDidSX1 },
- { SIEMENSVid, SIEMENSDidX65 },
- { SIEMENSVid, SIEMENSDidX75 },
- { SIEMENSVid, SIEMENSDidEF81 },
- { SYNTECHVid, SYNTECHDid },
- { NOKIACA42Vid, NOKIACA42Did },
- { CA42CA42Vid, CA42CA42Did },
- { SAGEMVid, SAGEMDid },
- { LEADTEKVid, LEADTEK9531Did },
- { SPEEDDRAGONVid,SPEEDDRAGONDid },
- { DATAPILOTU2Vid,DATAPILOTU2Did },
- { BELKINVid, BELKINDid },
- { ALCORVid, ALCORDid },
- { WS002INVid, WS002INDid },
- { COREGAVid, COREGADid },
- { YCCABLEVid, YCCABLEDid },
- { SUPERIALVid, SUPERIALDid },
- { HPVid, HPLD220Did },
- { 0, 0 },
-};
-
-int
-plmatch(char *info)
-{
- Cinfo *ip;
- char buf[50];
-
- for(ip = plinfo; ip->vid != 0; ip++){
- snprint(buf, sizeof buf, "vid %#06x did %#06x",
- ip->vid, ip->did);
- dsprint(2, "serial: %s %s\n", buf, info);
- if(strstr(info, buf) != nil)
- return 0;
- }
- return -1;
-}
-
-static void statusreader(void *u);
-
-static void
-dumpbuf(uchar *buf, int bufsz)
-{
- int i;
-
- for(i=0; i<bufsz; i++)
- print("buf[%d]=%#ux ", i, buf[i]);
- print("\n");
-}
-
-static int
-vendorread(Serialport *p, int val, int index, uchar *buf)
-{
- int res;
- Serial *ser;
-
- ser = p->s;
-
- dsprint(2, "serial: vendorread val: 0x%x idx:%d buf:%p\n",
- val, index, buf);
- res = usbcmd(ser->dev, Rd2h | Rvendor | Rdev, VendorReadReq,
- val, index, buf, 1);
- dsprint(2, "serial: vendorread res:%d\n", res);
- return res;
-}
-
-static int
-vendorwrite(Serialport *p, int val, int index)
-{
- int res;
- Serial *ser;
-
- ser = p->s;
-
- dsprint(2, "serial: vendorwrite val: 0x%x idx:%d\n", val, index);
- res = usbcmd(ser->dev, Rh2d | Rvendor | Rdev, VendorWriteReq,
- val, index, nil, 0);
- dsprint(2, "serial: vendorwrite res:%d\n", res);
- return res;
-}
-
-/* BUG: I could probably read Dcr0 and set only the bits */
-static int
-plmodemctl(Serialport *p, int set)
-{
- Serial *ser;
-
- ser = p->s;
-
- if(set == 0){
- p->mctl = 0;
- vendorwrite(p, Dcr0Idx|DcrSet, Dcr0Init);
- return 0;
- }
-
- p->mctl = 1;
- if(ser->type == TypeHX)
- vendorwrite(p, Dcr0Idx|DcrSet, Dcr0Init|Dcr0HwFcX);
- else
- vendorwrite(p, Dcr0Idx|DcrSet, Dcr0Init|Dcr0HwFcH);
- return 0;
-}
-
-static int
-plgetparam(Serialport *p)
-{
- uchar buf[ParamReqSz];
- int res;
- Serial *ser;
-
- ser = p->s;
-
-
- res = usbcmd(ser->dev, Rd2h | Rclass | Riface, GetLineReq,
- 0, 0, buf, sizeof buf);
- p->baud = GET4(buf);
-
- /*
- * with the Pl9 interface it is not possible to set `1.5' as stop bits
- * for the prologic:
- * 0 is 1 stop bit
- * 1 is 1.5 stop bits
- * 2 is 2 stop bits
- */
- if(buf[4] == 1)
- fprint(2, "warning, stop bit set to 1.5 unsupported");
- else if(buf[4] == 0)
- p->stop = 1;
- else if(buf[4] == 2)
- p->stop = 2;
- p->parity = buf[5];
- p->bits = buf[6];
-
- dsprint(2, "serial: getparam: ");
- if(serialdebug)
- dumpbuf(buf, sizeof buf);
- dsprint(2, "serial: getparam res: %d\n", res);
- return res;
-}
-
-static int
-plsetparam(Serialport *p)
-{
- uchar buf[ParamReqSz];
- int res;
- Serial *ser;
-
- ser = p->s;
-
- PUT4(buf, p->baud);
-
- if(p->stop == 1)
- buf[4] = 0;
- else if(p->stop == 2)
- buf[4] = 2; /* see comment in getparam */
- buf[5] = p->parity;
- buf[6] = p->bits;
-
- dsprint(2, "serial: setparam: ");
- if(serialdebug)
- dumpbuf(buf, sizeof buf);
- res = usbcmd(ser->dev, Rh2d | Rclass | Riface, SetLineReq,
- 0, 0, buf, sizeof buf);
- plmodemctl(p, p->mctl);
- plgetparam(p); /* make sure our state corresponds */
-
- dsprint(2, "serial: setparam res: %d\n", res);
- return res;
-}
-
-static int
-revid(ulong devno)
-{
- switch(devno){
- case RevH:
- return TypeH;
- case RevX:
- case RevHX:
- case Rev1:
- return TypeHX;
- default:
- return TypeUnk;
- }
-}
-
-/* linux driver says the release id is not always right */
-static int
-heuristicid(ulong csp, ulong maxpkt)
-{
- if(Class(csp) == 0x02)
- return TypeH;
- else if(maxpkt == 0x40)
- return TypeHX;
- else if(Class(csp) == 0x00 || Class(csp) == 0xFF)
- return TypeH;
- else{
- fprint(2, "serial: chip unknown, setting to HX version\n");
- return TypeHX;
- }
-}
-
-static int
-plinit(Serialport *p)
-{
- char *st;
- uchar *buf;
- ulong csp, maxpkt, dno;
- Serial *ser;
-
- ser = p->s;
- buf = emallocz(VendorReqSz, 1);
- dsprint(2, "plinit\n");
-
- csp = ser->dev->usb->csp;
- maxpkt = ser->dev->maxpkt;
- dno = ser->dev->usb->dno;
-
- if((ser->type = revid(dno)) == TypeUnk)
- ser->type = heuristicid(csp, maxpkt);
-
- dsprint(2, "serial: type %d\n", ser->type);
-
- vendorread(p, 0x8484, 0, buf);
- vendorwrite(p, 0x0404, 0);
- vendorread(p, 0x8484, 0, buf);
- vendorread(p, 0x8383, 0, buf);
- vendorread(p, 0x8484, 0, buf);
- vendorwrite(p, 0x0404, 1);
- vendorread(p, 0x8484, 0, buf);
- vendorread(p, 0x8383, 0, buf);
-
- vendorwrite(p, Dcr0Idx|DcrSet, Dcr0Init);
- vendorwrite(p, Dcr1Idx|DcrSet, Dcr1Init);
-
- if(ser->type == TypeHX)
- vendorwrite(p, Dcr2Idx|DcrSet, Dcr2InitX);
- else
- vendorwrite(p, Dcr2Idx|DcrSet, Dcr2InitH);
-
- plgetparam(p);
- qunlock(ser);
- free(buf);
- st = emallocz(255, 1);
- qlock(ser);
- if(serialdebug)
- serdumpst(p, st, 255);
- dsprint(2, st);
- free(st);
- /* p gets freed by closedev, the process has a reference */
- incref(ser->dev);
- proccreate(statusreader, p, 8*1024);
- return 0;
-}
-
-static int
-plsetbreak(Serialport *p, int val)
-{
- Serial *ser;
-
- ser = p->s;
- return usbcmd(ser->dev, Rh2d | Rclass | Riface,
- (val != 0? BreakOn: BreakOff), val, 0, nil, 0);
-}
-
-static int
-plclearpipes(Serialport *p)
-{
- Serial *ser;
-
- ser = p->s;
-
- if(ser->type == TypeHX){
- vendorwrite(p, PipeDSRst, 0);
- vendorwrite(p, PipeUSRst, 0);
- }else{
- if(unstall(ser->dev, p->epout, Eout) < 0)
- dprint(2, "disk: unstall epout: %r\n");
- if(unstall(ser->dev, p->epin, Ein) < 0)
- dprint(2, "disk: unstall epin: %r\n");
- if(unstall(ser->dev, p->epintr, Ein) < 0)
- dprint(2, "disk: unstall epintr: %r\n");
- }
- return 0;
-}
-
-static int
-setctlline(Serialport *p, uchar val)
-{
- Serial *ser;
-
- ser = p->s;
- return usbcmd(ser->dev, Rh2d | Rclass | Riface, SetCtlReq,
- val, 0, nil, 0);
-}
-
-static void
-composectl(Serialport *p)
-{
- if(p->rts)
- p->ctlstate |= CtlRTS;
- else
- p->ctlstate &= ~CtlRTS;
- if(p->dtr)
- p->ctlstate |= CtlDTR;
- else
- p->ctlstate &= ~CtlDTR;
-}
-
-static int
-plsendlines(Serialport *p)
-{
- int res;
-
- dsprint(2, "serial: sendlines: %#2.2x\n", p->ctlstate);
- composectl(p);
- res = setctlline(p, p->ctlstate);
- dsprint(2, "serial: sendlines res: %d\n", res);
- return 0;
-}
-
-static int
-plreadstatus(Serialport *p)
-{
- int nr, dfd;
- char err[40];
- uchar buf[VendorReqSz];
- Serial *ser;
-
- ser = p->s;
-
- qlock(ser);
- dsprint(2, "serial: reading from interrupt\n");
- dfd = p->epintr->dfd;
-
- qunlock(ser);
- nr = read(dfd, buf, sizeof buf);
- qlock(ser);
- snprint(err, sizeof err, "%r");
- dsprint(2, "serial: interrupt read %d %r\n", nr);
-
- if(nr < 0 && strstr(err, "timed out") == nil){
- dsprint(2, "serial: need to recover, status read %d %r\n", nr);
- if(serialrecover(ser, nil, nil, err) < 0){
- qunlock(ser);
- return -1;
- }
- }
- if(nr < 0)
- dsprint(2, "serial: reading status: %r");
- else if(nr >= sizeof buf - 1){
- p->dcd = buf[8] & DcdStatus;
- p->dsr = buf[8] & DsrStatus;
- p->cts = buf[8] & BreakerrStatus;
- p->ring = buf[8] & RingStatus;
- p->cts = buf[8] & CtsStatus;
- if(buf[8] & FrerrStatus)
- p->nframeerr++;
- if(buf[8] & ParerrStatus)
- p->nparityerr++;
- if(buf[8] & OvererrStatus)
- p->novererr++;
- } else
- dsprint(2, "serial: bad status read %d\n", nr);
- dsprint(2, "serial: finished read from interrupt %d\n", nr);
- qunlock(ser);
- return 0;
-}
-
-static void
-statusreader(void *u)
-{
- Serialport *p;
- Serial *ser;
-
- p = u;
- ser = p->s;
- threadsetname("statusreaderproc");
- while(plreadstatus(p) >= 0)
- ;
- fprint(2, "serial: statusreader exiting\n");
- closedev(ser->dev);
-}
-
-/*
- * Maximum number of bytes transferred per frame
- * The output buffer size cannot be increased due to the size encoding
- */
-
-static int
-plseteps(Serialport *p)
-{
- devctl(p->epin, "maxpkt 256");
- devctl(p->epout, "maxpkt 256");
- return 0;
-}
-
-Serialops plops = {
- .init = plinit,
- .getparam = plgetparam,
- .setparam = plsetparam,
- .clearpipes = plclearpipes,
- .sendlines = plsendlines,
- .modemctl = plmodemctl,
- .setbreak = plsetbreak,
- .seteps = plseteps,
-};
diff --git a/sys/src/cmd/usb/serial/prolific.h b/sys/src/cmd/usb/serial/prolific.h
deleted file mode 100644
index d07279315..000000000
--- a/sys/src/cmd/usb/serial/prolific.h
+++ /dev/null
@@ -1,178 +0,0 @@
-enum {
- /* flavours of the device */
- TypeH,
- TypeHX,
- TypeUnk,
-
- RevH = 0x0202,
- RevX = 0x0300,
- RevHX = 0x0400,
- Rev1 = 0x0001,
-
- /* usbcmd parameters */
- SetLineReq = 0x20,
-
- SetCtlReq = 0x22,
-
- BreakReq = 0x23,
- BreakOn = 0xffff,
- BreakOff = 0x0000,
-
- GetLineReq = 0x21,
-
- VendorWriteReq = 0x01, /* BUG: is this a standard request? */
- VendorReadReq = 0x01,
-
- ParamReqSz = 7,
- VendorReqSz = 10,
-
- /* status read from interrupt endpoint */
- DcdStatus = 0x01,
- DsrStatus = 0x02,
- BreakerrStatus = 0x04,
- RingStatus = 0x08,
- FrerrStatus = 0x10,
- ParerrStatus = 0x20,
- OvererrStatus = 0x40,
- CtsStatus = 0x80,
-
- DcrGet = 0x80,
- DcrSet = 0x00,
-
- Dcr0Idx = 0x00,
-
- Dcr0Init = 0x0001,
- Dcr0HwFcH = 0x0040,
- Dcr0HwFcX = 0x0060,
-
- Dcr1Idx = 0x01,
-
- Dcr1Init = 0x0000,
- Dcr1InitH = 0x0080,
- Dcr1InitX = 0x0000,
-
- Dcr2Idx = 0x02,
-
- Dcr2InitH = 0x0024,
- Dcr2InitX = 0x0044,
-
- PipeDSRst = 0x08,
- PipeUSRst = 0x09,
-
-};
-
-enum {
- PL2303Vid = 0x067b,
- PL2303Did = 0x2303,
- PL2303DidRSAQ2 = 0x04bb,
- PL2303DidDCU11 = 0x1234,
- PL2303DidPHAROS = 0xaaa0,
- PL2303DidRSAQ3 = 0xaaa2,
- PL2303DidALDIGA = 0x0611,
- PL2303DidMMX = 0x0612,
- PL2303DidGPRS = 0x0609,
-
- ATENVid = 0x0557,
- ATENVid2 = 0x0547,
- ATENDid = 0x2008,
-
- IODATAVid = 0x04bb,
- IODATADid = 0x0a03,
- IODATADidRSAQ5 = 0x0a0e,
-
- ELCOMVid = 0x056e,
- ELCOMDid = 0x5003,
- ELCOMDidUCSGT = 0x5004,
-
- ITEGNOVid = 0x0eba,
- ITEGNODid = 0x1080,
- ITEGNODid2080 = 0x2080,
-
- MA620Vid = 0x0df7,
- MA620Did = 0x0620,
-
- RATOCVid = 0x0584,
- RATOCDid = 0xb000,
-
- TRIPPVid = 0x2478,
- TRIPPDid = 0x2008,
-
- RADIOSHACKVid = 0x1453,
- RADIOSHACKDid = 0x4026,
-
- DCU10Vid = 0x0731,
- DCU10Did = 0x0528,
-
- SITECOMVid = 0x6189,
- SITECOMDid = 0x2068,
-
- /* Alcatel OT535/735 USB cable */
- ALCATELVid = 0x11f7,
- ALCATELDid = 0x02df,
-
- /* Samsung I330 phone cradle */
- SAMSUNGVid = 0x04e8,
- SAMSUNGDid = 0x8001,
-
- SIEMENSVid = 0x11f5,
- SIEMENSDidSX1 = 0x0001,
- SIEMENSDidX65 = 0x0003,
- SIEMENSDidX75 = 0x0004,
- SIEMENSDidEF81 = 0x0005,
-
- SYNTECHVid = 0x0745,
- SYNTECHDid = 0x0001,
-
- /* Nokia CA-42 Cable */
- NOKIACA42Vid = 0x078b,
- NOKIACA42Did = 0x1234,
-
- /* CA-42 CLONE Cable www.ca-42.com chipset: Prolific Technology Inc */
- CA42CA42Vid = 0x10b5,
- CA42CA42Did = 0xac70,
-
- SAGEMVid = 0x079b,
- SAGEMDid = 0x0027,
-
- /* Leadtek GPS 9531 (ID 0413:2101) */
- LEADTEKVid = 0x0413,
- LEADTEK9531Did = 0x2101,
-
- /* USB GSM cable from Speed Dragon Multimedia, Ltd */
- SPEEDDRAGONVid = 0x0e55,
- SPEEDDRAGONDid = 0x110b,
-
- /* DATAPILOT Universal-2 Phone Cable */
- BELKINVid = 0x050d,
- BELKINDid = 0x0257,
-
- /* Belkin "F5U257" Serial Adapter */
- DATAPILOTU2Vid = 0x0731,
- DATAPILOTU2Did = 0x2003,
-
- ALCORVid = 0x058F,
- ALCORDid = 0x9720,
-
- /* Willcom WS002IN Data Driver (by NetIndex Inc.) */,
- WS002INVid = 0x11f6,
- WS002INDid = 0x2001,
-
- /* Corega CG-USBRS232R Serial Adapter */,
- COREGAVid = 0x07aa,
- COREGADid = 0x002a,
-
- /* Y.C. Cable U.S.A., Inc - USB to RS-232 */,
- YCCABLEVid = 0x05ad,
- YCCABLEDid = 0x0fba,
-
- /* "Superial" USB - Serial */,
- SUPERIALVid = 0x5372,
- SUPERIALDid = 0x2303,
-
- /* Hewlett-Packard LD220-HP POS Pole Display */,
- HPVid = 0x03f0,
- HPLD220Did = 0x3524,
-};
-
-extern Serialops plops;
-int plmatch(char *info);
diff --git a/sys/src/cmd/usb/serial/serial.c b/sys/src/cmd/usb/serial/serial.c
deleted file mode 100644
index 33aef3be5..000000000
--- a/sys/src/cmd/usb/serial/serial.c
+++ /dev/null
@@ -1,890 +0,0 @@
-/*
- * This part takes care of locking except for initialization and
- * other threads created by the hw dep. drivers.
- */
-
-#include <u.h>
-#include <libc.h>
-#include <ctype.h>
-#include <thread.h>
-#include "usb.h"
-#include "usbfs.h"
-#include "serial.h"
-#include "prolific.h"
-#include "ucons.h"
-#include "ftdi.h"
-
-int serialdebug;
-
-enum {
- /* Qids. Maintain order (relative to dirtabs structs) */
- Qroot = 0,
- Qctl,
- Qdata,
- Qmax,
-};
-
-typedef struct Dirtab Dirtab;
-struct Dirtab {
- char *name;
- int mode;
-};
-
-static Dirtab dirtab[] = {
- [Qroot] "/", DMDIR|0555,
- [Qdata] "%s", 0660,
- [Qctl] "%sctl", 0664,
-};
-
-static int sdebug;
-
-static void
-serialfatal(Serial *ser)
-{
- Serialport *p;
- int i;
-
- dsprint(2, "serial: fatal error, detaching\n");
- devctl(ser->dev, "detach");
-
- for(i = 0; i < ser->nifcs; i++){
- p = &ser->p[i];
- usbfsdel(&p->fs);
- if(p->w4data != nil)
- chanclose(p->w4data);
- if(p->gotdata != nil)
- chanclose(p->gotdata);
- if(p->readc)
- chanclose(p->readc);
- }
-}
-
-/* I sleep with the lock... only way to drain in general */
-static void
-serialdrain(Serialport *p)
-{
- Serial *ser;
- uint baud, pipesize;
-
- ser = p->s;
- baud = p->baud;
-
- if(p->baud == ~0)
- return;
- if(ser->maxwtrans < 256)
- pipesize = 256;
- else
- pipesize = ser->maxwtrans;
- /* wait for the at least 256-byte pipe to clear */
- sleep(10 + pipesize/((1 + baud)*1000));
- if(ser->clearpipes != nil)
- ser->clearpipes(p);
-}
-
-int
-serialreset(Serial *ser)
-{
- Serialport *p;
- int i, res;
-
- res = 0;
- /* cmd for reset */
- for(i = 0; i < ser->nifcs; i++){
- p = &ser->p[i];
- serialdrain(p);
- }
- if(ser->reset != nil)
- res = ser->reset(ser, nil);
- return res;
-}
-
-/* call this if something goes wrong, must be qlocked */
-int
-serialrecover(Serial *ser, Serialport *p, Dev *ep, char *err)
-{
- if(p != nil)
- dprint(2, "serial[%d], %s: %s, level %d\n", p->interfc,
- p->name, err, ser->recover);
- else
- dprint(2, "serial[%s], global error, level %d\n",
- ser->p[0].name, ser->recover);
- ser->recover++;
- if(strstr(err, "detached") != nil)
- return -1;
- if(ser->recover < 3){
- if(p != nil){
- if(ep != nil){
- if(ep == p->epintr)
- unstall(ser->dev, p->epintr, Ein);
- if(ep == p->epin)
- unstall(ser->dev, p->epin, Ein);
- if(ep == p->epout)
- unstall(ser->dev, p->epout, Eout);
- return 0;
- }
-
- if(p->epintr != nil)
- unstall(ser->dev, p->epintr, Ein);
- if(p->epin != nil)
- unstall(ser->dev, p->epin, Ein);
- if(p->epout != nil)
- unstall(ser->dev, p->epout, Eout);
- }
- return 0;
- }
- if(ser->recover > 4 && ser->recover < 8)
- serialfatal(ser);
- if(ser->recover > 8){
- ser->reset(ser, p);
- return 0;
- }
- if(serialreset(ser) < 0)
- return -1;
- return 0;
-}
-
-static int
-serialctl(Serialport *p, char *cmd)
-{
- Serial *ser;
- int c, i, n, nf, nop, nw, par, drain, set, lines;
- char *f[16];
- uchar x;
-
- ser = p->s;
- drain = set = lines = 0;
- nf = tokenize(cmd, f, nelem(f));
- for(i = 0; i < nf; i++){
- if(strncmp(f[i], "break", 5) == 0){
- if(ser->setbreak != nil)
- ser->setbreak(p, 1);
- continue;
- }
-
- nop = 0;
- n = atoi(f[i]+1);
- c = *f[i];
- if (isascii(c) && isupper(c))
- c = tolower(c);
- switch(c){
- case 'b':
- drain++;
- p->baud = n;
- set++;
- break;
- case 'c':
- p->dcd = n;
- // lines++;
- ++nop;
- break;
- case 'd':
- p->dtr = n;
- lines++;
- break;
- case 'e':
- p->dsr = n;
- // lines++;
- ++nop;
- break;
- case 'f': /* flush the pipes */
- drain++;
- break;
- case 'h': /* hangup?? */
- p->rts = p->dtr = 0;
- lines++;
- fprint(2, "serial: %c, unsure ctl\n", c);
- break;
- case 'i':
- ++nop;
- break;
- case 'k':
- drain++;
- ser->setbreak(p, 1);
- sleep(n);
- ser->setbreak(p, 0);
- break;
- case 'l':
- drain++;
- p->bits = n;
- set++;
- break;
- case 'm':
- drain++;
- if(ser->modemctl != nil)
- ser->modemctl(p, n);
- if(n == 0)
- p->cts = 0;
- break;
- case 'n':
- p->blocked = n;
- ++nop;
- break;
- case 'p': /* extended... */
- if(strlen(f[i]) != 2)
- return -1;
- drain++;
- par = f[i][1];
- if(par == 'n')
- p->parity = 0;
- else if(par == 'o')
- p->parity = 1;
- else if(par == 'e')
- p->parity = 2;
- else if(par == 'm') /* mark parity */
- p->parity = 3;
- else if(par == 's') /* space parity */
- p->parity = 4;
- else
- return -1;
- set++;
- break;
- case 'q':
- // drain++;
- p->limit = n;
- ++nop;
- break;
- case 'r':
- drain++;
- p->rts = n;
- lines++;
- break;
- case 's':
- drain++;
- p->stop = n;
- set++;
- break;
- case 'w':
- /* ?? how do I put this */
- p->timer = n * 100000LL;
- ++nop;
- break;
- case 'x':
- if(n == 0)
- x = CTLS;
- else
- x = CTLQ;
- if(ser->wait4write != nil)
- nw = ser->wait4write(p, &x, 1);
- else
- nw = write(p->epout->dfd, &x, 1);
- if(nw != 1){
- serialrecover(ser, p, p->epout, "");
- return -1;
- }
- break;
- }
- /*
- * don't print. the condition is harmless and the print
- * splatters all over the display.
- */
- USED(nop);
- if (0 && nop)
- fprint(2, "serial: %c, unsupported nop ctl\n", c);
- }
- if(drain)
- serialdrain(p);
- if(lines && !set){
- if(ser->sendlines != nil && ser->sendlines(p) < 0)
- return -1;
- } else if(set){
- if(ser->setparam != nil && ser->setparam(p) < 0)
- return -1;
- }
- ser->recover = 0;
- return 0;
-}
-
-char *pformat = "noems";
-
-char *
-serdumpst(Serialport *p, char *buf, int bufsz)
-{
- char *e, *s;
- Serial *ser;
-
- ser = p->s;
-
- e = buf + bufsz;
- s = seprint(buf, e, "b%d ", p->baud);
- s = seprint(s, e, "c%d ", p->dcd); /* unimplemented */
- s = seprint(s, e, "d%d ", p->dtr);
- s = seprint(s, e, "e%d ", p->dsr); /* unimplemented */
- s = seprint(s, e, "l%d ", p->bits);
- s = seprint(s, e, "m%d ", p->mctl);
- if(p->parity >= 0 || p->parity < strlen(pformat))
- s = seprint(s, e, "p%c ", pformat[p->parity]);
- else
- s = seprint(s, e, "p%c ", '?');
- s = seprint(s, e, "r%d ", p->rts);
- s = seprint(s, e, "s%d ", p->stop);
- s = seprint(s, e, "i%d ", p->fifo);
- s = seprint(s, e, "\ndev(%d) ", 0);
- s = seprint(s, e, "type(%d) ", ser->type);
- s = seprint(s, e, "framing(%d) ", p->nframeerr);
- s = seprint(s, e, "overruns(%d) ", p->novererr);
- s = seprint(s, e, "berr(%d) ", p->nbreakerr);
- s = seprint(s, e, " serr(%d)\n", p->nparityerr);
- return s;
-}
-
-static int
-serinit(Serialport *p)
-{
- int res;
- res = 0;
- Serial *ser;
-
- ser = p->s;
-
- if(ser->init != nil)
- res = ser->init(p);
- if(ser->getparam != nil)
- ser->getparam(p);
- p->nframeerr = p->nparityerr = p->nbreakerr = p->novererr = 0;
-
- return res;
-}
-
-static int
-dwalk(Usbfs *fs, Fid *fid, char *name)
-{
- int i;
- char *dname;
- Qid qid;
- Serialport *p;
-
- qid = fid->qid;
- if((qid.type & QTDIR) == 0){
- werrstr("walk in non-directory");
- return -1;
- }
-
- if(strcmp(name, "..") == 0){
- /* must be /eiaU%d; i.e. our root dir. */
- fid->qid.path = Qroot | fs->qid;
- fid->qid.vers = 0;
- fid->qid.type = QTDIR;
- return 0;
- }
-
- p = fs->aux;
- for(i = 1; i < nelem(dirtab); i++){
- dname = smprint(dirtab[i].name, p->name);
- if(strcmp(name, dname) == 0){
- qid.path = i | fs->qid;
- qid.vers = 0;
- qid.type = dirtab[i].mode >> 24;
- fid->qid = qid;
- free(dname);
- return 0;
- } else
- free(dname);
- }
- werrstr(Enotfound);
- return -1;
-}
-
-static void
-dostat(Usbfs *fs, int path, Dir *d)
-{
- Dirtab *t;
- Serialport *p;
-
- t = &dirtab[path];
- d->qid.path = path;
- d->qid.type = t->mode >> 24;
- d->mode = t->mode;
- p = fs->aux;
-
- if(strcmp(t->name, "/") == 0)
- d->name = t->name;
- else
- snprint(d->name, Namesz, t->name, p->fs.name);
- d->length = 0;
-}
-
-static int
-dstat(Usbfs *fs, Qid qid, Dir *d)
-{
- int path;
-
- path = qid.path & ~fs->qid;
- dostat(fs, path, d);
- d->qid.path |= fs->qid;
- return 0;
-}
-
-static int
-dopen(Usbfs *fs, Fid *fid, int)
-{
- ulong path;
- Serialport *p;
-
- path = fid->qid.path & ~fs->qid;
- p = fs->aux;
- switch(path){ /* BUG: unneeded? */
- case Qdata:
- dsprint(2, "serial, opened data\n");
- break;
- case Qctl:
- dsprint(2, "serial, opened ctl\n");
- if(p->isjtag)
- return 0;
- serialctl(p, "l8 i1"); /* default line parameters */
- break;
- }
- return 0;
-}
-
-
-static void
-filldir(Usbfs *fs, Dir *d, Dirtab *tab, int i, void *v)
-{
- Serialport *p;
-
- p = v;
- d->qid.path = i | fs->qid;
- d->mode = tab->mode;
- if((d->mode & DMDIR) != 0)
- d->qid.type = QTDIR;
- else
- d->qid.type = QTFILE;
- sprint(d->name, tab->name, p->name); /* hope it fits */
-}
-
-static int
-dirgen(Usbfs *fs, Qid, int i, Dir *d, void *p)
-{
- i++; /* skip root */
- if(i >= nelem(dirtab))
- return -1;
- filldir(fs, d, &dirtab[i], i, p);
- return 0;
-}
-
-enum {
- Serbufsize = 255,
-};
-
-static long
-dread(Usbfs *fs, Fid *fid, void *data, long count, vlong offset)
-{
- int dfd;
- long rcount;
- ulong path;
- char *e, *buf, *err; /* change */
- Qid q;
- Serialport *p;
- Serial *ser;
- static int errrun, good;
-
- q = fid->qid;
- path = fid->qid.path & ~fs->qid;
- p = fs->aux;
- ser = p->s;
-
- buf = emallocz(Serbufsize, 1);
- err = emallocz(Serbufsize, 1);
- qlock(ser);
- switch(path){
- case Qroot:
- count = usbdirread(fs, q, data, count, offset, dirgen, p);
- break;
- case Qdata:
- if(count > ser->maxread)
- count = ser->maxread;
- dsprint(2, "serial: reading from data\n");
- do {
- err[0] = 0;
- dfd = p->epin->dfd;
- if(usbdebug >= 3)
- dsprint(2, "serial: reading: %ld\n", count);
-
- assert(count > 0);
- if(ser->wait4data != nil)
- rcount = ser->wait4data(p, data, count);
- else{
- qunlock(ser);
- rcount = read(dfd, data, count);
- qlock(ser);
- }
- /*
- * if we encounter a long run of continuous read
- * errors, do something drastic so that our caller
- * doesn't just spin its wheels forever.
- */
- if(rcount < 0) {
- snprint(err, Serbufsize, "%r");
- ++errrun;
- sleep(20);
- if (good > 0 && errrun > 10000) {
- /* the line has been dropped; give up */
- qunlock(ser);
- fprint(2, "%s: line %s is gone: %r\n",
- argv0, p->fs.name);
- threadexitsall("serial line gone");
- }
- } else {
- errrun = 0;
- good++;
- }
- if(usbdebug >= 3)
- dsprint(2, "serial: read: %s %ld\n", err, rcount);
- } while(rcount < 0 && strstr(err, "timed out") != nil);
-
- dsprint(2, "serial: read from bulk %ld, %10.10s\n", rcount, err);
- if(rcount < 0){
- dsprint(2, "serial: need to recover, data read %ld %r\n",
- count);
- serialrecover(ser, p, p->epin, err);
- }
- dsprint(2, "serial: read from bulk %ld\n", rcount);
- count = rcount;
- break;
- case Qctl:
- if(offset != 0)
- count = 0;
- else {
- if(!p->isjtag){
- e = serdumpst(p, buf, Serbufsize);
- count = usbreadbuf(data, count, 0, buf, e - buf);
- }
- }
- break;
- }
- if(count >= 0)
- ser->recover = 0;
- qunlock(ser);
- free(err);
- free(buf);
- return count;
-}
-
-static long
-altwrite(Serialport *p, uchar *buf, long count)
-{
- int nw, dfd;
- char err[128];
- Serial *ser;
-
- ser = p->s;
- do{
- dsprint(2, "serial: write to bulk %ld\n", count);
-
- if(ser->wait4write != nil)
- /* unlocked inside later */
- nw = ser->wait4write(p, buf, count);
- else{
- dfd = p->epout->dfd;
- qunlock(ser);
- nw = write(dfd, buf, count);
- qlock(ser);
- }
- rerrstr(err, sizeof err);
- dsprint(2, "serial: written %s %d\n", err, nw);
- } while(nw < 0 && strstr(err, "timed out") != nil);
-
- if(nw != count){
- dsprint(2, "serial: need to recover, status in write %d %r\n",
- nw);
- snprint(err, sizeof err, "%r");
- serialrecover(p->s, p, p->epout, err);
- }
- return nw;
-}
-
-static long
-dwrite(Usbfs *fs, Fid *fid, void *buf, long count, vlong)
-{
- ulong path;
- char *cmd;
- Serialport *p;
- Serial *ser;
-
- p = fs->aux;
- ser = p->s;
- path = fid->qid.path & ~fs->qid;
-
- qlock(ser);
- switch(path){
- case Qdata:
- count = altwrite(p, (uchar *)buf, count);
- break;
- case Qctl:
- if(p->isjtag)
- break;
- cmd = emallocz(count+1, 1);
- memmove(cmd, buf, count);
- cmd[count] = 0;
- if(serialctl(p, cmd) < 0){
- qunlock(ser);
- werrstr(Ebadctl);
- free(cmd);
- return -1;
- }
- free(cmd);
- break;
- default:
- qunlock(ser);
- werrstr(Eperm);
- return -1;
- }
- if(count >= 0)
- ser->recover = 0;
- else
- serialrecover(ser, p, p->epout, "writing");
- qunlock(ser);
- return count;
-}
-
-static int
-openeps(Serialport *p, int epin, int epout, int epintr)
-{
- Serial *ser;
-
- ser = p->s;
- p->epin = openep(ser->dev, epin);
- if(p->epin == nil){
- fprint(2, "serial: openep %d: %r\n", epin);
- return -1;
- }
- p->epout = openep(ser->dev, epout);
- if(p->epout == nil){
- fprint(2, "serial: openep %d: %r\n", epout);
- closedev(p->epin);
- return -1;
- }
-
- if(!p->isjtag){
- devctl(p->epin, "timeout 1000");
- devctl(p->epout, "timeout 1000");
- }
-
- if(ser->hasepintr){
- p->epintr = openep(ser->dev, epintr);
- if(p->epintr == nil){
- fprint(2, "serial: openep %d: %r\n", epintr);
- closedev(p->epin);
- closedev(p->epout);
- return -1;
- }
- opendevdata(p->epintr, OREAD);
- devctl(p->epintr, "timeout 1000");
- }
-
- if(ser->seteps!= nil)
- ser->seteps(p);
- opendevdata(p->epin, OREAD);
- opendevdata(p->epout, OWRITE);
- if(p->epin->dfd < 0 ||p->epout->dfd < 0 ||
- (ser->hasepintr && p->epintr->dfd < 0)){
- fprint(2, "serial: open i/o ep data: %r\n");
- closedev(p->epin);
- closedev(p->epout);
- if(ser->hasepintr)
- closedev(p->epintr);
- return -1;
- }
- return 0;
-}
-
-static int
-findendpoints(Serial *ser, int ifc)
-{
- int i, epin, epout, epintr;
- Ep *ep, **eps;
-
- epintr = epin = epout = -1;
-
- /*
- * interfc 0 means start from the start which is equiv to
- * iterate through endpoints probably, could be done better
- */
- eps = ser->dev->usb->conf[0]->iface[ifc]->ep;
-
- for(i = 0; i < Nep; i++){
- if((ep = eps[i]) == nil)
- continue;
- if(ser->hasepintr && ep->type == Eintr &&
- ep->dir == Ein && epintr == -1)
- epintr = ep->id;
- if(ep->type == Ebulk){
- if(ep->dir == Ein && epin == -1)
- epin = ep->id;
- if(ep->dir == Eout && epout == -1)
- epout = ep->id;
- }
- }
- dprint(2, "serial[%d]: ep ids: in %d out %d intr %d\n", ifc, epin, epout, epintr);
- if(epin == -1 || epout == -1 || (ser->hasepintr && epintr == -1))
- return -1;
-
- if(openeps(&ser->p[ifc], epin, epout, epintr) < 0)
- return -1;
-
- dprint(2, "serial: ep in %s out %s\n", ser->p[ifc].epin->dir, ser->p[ifc].epout->dir);
- if(ser->hasepintr)
- dprint(2, "serial: ep intr %s\n", ser->p[ifc].epintr->dir);
-
- if(usbdebug > 1 || serialdebug > 2){
- devctl(ser->p[ifc].epin, "debug 1");
- devctl(ser->p[ifc].epout, "debug 1");
- if(ser->hasepintr)
- devctl(ser->p[ifc].epintr, "debug 1");
- devctl(ser->dev, "debug 1");
- }
- return 0;
-}
-
-/* keep in sync with main.c */
-static int
-usage(void)
-{
- werrstr("usage: usb/serial [-dD] [-m mtpt] [-s srv]");
- return -1;
-}
-
-static void
-serdevfree(void *a)
-{
- Serial *ser = a;
- Serialport *p;
- int i;
-
- if(ser == nil)
- return;
-
- for(i = 0; i < ser->nifcs; i++){
- p = &ser->p[i];
-
- if(ser->hasepintr)
- closedev(p->epintr);
- closedev(p->epin);
- closedev(p->epout);
- p->epintr = p->epin = p->epout = nil;
- if(p->w4data != nil)
- chanfree(p->w4data);
- if(p->gotdata != nil)
- chanfree(p->gotdata);
- if(p->readc)
- chanfree(p->readc);
-
- }
- free(ser);
-}
-
-static Usbfs serialfs = {
- .walk = dwalk,
- .open = dopen,
- .read = dread,
- .write= dwrite,
- .stat = dstat,
-};
-
-static void
-serialfsend(Usbfs *fs)
-{
- Serialport *p;
-
- p = fs->aux;
-
- if(p->w4data != nil)
- chanclose(p->w4data);
- if(p->gotdata != nil)
- chanclose(p->gotdata);
- if(p->readc)
- chanclose(p->readc);
-}
-
-int
-serialmain(Dev *dev, int argc, char* argv[])
-{
- Serial *ser;
- Serialport *p;
- char buf[50];
- int i, devid;
-
- devid = dev->id;
- ARGBEGIN{
- case 'd':
- serialdebug++;
- break;
- case 'N':
- devid = atoi(EARGF(usage()));
- break;
- default:
- return usage();
- }ARGEND
- if(argc != 0)
- return usage();
-
- ser = dev->aux = emallocz(sizeof(Serial), 1);
- ser->maxrtrans = ser->maxwtrans = sizeof ser->p[0].data;
- ser->maxread = ser->maxwrite = sizeof ser->p[0].data;
- ser->dev = dev;
- dev->free = serdevfree;
- ser->jtag = -1;
- ser->nifcs = 1;
-
- snprint(buf, sizeof buf, "vid %#06x did %#06x",
- dev->usb->vid, dev->usb->did);
- if(plmatch(buf) == 0){
- ser->hasepintr = 1;
- ser->Serialops = plops;
- } else if(uconsmatch(buf) == 0)
- ser->Serialops = uconsops;
- else if(ftmatch(ser, buf) == 0)
- ser->Serialops = ftops;
- else {
- werrstr("serial: no serial devices found");
- return -1;
- }
- for(i = 0; i < ser->nifcs; i++){
- p = &ser->p[i];
- p->interfc = i;
- p->s = ser;
- p->fs = serialfs;
- if(i == ser->jtag){
- p->isjtag++;
- }
- if(findendpoints(ser, i) < 0){
- werrstr("serial: no endpoints found for ifc %d", i);
- return -1;
- }
- p->w4data = chancreate(sizeof(ulong), 0);
- p->gotdata = chancreate(sizeof(ulong), 0);
- }
-
- qlock(ser);
- serialreset(ser);
- for(i = 0; i < ser->nifcs; i++){
- p = &ser->p[i];
- dprint(2, "serial: valid interface, calling serinit\n");
- if(serinit(p) < 0){
- dprint(2, "serial: serinit: %r\n");
- return -1;
- }
-
- dsprint(2, "serial: adding interface %d, %p\n", p->interfc, p);
- if(p->isjtag){
- snprint(p->name, sizeof p->name, "jtag");
- dsprint(2, "serial: JTAG interface %d %p\n", i, p);
- snprint(p->fs.name, sizeof p->fs.name, "jtag%d.%d", devid, i);
- } else {
- snprint(p->name, sizeof p->name, "eiaU");
- if(i == 0)
- snprint(p->fs.name, sizeof p->fs.name, "eiaU%d", devid);
- else
- snprint(p->fs.name, sizeof p->fs.name, "eiaU%d.%d", devid, i);
- }
- fprint(2, "%s...", p->fs.name);
- p->fs.dev = dev;
- incref(dev);
- p->fs.aux = p;
- p->fs.end = serialfsend;
- usbfsadd(&p->fs);
- }
-
- qunlock(ser);
- return 0;
-}
diff --git a/sys/src/cmd/usb/serial/serial.h b/sys/src/cmd/usb/serial/serial.h
deleted file mode 100644
index 74e9aab2d..000000000
--- a/sys/src/cmd/usb/serial/serial.h
+++ /dev/null
@@ -1,126 +0,0 @@
-typedef struct Serial Serial;
-typedef struct Serialops Serialops;
-typedef struct Serialport Serialport;
-
-struct Serialops {
- int (*seteps)(Serialport*);
- int (*init)(Serialport*);
- int (*getparam)(Serialport*);
- int (*setparam)(Serialport*);
- int (*clearpipes)(Serialport*);
- int (*reset)(Serial*, Serialport*);
- int (*sendlines)(Serialport*);
- int (*modemctl)(Serialport*, int);
- int (*setbreak)(Serialport*, int);
- int (*readstatus)(Serialport*);
- int (*wait4data)(Serialport*, uchar *, int);
- int (*wait4write)(Serialport*, uchar *, int);
-};
-
-enum {
- DataBufSz = 8*1024,
- Maxifc = 16,
-};
-
-
-struct Serialport {
- char name[32];
- Serial *s; /* device we belong to */
- int isjtag;
-
- Dev *epintr; /* may not exist */
-
- Dev *epin;
- Dev *epout;
-
- Usbfs fs;
- uchar ctlstate;
-
- /* serial parameters */
- uint baud;
- int stop;
- int mctl;
- int parity;
- int bits;
- int fifo;
- int limit;
- int rts;
- int cts;
- int dsr;
- int dcd;
- int dtr;
- int rlsd;
-
- vlong timer;
- int blocked; /* for sw flow ctl. BUG: not implemented yet */
- int nbreakerr;
- int ring;
- int nframeerr;
- int nparityerr;
- int novererr;
- int enabled;
-
- int interfc; /* interfc on the device for ftdi */
-
- Channel *w4data;
- Channel *gotdata;
- Channel *readc; /* to uncouple reads, only used in ftdi... */
- int ndata;
- uchar data[DataBufSz];
-};
-
-struct Serial {
- QLock;
- Dev *dev; /* usb device*/
-
- int type; /* serial model subtype */
- int recover; /* # of non-fatal recovery tries */
- Serialops;
-
- int hasepintr;
-
- int jtag; /* index of jtag interface, -1 none */
- int nifcs; /* # of serial interfaces, including JTAG */
- Serialport p[Maxifc];
- int maxrtrans;
- int maxwtrans;
-
- int maxread;
- int maxwrite;
-
- int inhdrsz;
- int outhdrsz;
- int baudbase; /* for special baud base settings, see ftdi */
-};
-
-enum {
- /* soft flow control chars */
- CTLS = 023,
- CTLQ = 021,
- CtlDTR = 1,
- CtlRTS = 2,
-};
-
-/*
- * !hget http://lxr.linux.no/source/drivers/usb/serial/pl2303.h|htmlfmt
- * !hget http://lxr.linux.no/source/drivers/usb/serial/pl2303.c|htmlfmt
- */
-
-int serialmain(Dev *d, int argc, char *argv[]);
-
-typedef struct Cinfo Cinfo;
-struct Cinfo {
- int vid; /* usb vendor id */
- int did; /* usb device/product id */
- int cid; /* controller id assigned by us */
-};
-
-extern Cinfo plinfo[];
-extern Cinfo uconsinfo[];
-extern int serialdebug;
-
-#define dsprint if(serialdebug)fprint
-
-int serialrecover(Serial *ser, Serialport *p, Dev *ep, char *err);
-int serialreset(Serial *ser);
-char *serdumpst(Serialport *p, char *buf, int bufsz);
diff --git a/sys/src/cmd/usb/serial/ucons.c b/sys/src/cmd/usb/serial/ucons.c
deleted file mode 100644
index 1265467b8..000000000
--- a/sys/src/cmd/usb/serial/ucons.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-#include "usbfs.h"
-#include "serial.h"
-#include "ucons.h"
-
-Cinfo uconsinfo[] = {
- { Net20DCVid, Net20DCDid },
- { 0, 0 },
-};
-
-int
-uconsmatch(char *info)
-{
- Cinfo *ip;
- char buf[50];
-
- for(ip = uconsinfo; ip->vid != 0; ip++){
- snprint(buf, sizeof buf, "vid %#06x did %#06x",
- ip->vid, ip->did);
- dsprint(2, "serial: %s %s\n", buf, info);
- if(strstr(info, buf) != nil)
- return 0;
- }
- return -1;
-}
-
-static int
-ucseteps(Serialport *p)
-{
- Serial *ser;
-
- ser = p->s;
-
- p->baud = ~0; /* not real port */
- ser->maxrtrans = ser->maxwtrans = 8;
- devctl(p->epin, "maxpkt 8");
- devctl(p->epout, "maxpkt 8");
- return 0;
-}
-
-/* all nops */
-Serialops uconsops = {
- .seteps = ucseteps,
-};
diff --git a/sys/src/cmd/usb/serial/ucons.h b/sys/src/cmd/usb/serial/ucons.h
deleted file mode 100644
index 421526abf..000000000
--- a/sys/src/cmd/usb/serial/ucons.h
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-enum {
- Net20DCVid = 0x0525, /* Ajays usb debug cable */
- Net20DCDid = 0x127a,
-};
-
-int uconsmatch(char *info);
-extern Serialops uconsops;
diff --git a/sys/src/cmd/usb/usbd/dev.c b/sys/src/cmd/usb/usbd/dev.c
deleted file mode 100644
index 83d55ed75..000000000
--- a/sys/src/cmd/usb/usbd/dev.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Framework for USB devices.
- * Some of them may be embedded into usbd and some of
- * them may exist as /bin/usb/* binaries on their own.
- *
- * When embedded, devmain() is given a ref of an already
- * configured and open Dev. If devmain()
- * does not fail it should release this ref when done and
- * use incref to add further refs to it.
- */
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-#include "usbd.h"
-
-static Lock masklck;
-extern Devtab devtab[];
-static char* cputype;
-
-int
-getdevnb(uvlong *maskp)
-{
- int i;
-
- lock(&masklck);
- for(i = 0; i < 8 * sizeof *maskp; i++)
- if((*maskp & (1ULL<<i)) == 0){
- *maskp |= 1ULL<<i;
- unlock(&masklck);
- return i;
- }
- unlock(&masklck);
- return -1;
-}
-
-void
-putdevnb(uvlong *maskp, int id)
-{
- lock(&masklck);
- if(id >= 0)
- *maskp &= ~(1ULL<<id);
- unlock(&masklck);
-}
-
-static int
-cspmatch(Devtab *dt, int dcsp)
-{
- int i;
- int csp;
-
- for(i = 0; i < nelem(dt->csps); i++)
- if((csp=dt->csps[i]) != 0)
- if(csp == dcsp)
- return 1;
- else if((csp&DCL) && (csp&~DCL) == Class(dcsp))
- return 1;
- return 0;
-}
-
-static int
-devmatch(Devtab *dt, Usbdev *d)
-{
- int i;
- int c;
- Conf *cp;
-
- if(dt->vid != -1 && d->vid != dt->vid)
- return 0;
- if(dt->did != -1 && d->did != dt->did)
- return 0;
- if(cspmatch(dt, d->csp))
- return 1;
- for(c = 0; c < Nconf; c++)
- if((cp=d->conf[c]) != nil)
- for(i = 0; i < Niface; i++)
- if(cp->iface[i] != nil)
- if(cspmatch(dt, cp->iface[i]->csp))
- return 1;
- return 0;
-}
-
-/* We can't use procexec to execute drivers, because
- * procexec mounts #| at /mnt/temp and we do *not*
- * have /mnt/temp at boot time.
- * Instead, we use access to guess if we can execute the file.
- * and reply as procexec. Be careful that the child inherits
- * all the shared state of the thread library. It should run unnoticed.
- */
-static void
-xexec(Channel *c, char *nm, char *args[])
-{
- int pid;
-
- if(access(nm, AEXEC) == 0){
- pid = rfork(RFFDG|RFREND|RFPROC);
- switch(pid){
- case 0:
- exec(nm, args);
- _exits("exec");
- case -1:
- break;
- default:
- sendul(c, pid);
- threadexits(nil);
- }
- }
-}
-
-typedef struct Sarg Sarg;
-struct Sarg{
- Port *pp;
- Devtab* dt;
- Channel*rc;
- char fname[80];
- char args[128];
- char *argv[40];
-};
-
-static void
-startdevproc(void *a)
-{
- Sarg *sa = a;
- Dev *d;
- Devtab *dt;
- int argc;
- char *args, *argse, **argv;
- char *fname;
-
- threadsetgrp(threadid());
- d = sa->pp->dev;
- dt = sa->dt;
- args = sa->args;
- argse = sa->args + sizeof sa->args;
- argv = sa->argv;
- fname = sa->fname;
- sa->pp->devmaskp = &dt->devmask;
- sa->pp->devnb = getdevnb(&dt->devmask);
- if(sa->pp->devnb < 0){
- sa->pp->devmaskp = nil;
- sa->pp->devnb = 0;
- }else
- args = seprint(args, argse, "-N %d", sa->pp->devnb);
- if(dt->args != nil)
- seprint(args, argse, " %s", dt->args);
- args = sa->args;
- dprint(2, "%s: start: %s %s\n", argv0, dt->name, args);
- argv[0] = dt->name;
- argc = 1;
- if(args[0] != 0)
- argc += tokenize(args, argv+1, nelem(sa->argv)-2);
- argv[argc] = nil;
- if(dt->init == nil){
- if(d->dfd > 0 ){
- close(d->dfd);
- d->dfd = -1;
- }
- rfork(RFCFDG);
- open("/dev/null", OREAD);
- open("/dev/cons", OWRITE);
- open("/dev/cons", OWRITE);
-
- xexec(sa->rc, argv[0], argv);
- snprint(fname, sizeof(sa->fname), "/bin/usb/%s", dt->name);
- xexec(sa->rc, fname, argv);
- snprint(fname, sizeof(sa->fname), "/boot/%s", dt->name);
- xexec(sa->rc, fname, argv);
- if(cputype == nil)
- cputype = getenv("cputype");
- if(cputype != nil){
- snprint(fname, sizeof(sa->fname), "/%s/bin/%s",
- cputype, dt->name);
- argv[0] = fname;
- xexec(sa->rc, fname, argv);
- }
- fprint(2, "%s: %s: not found. can't exec\n", argv0, dt->name);
- sendul(sa->rc, -1);
- threadexits("exec");
- }else{
- sa->pp->dev = opendev(d->dir);
- sendul(sa->rc, 0);
- if(dt->init(d, argc, argv) < 0)
- fprint(2, "%s: %s: %r\n", argv0, dt->name);
- closedev(d);
- free(sa);
- }
- threadexits(nil);
-}
-
-static void
-writeinfo(Dev *d)
-{
- char buf[128];
- char *s;
- char *se;
- Usbdev *ud;
- Conf *c;
- Iface *ifc;
- int i, j;
-
- ud = d->usb;
- s = buf;
- se = buf+sizeof(buf);
- s = seprint(s, se, "info %s csp %#08ulx", classname(ud->class), ud->csp);
- for(i = 0; i < ud->nconf; i++){
- c = ud->conf[i];
- if(c == nil)
- break;
- for(j = 0; j < nelem(c->iface); j++){
- ifc = c->iface[j];
- if(ifc == nil)
- break;
- if(ifc->csp != ud->csp)
- s = seprint(s, se, " csp %#08ulx", ifc->csp);
- }
- }
- s = seprint(s, se, " vid %06#x did %06#x", ud->vid, ud->did);
- seprint(s, se, " %q %q", ud->vendor, ud->product);
- devctl(d, "%s", buf);
-}
-
-int
-startdev(Port *pp)
-{
- Dev *d;
- Usbdev *ud;
- Devtab *dt;
- Sarg *sa;
- Channel *rc;
-
- d = pp->dev;
- assert(d);
- ud = d->usb;
- assert(ud != nil);
-
- writeinfo(d);
-
- if(ud->class == Clhub){
- /*
- * Hubs are handled directly by this process avoiding
- * concurrent operation so that at most one device
- * has the config address in use.
- * We cancel kernel debug for these eps. too chatty.
- */
- pp->hub = newhub(d->dir, d);
- if(pp->hub == nil)
- fprint(2, "%s: %s: %r\n", argv0, d->dir);
- else
- fprint(2, "usb/hub... ");
- if(usbdebug > 1)
- devctl(d, "debug 0"); /* polled hubs are chatty */
- return pp->hub == nil ? -1 : 0;
- }
-
- for(dt = devtab; dt->name != nil; dt++)
- if(devmatch(dt, ud))
- break;
- /*
- * From here on the device is for the driver.
- * When we return pp->dev contains a Dev just for us
- * with only the ctl open. Both devs are released on the last closedev:
- * driver's upon I/O errors and ours upon port dettach.
- */
- if(dt->name == nil){
- dprint(2, "%s: no configured entry for %s (csp %#08lx)\n",
- argv0, d->dir, ud->csp);
- close(d->dfd);
- d->dfd = -1;
- return 0;
- }
- sa = emallocz(sizeof(Sarg), 1);
- sa->pp = pp;
- sa->dt = dt;
- rc = sa->rc = chancreate(sizeof(ulong), 1);
- procrfork(startdevproc, sa, Stack, RFNOTEG);
- if(recvul(rc) != 0)
- free(sa);
- chanfree(rc);
- fprint(2, "usb/%s... ", dt->name);
-
- sleep(Spawndelay); /* in case we re-spawn too fast */
- return 0;
-}
diff --git a/sys/src/cmd/usb/usbd/mkdev b/sys/src/cmd/usb/usbd/mkdev
deleted file mode 100755
index 284a396cd..000000000
--- a/sys/src/cmd/usb/usbd/mkdev
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/bin/rc
-rfork e
-
-DB=usbdb
-HDR=../lib/usb.h
-
-subs=`{ grep '^ Cl.*' $HDR |
- sed -e 's/.*Cl([a-z]+)[ ]+=[ ]+([0-9]+).*/-e s.\1,.\2,./' |
- tr A-Z a-z
-}
-cat<<EOF
-/* machine generated. do not edit */
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "usb.h"
-#include "usbd.h"
-
-EOF
-
-awk '
-/^#|^$/ { next }
-collect && /^[^ \t]/{
- collect = 0;
-}
-$0 ~ /^(embed|auto)/{
- section = $0;
- collect = 1;
- next;
-}
-collect {
- if(section ~ "embed"){
- printf("extern int %smain(Dev*, int, char**);\n", $1);
- }
-}
-' $DB
-cat <<EOF
-
-Devtab devtab[] = {
- /* device, entrypoint, {csp, csp, csp csp}, vid, did */
-EOF
-
-awk '
-/^#|^$/ { next }
-collect && /^[^ \t]/{
- collect = 0;
-}
-$0 ~ /^(embed|auto)/{
- section = $0;
- collect = 1;
- next;
-}
-collect {
- printf(" {\"%s\"", $1);
- if(section ~ "embed"){
- fns[nfns++] = $1;
- printf(",\t%smain", $1);
- } else
- printf(", nil");
- printf(",\t{");
- ncsp = 0;
- vid="-1";
- did="-1";
- args="";
- for(i = 2; i <= NF; i++)
- if($i ~ "^args="){
- sub("args=", "", $i);
- for(j = i; j <= NF; j++)
- if(j > i)
- args = args " " $j;
- else
- args = $j
- }
- for(i = 2; i <= NF; i++){
- if($i ~ "^csp="){
- ncsp++;
- sub("csp=", "", $i);
- printf("%s, ", $i);
- } else
- if($i ~ "^subclass="){
- ncsp++;
- sub("subclass=", "", $i);
- printf("DSC|%s, ", $i);
- } else
- if($i ~ "^class="){
- ncsp++;
- sub("class=", "", $i);
- printf("DCL|%s, ", $i);
- } else
- if($i ~ "^proto="){
- ncsp++;
- sub("proto=", "", $i);
- printf("DPT|%s, ", $i);
- } else
- if($i ~ "^vid="){
- sub("vid=", "", $i);
- vid=$i
- } else
- if($i ~ "did="){
- sub("did=", "", $i);
- did=$i
- }
- }
- for(i = ncsp; i < 4; i++)
- printf("0, ");
- printf("}, %s, %s, \"%s\"},\n", vid, did, args);
-}
-' $DB | sed $subs
-
-cat <<EOF
- {nil, nil, {0, 0, 0, 0, }, -1, -1, nil},
-};
-
-/* end of machine generated */
-EOF
diff --git a/sys/src/cmd/usb/usbd/mkfile b/sys/src/cmd/usb/usbd/mkfile
deleted file mode 100644
index e666994cb..000000000
--- a/sys/src/cmd/usb/usbd/mkfile
+++ /dev/null
@@ -1,39 +0,0 @@
-</$objtype/mkfile
-
-TARG=usbd
-OFILES=\
- usbd.$O\
- dev.$O\
- devtab.$O\
-
-HFILES=\
- usbd.h\
- ../lib/usb.h\
- ../lib/usbfs.h\
-
-LIBD=../lib/usbdev.a$O
-LIBU=../lib/usb.a$O
-LIB=\
- $LIBD\
- $LIBU\
-
-UPDATE=\
- $HFILES\
- ${OFILES:%.$O=%.c}\
- mkfile\
- /sys/man/3/usb\
-
-BIN=/$objtype/bin/usb
-</sys/src/cmd/mkone
-
-CFLAGS=-I../lib $CFLAGS
-CLEANFILES=devtab.c
-
-$LIBU:
- cd ../lib
- mk install
- mk clean
-
-devtab.c: usbdb ../lib/usb.h mkdev
- mkdev >$target
-
diff --git a/sys/src/cmd/usb/usbd/usbd.c b/sys/src/cmd/usb/usbd/usbd.c
deleted file mode 100644
index 75da53dc0..000000000
--- a/sys/src/cmd/usb/usbd/usbd.c
+++ /dev/null
@@ -1,875 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include <fcall.h>
-#include "usb.h"
-#include "usbfs.h"
-#include "usbd.h"
-
-static Channel *portc;
-static int win;
-static int verbose;
-
-int mainstacksize = Stack;
-static Hub *hubs;
-static int nhubs;
-static int mustdump;
-static int pollms = Pollms;
-
-static char *dsname[] = { "disabled", "attached", "configed" };
-
-static int
-hubfeature(Hub *h, int port, int f, int on)
-{
- int cmd;
-
- if(on)
- cmd = Rsetfeature;
- else
- cmd = Rclearfeature;
- return usbcmd(h->dev, Rh2d|Rclass|Rother, cmd, f, port, nil, 0);
-}
-
-/*
- * This may be used to detect overcurrent on the hub
- */
-static void
-checkhubstatus(Hub *h)
-{
- uchar buf[4];
- int sts;
-
- if(h->isroot) /* not for root hubs */
- return;
- if(usbcmd(h->dev, Rd2h|Rclass|Rdev, Rgetstatus, 0, 0, buf, 4) < 0){
- dprint(2, "%s: get hub status: %r\n", h->dev->dir);
- return;
- }
- sts = GET2(buf);
- dprint(2, "hub %s: status %#ux\n", h->dev->dir, sts);
-}
-
-static int
-confighub(Hub *h)
-{
- int type;
- uchar buf[128]; /* room for extra descriptors */
- int i;
- Usbdev *d;
- DHub *dd;
- Port *pp;
- int nr;
- int nmap;
- uchar *PortPwrCtrlMask;
- int offset;
- int mask;
-
- d = h->dev->usb;
- for(i = 0; i < nelem(d->ddesc); i++)
- if(d->ddesc[i] == nil)
- break;
- else if(d->ddesc[i]->data.bDescriptorType == Dhub){
- dd = (DHub*)&d->ddesc[i]->data;
- nr = Dhublen;
- goto Config;
- }
- type = Rd2h|Rclass|Rdev;
- nr = usbcmd(h->dev, type, Rgetdesc, Dhub<<8|0, 0, buf, sizeof buf);
- if(nr < Dhublen){
- dprint(2, "%s: %s: getdesc hub: %r\n", argv0, h->dev->dir);
- return -1;
- }
- dd = (DHub*)buf;
-Config:
- h->nport = dd->bNbrPorts;
- nmap = 1 + h->nport/8;
- if(nr < 7 + 2*nmap){
- fprint(2, "%s: %s: descr. too small\n", argv0, h->dev->dir);
- return -1;
- }
- h->port = emallocz((h->nport+1)*sizeof(Port), 1);
- h->pwrms = dd->bPwrOn2PwrGood*2;
- if(h->pwrms < Powerdelay)
- h->pwrms = Powerdelay;
- h->maxcurrent = dd->bHubContrCurrent;
- h->pwrmode = dd->wHubCharacteristics[0] & 3;
- h->compound = (dd->wHubCharacteristics[0] & (1<<2))!=0;
- h->leds = (dd->wHubCharacteristics[0] & (1<<7)) != 0;
- PortPwrCtrlMask = dd->DeviceRemovable + nmap;
- for(i = 1; i <= h->nport; i++){
- pp = &h->port[i];
- offset = i/8;
- mask = 1<<(i%8);
- pp->removable = (dd->DeviceRemovable[offset] & mask) != 0;
- pp->pwrctl = (PortPwrCtrlMask[offset] & mask) != 0;
- }
- return 0;
-}
-
-static void
-configroothub(Hub *h)
-{
- Dev *d;
- char buf[128];
- char *p;
- int nr;
-
- d = h->dev;
- h->nport = 2;
- h->maxpkt = 8;
- seek(d->cfd, 0, 0);
- nr = read(d->cfd, buf, sizeof(buf)-1);
- if(nr < 0)
- goto Done;
- buf[nr] = 0;
-
- p = strstr(buf, "ports ");
- if(p == nil)
- fprint(2, "%s: %s: no port information\n", argv0, d->dir);
- else
- h->nport = atoi(p+6);
- p = strstr(buf, "maxpkt ");
- if(p == nil)
- fprint(2, "%s: %s: no maxpkt information\n", argv0, d->dir);
- else
- h->maxpkt = atoi(p+7);
-Done:
- h->port = emallocz((h->nport+1)*sizeof(Port), 1);
- dprint(2, "%s: %s: ports %d maxpkt %d\n", argv0, d->dir, h->nport, h->maxpkt);
-}
-
-Hub*
-newhub(char *fn, Dev *d)
-{
- Hub *h;
- int i;
- Usbdev *ud;
-
- h = emallocz(sizeof(Hub), 1);
- h->isroot = (d == nil);
- if(h->isroot){
- h->dev = opendev(fn);
- if(h->dev == nil){
- fprint(2, "%s: opendev: %s: %r", argv0, fn);
- goto Fail;
- }
- if(opendevdata(h->dev, ORDWR) < 0){
- fprint(2, "%s: opendevdata: %s: %r\n", argv0, fn);
- goto Fail;
- }
- configroothub(h); /* never fails */
- }else{
- h->dev = d;
- if(confighub(h) < 0){
- fprint(2, "%s: %s: config: %r\n", argv0, fn);
- goto Fail;
- }
- }
- if(h->dev == nil){
- fprint(2, "%s: opendev: %s: %r\n", argv0, fn);
- goto Fail;
- }
- devctl(h->dev, "hub");
- ud = h->dev->usb;
- if(h->isroot)
- devctl(h->dev, "info roothub csp %#08ux ports %d",
- 0x000009, h->nport);
- else{
- devctl(h->dev, "info hub csp %#08ulx ports %d %q %q",
- ud->csp, h->nport, ud->vendor, ud->product);
- for(i = 1; i <= h->nport; i++)
- if(hubfeature(h, i, Fportpower, 1) < 0)
- fprint(2, "%s: %s: power: %r\n", argv0, fn);
- sleep(h->pwrms);
- for(i = 1; i <= h->nport; i++)
- if(h->leds != 0)
- hubfeature(h, i, Fportindicator, 1);
- }
- h->next = hubs;
- hubs = h;
- nhubs++;
- dprint(2, "%s: hub %#p allocated:", argv0, h);
- dprint(2, " ports %d pwrms %d max curr %d pwrm %d cmp %d leds %d\n",
- h->nport, h->pwrms, h->maxcurrent,
- h->pwrmode, h->compound, h->leds);
- incref(h->dev);
- return h;
-Fail:
- if(d != nil)
- devctl(d, "detach");
- free(h->port);
- free(h);
- dprint(2, "%s: hub %#p failed to start:", argv0, h);
- return nil;
-}
-
-static void portdetach(Hub *h, int p);
-
-/*
- * If during enumeration we get an I/O error the hub is gone or
- * in pretty bad shape. Because of retries of failed usb commands
- * (and the sleeps they include) it can take a while to detach all
- * ports for the hub. This detaches all ports and makes the hub void.
- * The parent hub will detect a detach (probably right now) and
- * close it later.
- */
-static void
-hubfail(Hub *h)
-{
- int i;
-
- for(i = 1; i <= h->nport; i++)
- portdetach(h, i);
- h->failed = 1;
-}
-
-static void
-closehub(Hub *h)
-{
- Hub **hl;
-
- dprint(2, "%s: closing hub %#p\n", argv0, h);
- for(hl = &hubs; *hl != nil; hl = &(*hl)->next)
- if(*hl == h)
- break;
- if(*hl == nil)
- sysfatal("closehub: no hub");
- *hl = h->next;
- nhubs--;
- hubfail(h); /* detach all ports */
- free(h->port);
- assert(h->dev != nil);
- devctl(h->dev, "detach");
- closedev(h->dev);
- free(h);
-}
-
-static int
-portstatus(Hub *h, int p)
-{
- Dev *d;
- uchar buf[4];
- int t;
- int sts;
- int dbg;
-
- dbg = usbdebug;
- if(dbg != 0 && dbg < 4)
- usbdebug = 1; /* do not be too chatty */
- d = h->dev;
- t = Rd2h|Rclass|Rother;
- if(usbcmd(d, t, Rgetstatus, 0, p, buf, sizeof(buf)) < 0)
- sts = -1;
- else
- sts = GET2(buf);
- usbdebug = dbg;
- return sts;
-}
-
-static char*
-stsstr(int sts)
-{
- static char s[80];
- char *e;
-
- e = s;
- if(sts&PSsuspend)
- *e++ = 'z';
- if(sts&PSreset)
- *e++ = 'r';
- if(sts&PSslow)
- *e++ = 'l';
- if(sts&PShigh)
- *e++ = 'h';
- if(sts&PSchange)
- *e++ = 'c';
- if(sts&PSenable)
- *e++ = 'e';
- if(sts&PSstatuschg)
- *e++ = 's';
- if(sts&PSpresent)
- *e++ = 'p';
- if(e == s)
- *e++ = '-';
- *e = 0;
- return s;
-}
-
-static int
-getmaxpkt(Dev *d, int islow)
-{
- uchar buf[64]; /* More room to try to get device-specific descriptors */
- DDev *dd;
-
- dd = (DDev*)buf;
- if(islow)
- dd->bMaxPacketSize0 = 8;
- else
- dd->bMaxPacketSize0 = 64;
- if(usbcmd(d, Rd2h|Rstd|Rdev, Rgetdesc, Ddev<<8|0, 0, buf, sizeof(buf)) < 0)
- return -1;
- return dd->bMaxPacketSize0;
-}
-
-/*
- * BUG: does not consider max. power avail.
- */
-static Dev*
-portattach(Hub *h, int p, int sts)
-{
- Dev *d;
- Port *pp;
- Dev *nd;
- char fname[80];
- char buf[40];
- char *sp;
- int mp;
- int nr;
-
- d = h->dev;
- pp = &h->port[p];
- nd = nil;
- pp->state = Pattached;
- dprint(2, "%s: %s: port %d attach sts %#ux\n", argv0, d->dir, p, sts);
- sleep(Connectdelay);
- if(hubfeature(h, p, Fportenable, 1) < 0)
- dprint(2, "%s: %s: port %d: enable: %r\n", argv0, d->dir, p);
- sleep(Enabledelay);
- if(hubfeature(h, p, Fportreset, 1) < 0){
- dprint(2, "%s: %s: port %d: reset: %r\n", argv0, d->dir, p);
- goto Fail;
- }
- sleep(Resetdelay);
- sts = portstatus(h, p);
- if(sts < 0)
- goto Fail;
- if((sts & PSenable) == 0){
- dprint(2, "%s: %s: port %d: not enabled?\n", argv0, d->dir, p);
- hubfeature(h, p, Fportenable, 1);
- sts = portstatus(h, p);
- if((sts & PSenable) == 0)
- goto Fail;
- }
- sp = "full";
- if(sts & PSslow)
- sp = "low";
- if(sts & PShigh)
- sp = "high";
- dprint(2, "%s: %s: port %d: attached status %#ux\n", argv0, d->dir, p, sts);
-
- if(devctl(d, "newdev %s %d", sp, p) < 0){
- fprint(2, "%s: %s: port %d: newdev: %r\n", argv0, d->dir, p);
- goto Fail;
- }
- seek(d->cfd, 0, 0);
- nr = read(d->cfd, buf, sizeof(buf)-1);
- if(nr == 0){
- fprint(2, "%s: %s: port %d: newdev: eof\n", argv0, d->dir, p);
- goto Fail;
- }
- if(nr < 0){
- fprint(2, "%s: %s: port %d: newdev: %r\n", argv0, d->dir, p);
- goto Fail;
- }
- buf[nr] = 0;
- snprint(fname, sizeof(fname), "/dev/usb/%s", buf);
- nd = opendev(fname);
- if(nd == nil){
- fprint(2, "%s: %s: port %d: opendev: %r\n", argv0, d->dir, p);
- goto Fail;
- }
- if(usbdebug > 2)
- devctl(nd, "debug 1");
- if(opendevdata(nd, ORDWR) < 0){
- fprint(2, "%s: %s: opendevdata: %r\n", argv0, nd->dir);
- goto Fail;
- }
- if(usbcmd(nd, Rh2d|Rstd|Rdev, Rsetaddress, nd->id, 0, nil, 0) < 0){
- dprint(2, "%s: %s: port %d: setaddress: %r\n", argv0, d->dir, p);
- goto Fail;
- }
- if(devctl(nd, "address") < 0){
- dprint(2, "%s: %s: port %d: set address: %r\n", argv0, d->dir, p);
- goto Fail;
- }
-
- mp=getmaxpkt(nd, strcmp(sp, "low") == 0);
- if(mp < 0){
- dprint(2, "%s: %s: port %d: getmaxpkt: %r\n", argv0, d->dir, p);
- goto Fail;
- }else{
- dprint(2, "%s; %s: port %d: maxpkt %d\n", argv0, d->dir, p, mp);
- devctl(nd, "maxpkt %d", mp);
- }
- if((sts & PSslow) != 0 && strcmp(sp, "full") == 0)
- dprint(2, "%s: %s: port %d: %s is full speed when port is low\n",
- argv0, d->dir, p, nd->dir);
- if(configdev(nd) < 0){
- dprint(2, "%s: %s: port %d: configdev: %r\n", argv0, d->dir, p);
- goto Fail;
- }
- /*
- * We always set conf #1. BUG.
- */
- if(usbcmd(nd, Rh2d|Rstd|Rdev, Rsetconf, 1, 0, nil, 0) < 0){
- dprint(2, "%s: %s: port %d: setconf: %r\n", argv0, d->dir, p);
- unstall(nd, nd, Eout);
- if(usbcmd(nd, Rh2d|Rstd|Rdev, Rsetconf, 1, 0, nil, 0) < 0)
- goto Fail;
- }
- dprint(2, "%s: %U", argv0, nd);
- pp->state = Pconfiged;
- dprint(2, "%s: %s: port %d: configed: %s\n",
- argv0, d->dir, p, nd->dir);
- return pp->dev = nd;
-Fail:
- pp->state = Pdisabled;
- pp->sts = 0;
- if(pp->hub != nil)
- pp->hub = nil; /* hub closed by enumhub */
- hubfeature(h, p, Fportenable, 0);
- if(nd != nil)
- devctl(nd, "detach");
- closedev(nd);
- return nil;
-}
-
-static void
-portdetach(Hub *h, int p)
-{
- Dev *d;
- Port *pp;
- extern void usbfsgone(char*);
- d = h->dev;
- pp = &h->port[p];
-
- /*
- * Clear present, so that we detect an attach on reconnects.
- */
- pp->sts &= ~(PSpresent|PSenable);
-
- if(pp->state == Pdisabled)
- return;
- pp->state = Pdisabled;
- dprint(2, "%s: %s: port %d: detached\n", argv0, d->dir, p);
-
- if(pp->hub != nil){
- closehub(pp->hub);
- pp->hub = nil;
- }
- if(pp->devmaskp != nil)
- putdevnb(pp->devmaskp, pp->devnb);
- pp->devmaskp = nil;
- if(pp->dev != nil){
- devctl(pp->dev, "detach");
- usbfsgone(pp->dev->dir);
- closedev(pp->dev);
- pp->dev = nil;
- }
-}
-
-/*
- * The next two functions are included to
- * perform a port reset asked for by someone (usually a driver).
- * This must be done while no other device is in using the
- * configuration address and with care to keep the old address.
- * To keep drivers decoupled from usbd they write the reset request
- * to the #u/usb/epN.0/ctl file and then exit.
- * This is unfortunate because usbd must now poll twice as much.
- *
- * An alternative to this reset process would be for the driver to detach
- * the device. The next function could see that, issue a port reset, and
- * then restart the driver once to see if it's a temporary error.
- *
- * The real fix would be to use interrupt endpoints for non-root hubs
- * (would probably make some hubs fail) and add an events file to
- * the kernel to report events to usbd. This is a severe change not
- * yet implemented.
- */
-static int
-portresetwanted(Hub *h, int p)
-{
- char buf[5];
- Port *pp;
- Dev *nd;
-
- pp = &h->port[p];
- nd = pp->dev;
- if(nd != nil && nd->cfd >= 0 && pread(nd->cfd, buf, 5, 0LL) == 5)
- return strncmp(buf, "reset", 5) == 0;
- else
- return 0;
-}
-
-static void
-portreset(Hub *h, int p)
-{
- int sts;
- Dev *d, *nd;
- Port *pp;
-
- d = h->dev;
- pp = &h->port[p];
- nd = pp->dev;
- dprint(2, "%s: %s: port %d: resetting\n", argv0, d->dir, p);
- if(hubfeature(h, p, Fportreset, 1) < 0){
- dprint(2, "%s: %s: port %d: reset: %r\n", argv0, d->dir, p);
- goto Fail;
- }
- sleep(Resetdelay);
- sts = portstatus(h, p);
- if(sts < 0)
- goto Fail;
- if((sts & PSenable) == 0){
- dprint(2, "%s: %s: port %d: not enabled?\n", argv0, d->dir, p);
- hubfeature(h, p, Fportenable, 1);
- sts = portstatus(h, p);
- if((sts & PSenable) == 0)
- goto Fail;
- }
- nd = pp->dev;
- opendevdata(nd, ORDWR);
- if(usbcmd(nd, Rh2d|Rstd|Rdev, Rsetaddress, nd->id, 0, nil, 0) < 0){
- dprint(2, "%s: %s: port %d: setaddress: %r\n", argv0, d->dir, p);
- goto Fail;
- }
- if(devctl(nd, "address") < 0){
- dprint(2, "%s: %s: port %d: set address: %r\n", argv0, d->dir, p);
- goto Fail;
- }
- if(usbcmd(nd, Rh2d|Rstd|Rdev, Rsetconf, 1, 0, nil, 0) < 0){
- dprint(2, "%s: %s: port %d: setconf: %r\n", argv0, d->dir, p);
- unstall(nd, nd, Eout);
- if(usbcmd(nd, Rh2d|Rstd|Rdev, Rsetconf, 1, 0, nil, 0) < 0)
- goto Fail;
- }
- if(nd->dfd >= 0)
- close(nd->dfd);
- return;
-Fail:
- pp->state = Pdisabled;
- pp->sts = 0;
- if(pp->hub != nil)
- pp->hub = nil; /* hub closed by enumhub */
- hubfeature(h, p, Fportenable, 0);
- if(nd != nil)
- devctl(nd, "detach");
- closedev(nd);
-}
-
-static int
-portgone(Port *pp, int sts)
-{
- if(sts < 0)
- return 1;
- /*
- * If it was enabled and it's not now then it may be reconnect.
- * We pretend it's gone and later we'll see it as attached.
- */
- if((pp->sts & PSenable) != 0 && (sts & PSenable) == 0)
- return 1;
- return (pp->sts & PSpresent) != 0 && (sts & PSpresent) == 0;
-}
-
-static int
-enumhub(Hub *h, int p)
-{
- int sts;
- Dev *d;
- Port *pp;
- int onhubs;
-
- if(h->failed)
- return 0;
- d = h->dev;
- if(usbdebug > 3)
- fprint(2, "%s: %s: port %d enumhub\n", argv0, d->dir, p);
-
- sts = portstatus(h, p);
- if(sts < 0){
- hubfail(h); /* avoid delays on detachment */
- return -1;
- }
- pp = &h->port[p];
- onhubs = nhubs;
- if((sts & PSsuspend) != 0){
- if(hubfeature(h, p, Fportenable, 1) < 0)
- dprint(2, "%s: %s: port %d: enable: %r\n", argv0, d->dir, p);
- sleep(Enabledelay);
- sts = portstatus(h, p);
- fprint(2, "%s: %s: port %d: resumed (sts %#ux)\n", argv0, d->dir, p, sts);
- }
- if((pp->sts & PSpresent) == 0 && (sts & PSpresent) != 0){
- if(portattach(h, p, sts) != nil)
- if(startdev(pp) < 0)
- portdetach(h, p);
- }else if(portgone(pp, sts))
- portdetach(h, p);
- else if(portresetwanted(h, p))
- portreset(h, p);
- else if(pp->sts != sts){
- dprint(2, "%s: %s port %d: sts %s %#x ->",
- argv0, d->dir, p, stsstr(pp->sts), pp->sts);
- dprint(2, " %s %#x\n",stsstr(sts), sts);
- }
- pp->sts = sts;
- if(onhubs != nhubs)
- return -1;
- return 0;
-}
-
-static void
-dump(void)
-{
- Hub *h;
- int i;
-
- mustdump = 0;
- for(h = hubs; h != nil; h = h->next)
- for(i = 1; i <= h->nport; i++)
- fprint(2, "%s: hub %#p %s port %d: %U",
- argv0, h, h->dev->dir, i, h->port[i].dev);
- usbfsdirdump();
-
-}
-
-static void
-work(void *a)
-{
- Channel *portc;
- char *fn;
- Hub *h;
- int i;
-
- portc = a;
- hubs = nil;
- /*
- * Receive requests for root hubs
- */
- while((fn = recvp(portc)) != nil){
- dprint(2, "%s: %s starting\n", argv0, fn);
- h = newhub(fn, nil);
- if(h == nil)
- fprint(2, "%s: %s: newhub failed: %r\n", argv0, fn);
- free(fn);
- }
- /*
- * Enumerate (and acknowledge after first enumeration).
- * Do NOT perform enumeration concurrently for the same
- * controller. new devices attached respond to a default
- * address (0) after reset, thus enumeration has to work
- * one device at a time at least before addresses have been
- * assigned.
- * Do not use hub interrupt endpoint because we
- * have to poll the root hub(s) in any case.
- */
- for(;;){
-Again:
- for(h = hubs; h != nil; h = h->next)
- for(i = 1; i <= h->nport; i++)
- if(enumhub(h, i) < 0){
- /* changes in hub list; repeat */
- goto Again;
- }
- if(portc != nil){
- sendp(portc, nil);
- portc = nil;
- }
- sleep(pollms);
- if(mustdump)
- dump();
- }
-}
-
-static int
-cfswalk(Usbfs*, Fid *, char *)
-{
- werrstr(Enotfound);
- return -1;
-}
-
-static int
-cfsopen(Usbfs*, Fid *, int)
-{
- return 0;
-}
-
-static long
-cfsread(Usbfs*, Fid *, void *, long , vlong )
-{
- return 0;
-}
-
-static void
-setdrvargs(char *name, char *args)
-{
- Devtab *dt;
- extern Devtab devtab[];
-
- for(dt = devtab; dt->name != nil; dt++)
- if(strstr(dt->name, name) != nil)
- dt->args = estrdup(args);
-}
-
-static long
-cfswrite(Usbfs*, Fid *, void *data, long cnt, vlong )
-{
- char buf[80];
- char *toks[4];
-
- if(cnt > sizeof(buf))
- cnt = sizeof(buf) - 1;
- strncpy(buf, data, cnt);
- buf[cnt] = 0;
- if(cnt > 0 && buf[cnt-1] == '\n')
- buf[cnt-1] = 0;
- if(strncmp(buf, "dump", 4) == 0){
- mustdump = 1;
- return cnt;
- }
- if(strncmp(buf, "reset", 5) == 0){
- werrstr("reset not implemented");
- return -1;
- }
- if(tokenize(buf, toks, nelem(toks)) != 2){
- werrstr("usage: debug|fsdebug n");
- return -1;
- }
- if(strcmp(toks[0], "debug") == 0)
- usbdebug = atoi(toks[1]);
- else if(strcmp(toks[0], "fsdebug") == 0)
- usbfsdebug = atoi(toks[1]);
- else if(strcmp(toks[0], "kbargs") == 0)
- setdrvargs("kb", toks[1]);
- else if(strcmp(toks[0], "diskargs") == 0)
- setdrvargs("disk", toks[1]);
- else{
- werrstr("unkown ctl '%s'", buf);
- return -1;
- }
- fprint(2, "%s: debug %d fsdebug %d\n", argv0, usbdebug, usbfsdebug);
- return cnt;
-}
-
-static int
-cfsstat(Usbfs* fs, Qid qid, Dir *d)
-{
- d->qid = qid;
- d->qid.path |= fs->qid;
- d->qid.type = 0;
- d->qid.vers = 0;
- d->name = "usbdctl";
- d->length = 0;
- d->mode = 0664;
- return 0;
-}
-
-static Usbfs ctlfs =
-{
- .walk = cfswalk,
- .open = cfsopen,
- .read = cfsread,
- .write = cfswrite,
- .stat = cfsstat
-};
-
-static void
-args(void)
-{
- char *s;
-
- s = getenv("usbdebug");
- if(s != nil)
- usbdebug = atoi(s);
- free(s);
- s = getenv("usbfsdebug");
- if(s != nil)
- usbfsdebug = atoi(s);
- free(s);
- s = getenv("kbargs");
- if(s != nil)
- setdrvargs("kb", s);
- free(s);
- s = getenv("diskargs");
- if(s != nil)
- setdrvargs("disk", s);
- free(s);
-}
-
-static void
-usage(void)
-{
- fprint(2, "usage: %s [-Dd] [-s srv] [-m mnt] [dev...]\n", argv0);
- threadexitsall("usage");
-}
-
-extern void usbfsexits(int);
-
-void
-threadmain(int argc, char **argv)
-{
- int i;
- Dir *d;
- int fd;
- int nd;
- char *err;
- char *srv;
- char *mnt;
-
- srv = "usb";
- mnt = "/dev";
- ARGBEGIN{
- case 'D':
- usbfsdebug++;
- break;
- case 'd':
- usbdebug++;
- break;
- case 's':
- srv = EARGF(usage());
- break;
- case 'i':
- pollms = atoi(EARGF(usage()));
- break;
- case 'm':
- mnt = EARGF(usage());
- break;
- default:
- usage();
- }ARGEND;
- if(access("/dev/usb", AEXIST) < 0 && bind("#u", "/dev", MBEFORE) < 0)
- sysfatal("#u: %r");
-
- args();
-
- fmtinstall('U', Ufmt);
- quotefmtinstall();
- rfork(RFNOTEG);
- portc = chancreate(sizeof(char *), 0);
- if(portc == nil)
- sysfatal("chancreate");
- proccreate(work, portc, Stack);
- if(argc == 0){
- fd = open("/dev/usb", OREAD);
- if(fd < 0)
- sysfatal("/dev/usb: %r");
- nd = dirreadall(fd, &d);
- close(fd);
- if(nd < 2)
- sysfatal("/dev/usb: no hubs");
- for(i = 0; i < nd; i++)
- if(strcmp(d[i].name, "ctl") != 0)
- sendp(portc, smprint("/dev/usb/%s", d[i].name));
- free(d);
- }else
- for(i = 0; i < argc; i++)
- sendp(portc, strdup(argv[i]));
- sendp(portc, nil);
- err = recvp(portc);
- chanfree(portc);
- usbfsexits(0);
- usbfsinit(srv, mnt, &usbdirfs, MAFTER);
- snprint(ctlfs.name, sizeof(ctlfs.name), "usbdctl");
- usbfsadd(&ctlfs);
- threadexits(err);
-}
diff --git a/sys/src/cmd/usb/usbd/usbd.h b/sys/src/cmd/usb/usbd/usbd.h
deleted file mode 100644
index fc8449197..000000000
--- a/sys/src/cmd/usb/usbd/usbd.h
+++ /dev/null
@@ -1,134 +0,0 @@
-typedef struct Hub Hub;
-typedef struct Port Port;
-typedef struct DHub DHub;
-typedef struct Devtab Devtab;
-typedef struct Usbfs Usbfs;
-
-enum
-{
- Stack = 32*1024,
-
- Dhub = 0x29, /* hub descriptor type */
- Dhublen = 9, /* hub descriptor length */
-
- /* hub class feature selectors */
- Fhublocalpower = 0,
- Fhubovercurrent = 1,
-
- Fportconnection = 0,
- Fportenable = 1,
- Fportsuspend = 2,
- Fportovercurrent = 3,
- Fportreset = 4,
- Fportpower = 8,
- Fportlowspeed = 9,
- Fcportconnection = 16,
- Fcportenable = 17,
- Fcportsuspend = 18,
- Fcportovercurrent= 19,
- Fcportreset = 20,
- Fportindicator = 22,
-
- /* Port status and status change bits
- * Constants at /sys/src/9/pc/usb.h starting with HP-
- * must have the same values or root hubs won't work.
- */
- PSpresent = 0x0001,
- PSenable = 0x0002,
- PSsuspend = 0x0004,
- PSovercurrent = 0x0008,
- PSreset = 0x0010,
- PSpower = 0x0100,
- PSslow = 0x0200,
- PShigh = 0x0400,
-
- PSstatuschg = 0x10000, /* PSpresent changed */
- PSchange = 0x20000, /* PSenable changed */
-
-
- /* port/device state */
- Pdisabled = 0, /* must be 0 */
- Pattached,
- Pconfiged,
-
- /* Delays, timeouts (ms) */
-// Spawndelay = 1000, /* how often may we re-spawn a driver */
- Spawndelay = 250, /* how often may we re-spawn a driver */
-// Connectdelay = 1000, /* how much to wait after a connect */
- Connectdelay = 500, /* how much to wait after a connect */
- Resetdelay = 20, /* how much to wait after a reset */
- Enabledelay = 20, /* how much to wait after an enable */
- Powerdelay = 100, /* after powering up ports */
- Pollms = 250, /* port poll interval */
- Chgdelay = 100, /* waiting for port become stable */
- Chgtmout = 1000, /* ...but at most this much */
-
- /*
- * device tab for embedded usb drivers.
- */
- DCL = 0x01000000, /* csp identifies just class */
- DSC = 0x02000000, /* csp identifies just subclass */
- DPT = 0x04000000, /* csp identifies just proto */
-
-};
-
-struct Hub
-{
- uchar pwrmode;
- uchar compound;
- uchar pwrms; /* time to wait in ms */
- uchar maxcurrent; /* after powering port*/
- int leds; /* has port indicators? */
- int maxpkt;
- uchar nport;
- Port *port;
- int failed; /* I/O error while enumerating */
- int isroot; /* set if root hub */
- Dev *dev; /* for this hub */
- Hub *next; /* in list of hubs */
-};
-
-struct Port
-{
- int state; /* state of the device */
- int sts; /* old port status */
- uchar removable;
- uchar pwrctl;
- Dev *dev; /* attached device (if non-nil) */
- Hub *hub; /* non-nil if hub attached */
- int devnb; /* device number */
- uvlong *devmaskp; /* ptr to dev mask */
-};
-
-
-/* USB HUB descriptor */
-struct DHub
-{
- uchar bLength;
- uchar bDescriptorType;
- uchar bNbrPorts;
- uchar wHubCharacteristics[2];
- uchar bPwrOn2PwrGood;
- uchar bHubContrCurrent;
- uchar DeviceRemovable[1]; /* variable length */
-};
-
-struct Devtab
-{
- char *name;
- int (*init)(Dev*, int, char**); /* nil if external */
- int csps[4];
- int vid;
- int did;
- char *args;
- uvlong devmask;
-};
-
-
-Hub* newhub(char *fn, Dev *d);
-int startdev(Port *pp);
-int getdevnb(uvlong *maskp);
-void putdevnb(uvlong *maskp, int nb);
-void threadmain(int argc, char **argv);
-
-extern Usbfs usbdfsops;
diff --git a/sys/src/cmd/usb/usbd/usbdb b/sys/src/cmd/usb/usbd/usbdb
deleted file mode 100644
index 0177487ae..000000000
--- a/sys/src/cmd/usb/usbd/usbdb
+++ /dev/null
@@ -1,11 +0,0 @@
-# only kb, disk, and ether are prepared for embedding.
-# others are not yet converted to sit in the usbd device driver library.
-embed
- kb csp=0x010103 csp=0x020103 args=
- disk class=storage args=
- ether class=255 csp=0x00ffff vid=0x0b95 args=
- serial class=255 csp=0xffffff vid=0x9e88 did=0x9e8f args=
- serial class=255 csp=0xffffff vid=0x0403 args=
-# wifi class=0 csp=0 vid=0x0bda did=0x8192 args=
-# wifi class=0 csp=0 vid=0x148f did=0x2870 args=
-auto