2 |
- |
1 |
/*
|
|
|
2 |
* common USB definitions.
|
|
|
3 |
*/
|
|
|
4 |
#define dprint if(debug)print
|
|
|
5 |
#define ddprint if(debug>1)print
|
|
|
6 |
#define deprint if(debug || ep->debug)print
|
|
|
7 |
#define ddeprint if(debug>1 || ep->debug>1)print
|
|
|
8 |
|
|
|
9 |
#define GET2(p) ((((p)[1]&0xFF)<<8)|((p)[0]&0xFF))
|
|
|
10 |
#define PUT2(p,v) {((p)[0] = (v)); ((p)[1] = (v)>>8);}
|
|
|
11 |
|
|
|
12 |
typedef struct Udev Udev; /* USB device */
|
|
|
13 |
typedef struct Ep Ep; /* Endpoint */
|
|
|
14 |
typedef struct Hci Hci; /* Host Controller Interface */
|
|
|
15 |
typedef struct Hciimpl Hciimpl; /* Link to the controller impl. */
|
|
|
16 |
|
|
|
17 |
enum
|
|
|
18 |
{
|
|
|
19 |
/* fundamental constants */
|
|
|
20 |
Ndeveps = 16, /* max nb. of endpoints per device */
|
|
|
21 |
|
|
|
22 |
/* tunable parameters */
|
|
|
23 |
Nhcis = 16, /* max nb. of HCIs */
|
|
|
24 |
Neps = 128, /* max nb. of endpoints */
|
|
|
25 |
Maxctllen = 32*1024, /* max allowed sized for ctl. xfers; see Maxdevconf */
|
|
|
26 |
Xfertmout = 2000, /* default request time out (ms) */
|
|
|
27 |
|
|
|
28 |
/* transfer types. keep this order */
|
|
|
29 |
Tnone = 0, /* no tranfer type configured */
|
|
|
30 |
Tctl, /* wr req + rd/wr data + wr/rd sts */
|
|
|
31 |
Tiso, /* stream rd or wr (real time) */
|
|
|
32 |
Tbulk, /* stream rd or wr */
|
|
|
33 |
Tintr, /* msg rd or wr */
|
|
|
34 |
Nttypes, /* number of transfer types */
|
|
|
35 |
|
|
|
36 |
Epmax = 0xF, /* max ep. addr */
|
|
|
37 |
Devmax = 0x7F, /* max dev. addr */
|
|
|
38 |
|
|
|
39 |
/* Speeds */
|
|
|
40 |
Fullspeed = 0,
|
|
|
41 |
Lowspeed,
|
|
|
42 |
Highspeed,
|
|
|
43 |
Nospeed,
|
|
|
44 |
|
|
|
45 |
/* request type */
|
|
|
46 |
Rh2d = 0<<7,
|
|
|
47 |
Rd2h = 1<<7,
|
|
|
48 |
Rstd = 0<<5,
|
|
|
49 |
Rclass = 1<<5,
|
|
|
50 |
Rdev = 0,
|
|
|
51 |
Rep = 2,
|
|
|
52 |
Rother = 3,
|
|
|
53 |
|
|
|
54 |
/* req offsets */
|
|
|
55 |
Rtype = 0,
|
|
|
56 |
Rreq = 1,
|
|
|
57 |
Rvalue = 2,
|
|
|
58 |
Rindex = 4,
|
|
|
59 |
Rcount = 6,
|
|
|
60 |
Rsetuplen = 8,
|
|
|
61 |
|
|
|
62 |
/* standard requests */
|
|
|
63 |
Rgetstatus = 0,
|
|
|
64 |
Rclearfeature = 1,
|
|
|
65 |
Rsetfeature = 3,
|
|
|
66 |
Rsetaddr = 5,
|
|
|
67 |
Rgetdesc = 6,
|
|
|
68 |
|
|
|
69 |
/* device states */
|
|
|
70 |
Dconfig = 0, /* configuration in progress */
|
|
|
71 |
Denabled, /* address assigned */
|
|
|
72 |
Ddetach, /* device is detached */
|
|
|
73 |
Dreset, /* its port is being reset */
|
|
|
74 |
|
|
|
75 |
/* (root) Hub reply to port status (reported to usbd) */
|
|
|
76 |
HPpresent = 0x1,
|
|
|
77 |
HPenable = 0x2,
|
|
|
78 |
HPsuspend = 0x4,
|
|
|
79 |
HPovercurrent = 0x8,
|
|
|
80 |
HPreset = 0x10,
|
|
|
81 |
HPpower = 0x100,
|
|
|
82 |
HPslow = 0x200,
|
|
|
83 |
HPhigh = 0x400,
|
|
|
84 |
HPstatuschg = 0x10000,
|
|
|
85 |
HPchange = 0x20000,
|
|
|
86 |
};
|
|
|
87 |
|
|
|
88 |
/*
|
|
|
89 |
* Services provided by the driver.
|
|
|
90 |
* epopen allocates hardware structures to prepare the endpoint
|
|
|
91 |
* for I/O. This happens when the user opens the data file.
|
|
|
92 |
* epclose releases them. This happens when the data file is closed.
|
|
|
93 |
* epwrite tries to write the given bytes, waiting until all of them
|
|
|
94 |
* have been written (or failed) before returning; but not for Iso.
|
|
|
95 |
* epread does the same for reading.
|
|
|
96 |
* It can be assumed that endpoints are DMEXCL but concurrent
|
|
|
97 |
* read/writes may be issued and the controller must take care.
|
|
|
98 |
* For control endpoints, device-to-host requests must be followed by
|
|
|
99 |
* a read of the expected length if needed.
|
|
|
100 |
* The port requests are called when usbd issues commands for root
|
|
|
101 |
* hubs. Port status must return bits as a hub request would do.
|
|
|
102 |
* Toggle handling and other details are left for the controller driver
|
|
|
103 |
* to avoid mixing too much the controller and the comon device.
|
|
|
104 |
* While an endpoint is closed, its toggles are saved in the Ep struct.
|
|
|
105 |
*/
|
|
|
106 |
struct Hciimpl
|
|
|
107 |
{
|
|
|
108 |
void *aux; /* for controller info */
|
|
|
109 |
void (*init)(Hci*); /* init. controller */
|
|
|
110 |
void (*dump)(Hci*); /* debug */
|
|
|
111 |
void (*interrupt)(Ureg*, void*); /* service interrupt */
|
|
|
112 |
void (*epopen)(Ep*); /* prepare ep. for I/O */
|
|
|
113 |
void (*epclose)(Ep*); /* terminate I/O on ep. */
|
|
|
114 |
long (*epread)(Ep*,void*,long); /* transmit data for ep */
|
|
|
115 |
long (*epwrite)(Ep*,void*,long); /* receive data for ep */
|
|
|
116 |
char* (*seprintep)(char*,char*,Ep*); /* debug */
|
|
|
117 |
int (*portenable)(Hci*, int, int); /* enable/disable port */
|
|
|
118 |
int (*portreset)(Hci*, int, int); /* set/clear port reset */
|
|
|
119 |
int (*portstatus)(Hci*, int); /* get port status */
|
|
|
120 |
void (*shutdown)(Hci*); /* shutdown for reboot */
|
|
|
121 |
void (*debug)(Hci*, int); /* set/clear debug flag */
|
|
|
122 |
};
|
|
|
123 |
|
|
|
124 |
struct Hci
|
|
|
125 |
{
|
|
|
126 |
ISAConf; /* hardware info */
|
|
|
127 |
int tbdf; /* type+busno+devno+funcno */
|
|
|
128 |
int ctlrno; /* controller number */
|
|
|
129 |
int nports; /* number of ports in hub */
|
|
|
130 |
int highspeed;
|
|
|
131 |
Hciimpl; /* HCI driver */
|
|
|
132 |
};
|
|
|
133 |
|
|
|
134 |
/*
|
|
|
135 |
* USB endpoint.
|
|
|
136 |
* All endpoints are kept in a global array. The first
|
|
|
137 |
* block of fields is constant after endpoint creation.
|
|
|
138 |
* The rest is configuration information given to all controllers.
|
|
|
139 |
* The first endpoint for a device (known as ep0) represents the
|
|
|
140 |
* device and is used to configure it and create other endpoints.
|
|
|
141 |
* Its QLock also protects per-device data in dev.
|
|
|
142 |
* See Hciimpl for clues regarding how this is used by controllers.
|
|
|
143 |
*/
|
|
|
144 |
struct Ep
|
|
|
145 |
{
|
|
|
146 |
Ref; /* one per fid (and per dev ep for ep0s) */
|
|
|
147 |
|
|
|
148 |
/* const once inited. */
|
|
|
149 |
int idx; /* index in global eps array */
|
|
|
150 |
int nb; /* endpoint number in device */
|
|
|
151 |
Hci* hp; /* HCI it belongs to */
|
|
|
152 |
Udev* dev; /* device for the endpoint */
|
|
|
153 |
Ep* ep0; /* control endpoint for its device */
|
|
|
154 |
|
|
|
155 |
QLock; /* protect fields below */
|
|
|
156 |
char* name; /* for ep file names at #u/ */
|
|
|
157 |
int inuse; /* endpoint is open */
|
|
|
158 |
int mode; /* OREAD, OWRITE, or ORDWR */
|
|
|
159 |
int clrhalt; /* true if halt was cleared on ep. */
|
|
|
160 |
int debug; /* per endpoint debug flag */
|
|
|
161 |
char* info; /* for humans to read */
|
|
|
162 |
long maxpkt; /* maximum packet size */
|
|
|
163 |
int ttype; /* tranfer type */
|
|
|
164 |
ulong load; /* in µs, for a fransfer of maxpkt bytes */
|
|
|
165 |
void* aux; /* for controller specific info */
|
|
|
166 |
int rhrepl; /* fake root hub replies */
|
|
|
167 |
int toggle[2]; /* saved toggles (while ep is not in use) */
|
|
|
168 |
long pollival; /* poll interval ([µ]frames; intr/iso) */
|
|
|
169 |
long hz; /* poll frequency (iso) */
|
|
|
170 |
long samplesz; /* sample size (iso) */
|
|
|
171 |
int ntds; /* nb. of Tds per µframe */
|
|
|
172 |
int tmout; /* 0 or timeout for transfers (ms) */
|
|
|
173 |
};
|
|
|
174 |
|
|
|
175 |
/*
|
|
|
176 |
* Per-device configuration and cached list of endpoints.
|
|
|
177 |
* eps[0]->QLock protects it.
|
|
|
178 |
*/
|
|
|
179 |
struct Udev
|
|
|
180 |
{
|
|
|
181 |
int nb; /* USB device number */
|
|
|
182 |
int state; /* state for the device */
|
|
|
183 |
int ishub; /* hubs can allocate devices */
|
|
|
184 |
int isroot; /* is a root hub */
|
|
|
185 |
int speed; /* Full/Low/High/No -speed */
|
|
|
186 |
int hub; /* dev number for the parent hub */
|
|
|
187 |
int port; /* port number in the parent hub */
|
|
|
188 |
Ep* eps[Ndeveps]; /* end points for this device (cached) */
|
|
|
189 |
};
|
|
|
190 |
|
|
|
191 |
void addhcitype(char *type, int (*reset)(Hci*));
|
|
|
192 |
|
|
|
193 |
extern char *usbmodename[];
|
|
|
194 |
|
|
|
195 |
extern char *seprintdata(char*,char*,uchar*,int);
|