123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- /*
- * common USB definitions.
- */
- typedef struct Udev Udev; /* USB device */
- typedef struct Ep Ep; /* Endpoint */
- typedef struct Hci Hci; /* Host Controller Interface */
- typedef struct Hciimpl Hciimpl; /* Link to the controller impl. */
- enum
- {
- /* fundamental constants */
- Ndeveps = 16, /* max nb. of endpoints per device */
- /* tunable parameters */
- Nhcis = 16, /* max nb. of HCIs */
- Neps = 64, /* max nb. of endpoints */
- Maxctllen = 32*1024, /* max allowed sized for ctl. xfers; see Maxdevconf */
- Xfertmout = 2000, /* default request time out (ms) */
- /* transfer types. keep this order */
- Tnone = 0, /* no tranfer type configured */
- Tctl, /* wr req + rd/wr data + wr/rd sts */
- Tiso, /* stream rd or wr (real time) */
- Tbulk, /* stream rd or wr */
- Tintr, /* msg rd or wr */
- Nttypes, /* number of transfer types */
- Epmax = 0xF, /* max ep. addr */
- Devmax = 0x7F, /* max dev. addr */
- /* Speeds */
- Fullspeed = 0,
- Lowspeed,
- Highspeed,
- Nospeed,
- /* request type */
- Rh2d = 0<<7,
- Rd2h = 1<<7,
- Rstd = 0<<5,
- Rclass = 1<<5,
- Rdev = 0,
- Rep = 2,
- Rother = 3,
- /* req offsets */
- Rtype = 0,
- Rreq = 1,
- Rvalue = 2,
- Rindex = 4,
- Rcount = 6,
- Rsetuplen = 8,
- /* standard requests */
- Rgetstatus = 0,
- Rclearfeature = 1,
- Rsetfeature = 3,
- Rsetaddr = 5,
- Rgetdesc = 6,
- /* device states */
- Dconfig = 0, /* configuration in progress */
- Denabled, /* address assigned */
- Ddetach, /* device is detached */
- Dreset, /* its port is being reset */
- /* (root) Hub reply to port status (reported to usbd) */
- HPpresent = 0x1,
- HPenable = 0x2,
- HPsuspend = 0x4,
- HPovercurrent = 0x8,
- HPreset = 0x10,
- HPpower = 0x100,
- HPslow = 0x200,
- HPhigh = 0x400,
- HPstatuschg = 0x10000,
- HPchange = 0x20000,
- };
- /*
- * Services provided by the driver.
- * epopen allocates hardware structures to prepare the endpoint
- * for I/O. This happens when the user opens the data file.
- * epclose releases them. This happens when the data file is closed.
- * epwrite tries to write the given bytes, waiting until all of them
- * have been written (or failed) before returning; but not for Iso.
- * epread does the same for reading.
- * It can be assumed that endpoints are DMEXCL but concurrent
- * read/writes may be issued and the controller must take care.
- * For control endpoints, device-to-host requests must be followed by
- * a read of the expected length if needed.
- * The port requests are called when usbd issues commands for root
- * hubs. Port status must return bits as a hub request would do.
- * Toggle handling and other details are left for the controller driver
- * to avoid mixing too much the controller and the comon device.
- * While an endpoint is closed, its toggles are saved in the Ep struct.
- */
- struct Hciimpl
- {
- void *aux; /* for controller info */
- void (*init)(Hci*); /* init. controller */
- void (*dump)(Hci*); /* debug */
- void (*interrupt)(Ureg*, void*); /* service interrupt */
- void (*epopen)(Ep*); /* prepare ep. for I/O */
- void (*epclose)(Ep*); /* terminate I/O on ep. */
- long (*epread)(Ep*,void*,long); /* transmit data for ep */
- long (*epwrite)(Ep*,void*,long); /* receive data for ep */
- char* (*seprintep)(char*,char*,Ep*); /* debug */
- int (*portenable)(Hci*, int, int); /* enable/disable port */
- int (*portreset)(Hci*, int, int); /* set/clear port reset */
- int (*portstatus)(Hci*, int); /* get port status */
- void (*shutdown)(Hci*); /* shutdown for reboot */
- void (*debug)(Hci*, int); /* set/clear debug flag */
- };
- struct Hci
- {
- ISAConf; /* hardware info */
- int tbdf; /* type+busno+devno+funcno */
- int ctlrno; /* controller number */
- int nports; /* number of ports in hub */
- int highspeed;
- Hciimpl; /* HCI driver */
- };
- /*
- * USB endpoint.
- * All endpoints are kept in a global array. The first
- * block of fields is constant after endpoint creation.
- * The rest is configuration information given to all controllers.
- * The first endpoint for a device (known as ep0) represents the
- * device and is used to configure it and create other endpoints.
- * Its QLock also protects per-device data in dev.
- * See Hciimpl for clues regarding how this is used by controllers.
- */
- struct Ep
- {
- Ref; /* one per fid (and per dev ep for ep0s) */
- /* const once inited. */
- int idx; /* index in global eps array */
- int nb; /* endpoint number in device */
- Hci* hp; /* HCI it belongs to */
- Udev* dev; /* device for the endpoint */
- Ep* ep0; /* control endpoint for its device */
- QLock; /* protect fields below */
- char* name; /* for ep file names at #u/ */
- int inuse; /* endpoint is open */
- int mode; /* OREAD, OWRITE, or ORDWR */
- int clrhalt; /* true if halt was cleared on ep. */
- int debug; /* per endpoint debug flag */
- char* info; /* for humans to read */
- long maxpkt; /* maximum packet size */
- int ttype; /* tranfer type */
- ulong load; /* in µs, for a fransfer of maxpkt bytes */
- void* aux; /* for controller specific info */
- int rhrepl; /* fake root hub replies */
- int toggle[2]; /* saved toggles (while ep is not in use) */
- long pollival; /* poll interval ([µ]frames; intr/iso) */
- long hz; /* poll frequency (iso) */
- long samplesz; /* sample size (iso) */
- int ntds; /* nb. of Tds per µframe */
- int tmout; /* 0 or timeout for transfers (ms) */
- };
- /*
- * Per-device configuration and cached list of endpoints.
- * eps[0]->QLock protects it.
- */
- struct Udev
- {
- int nb; /* USB device number */
- int state; /* state for the device */
- int ishub; /* hubs can allocate devices */
- int isroot; /* is a root hub */
- int speed; /* Full/Low/High/No -speed */
- int hub; /* dev number for the parent hub */
- int port; /* port number in the parent hub */
- Ep* eps[Ndeveps]; /* end points for this device (cached) */
- };
- void addhcitype(char *type, int (*reset)(Hci*));
- #define dprint if(debug)print
- #define ddprint if(debug>1)print
- #define deprint if(debug || ep->debug)print
- #define ddeprint if(debug>1 || ep->debug>1)print
- #define GET2(p) ((((p)[1]&0xFF)<<8)|((p)[0]&0xFF))
- #define PUT2(p,v) {((p)[0] = (v)); ((p)[1] = (v)>>8);}
- extern char *usbmodename[];
- extern char Estalled[];
- extern char *seprintdata(char*,char*,uchar*,int);
|