123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- 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 = 16, /* 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 = 16, /* 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
- {
- uint32_t 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
- {
- uint8_t addr; /* endpt address, 0-15 (|0x80 if Ein) */
- uint8_t dir; /* direction, Ein/Eout */
- uint8_t type; /* Econtrol, Eiso, Ebulk, Eintr */
- uint8_t 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 */
- uint32_t 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
- {
- uint8_t bLength;
- uint8_t bDescriptorType;
- uint8_t 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
- {
- uint8_t bLength;
- uint8_t bDescriptorType;
- uint8_t bcdUSB[2];
- uint8_t bDevClass;
- uint8_t bDevSubClass;
- uint8_t bDevProtocol;
- uint8_t bMaxPacketSize0;
- uint8_t idVendor[2];
- uint8_t idProduct[2];
- uint8_t bcdDev[2];
- uint8_t iManufacturer;
- uint8_t iProduct;
- uint8_t iSerialNumber;
- uint8_t bNumConfigurations;
- };
- struct DConf
- {
- uint8_t bLength;
- uint8_t bDescriptorType;
- uint8_t wTotalLength[2];
- uint8_t bNumInterfaces;
- uint8_t bConfigurationValue;
- uint8_t iConfiguration;
- uint8_t bmAttributes;
- uint8_t MaxPower;
- };
- struct DIface
- {
- uint8_t bLength;
- uint8_t bDescriptorType;
- uint8_t bInterfaceNumber;
- uint8_t bAlternateSetting;
- uint8_t bNumEndpoints;
- uint8_t bInterfaceClass;
- uint8_t bInterfaceSubClass;
- uint8_t bInterfaceProtocol;
- uint8_t iInterface;
- };
- struct DEp
- {
- uint8_t bLength;
- uint8_t bDescriptorType;
- uint8_t bEndpointAddress;
- uint8_t bmAttributes;
- uint8_t wMaxPacketSize[2];
- uint8_t 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))
- /* These were macros. Let's start making them type safe with inline includes.
- * The use of macros is a puzzle given the Ken C toolchain's inlining at link time
- * abilities, but ...
- */
- static inline void PUT4(uint8_t *p, uint32_t 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
- int Ufmt(Fmt *f);
- char* classname(int c);
- void closedev(Dev *d);
- int configdev(Dev *d);
- int devctl(Dev *dev, char *fmt, ...);
- void* emallocz(uint32_t 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, uint8_t *b, int n);
- int parsedesc(Usbdev *d, Conf *c, uint8_t *b, int n);
- int parsedev(Dev *xd, uint8_t *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, uint8_t *data, int count);
- extern int usbdebug; /* more messages for bigger values */
|