Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | \ ========== Copyright Header Begin ========================================== |
2 | \ | |
3 | \ Hypervisor Software File: edtd.fth | |
4 | \ | |
5 | \ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | \ | |
7 | \ - Do no alter or remove copyright notices | |
8 | \ | |
9 | \ - Redistribution and use of this software in source and binary forms, with | |
10 | \ or without modification, are permitted provided that the following | |
11 | \ conditions are met: | |
12 | \ | |
13 | \ - Redistribution of source code must retain the above copyright notice, | |
14 | \ this list of conditions and the following disclaimer. | |
15 | \ | |
16 | \ - Redistribution in binary form must reproduce the above copyright notice, | |
17 | \ this list of conditions and the following disclaimer in the | |
18 | \ documentation and/or other materials provided with the distribution. | |
19 | \ | |
20 | \ Neither the name of Sun Microsystems, Inc. or the names of contributors | |
21 | \ may be used to endorse or promote products derived from this software | |
22 | \ without specific prior written permission. | |
23 | \ | |
24 | \ This software is provided "AS IS," without a warranty of any kind. | |
25 | \ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
26 | \ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
27 | \ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
28 | \ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
29 | \ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
30 | \ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
31 | \ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
32 | \ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
33 | \ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
34 | \ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
35 | \ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
36 | \ | |
37 | \ You acknowledge that this software is not designed, licensed or | |
38 | \ intended for use in the design, construction, operation or maintenance of | |
39 | \ any nuclear facility. | |
40 | \ | |
41 | \ ========== Copyright Header End ============================================ | |
42 | id: @(#)edtd.fth 1.1 07/01/24 | |
43 | purpose: Data structures and manuipulation routines for OHCI USB Controller | |
44 | \ See license at end of file | |
45 | ||
46 | hex | |
47 | headers | |
48 | ||
49 | \ XXX Isochronous is not supported in the current version of the OHCI driver | |
50 | ||
51 | \ --------------------------------------------------------------------------- | |
52 | \ Data structures for this implementation of the OHCI USB Driver include: | |
53 | \ - hcca 256 bytes defined by OCHI Spec for USB HC | |
54 | \ - ed-control pointer to the control ED list | |
55 | \ - ed-bulk pointer to the bulk ED list | |
56 | \ - intr internal array of interrupts (to complement the hcca) | |
57 | \ --------------------------------------------------------------------------- | |
58 | ||
59 | \ --------------------------------------------------------------------------- | |
60 | \ HcHCCA as defined by the OHCI Spec; 256-byte aligned | |
61 | \ --------------------------------------------------------------------------- | |
62 | ||
63 | 0 value intr \ Software interrupt buffer | |
64 | 0 value hcca \ Virtual address of HcHCCA | |
65 | 0 value hcca-unaligned \ Unaligned virtual address of HcHCCA | |
66 | 0 value hcca-phys \ Physical address of HcHCCA | |
67 | ||
68 | \ HCCA | |
69 | d# 32 constant #intr | |
70 | ||
71 | struct ( hcca ) | |
72 | #intr 4 * field >hcca-intr \ Physical addresses of interrupt EDs | |
73 | 2 field >hcca-frame | |
74 | 2 field >hcca-pad | |
75 | 4 field >hcca-done \ Physical addresses of done EDs | |
76 | d# 120 field >hcca-reserved | |
77 | constant /hcca | |
78 | ||
79 | : hcca! ( padr idx -- ) 4 * hcca + le-l! ; | |
80 | ||
81 | : init-hcca ( -- ) | |
82 | \ Allocate hcca | |
83 | /hcca aligned256-alloc | |
84 | dup to hcca \ Aligned address | |
85 | swap to hcca-unaligned \ Unaligned address | |
86 | /hcca true dma-map-in to hcca-phys \ Physical address | |
87 | ||
88 | \ Initialize hcca | |
89 | hcca /hcca erase | |
90 | hcca hcca-phys /hcca dma-sync | |
91 | ; | |
92 | ||
93 | \ --------------------------------------------------------------------------- | |
94 | \ Internal interrupt list per >hcca-intr entry | |
95 | \ | |
96 | \ XXX I can see how this can be expanded to >intr-head32ms, >intr-tail32ms, | |
97 | \ XXX and so on, to support the various poll intervals. See comment on | |
98 | \ XXX interrupt scheduling below. | |
99 | \ --------------------------------------------------------------------------- | |
100 | struct \ An entry of intr | |
101 | 4 field >intr-head \ Virtual address of interrupt head | |
102 | 4 field >intr-tail \ Virtual address of interrupt tail | |
103 | 4 field >iso-head \ Virtual address of isochronous head | |
104 | 4 field >iso-tail \ Virtual address of isochronous tail | |
105 | dup constant /intr-entry | |
106 | #intr * constant /intr | |
107 | ||
108 | : init-intr ( -- ) | |
109 | /intr alloc-mem dup to intr \ Allocate intr | |
110 | /intr erase \ Initialize intr | |
111 | ; | |
112 | ||
113 | : 'intr ( idx -- adr ) /intr-entry * intr + ; | |
114 | : intr-head@ ( idx -- adr ) 'intr >intr-head l@ ; | |
115 | : intr-head! ( adr idx -- ) 'intr >intr-head l! ; | |
116 | : intr-tail@ ( idx -- adr ) 'intr >intr-tail l@ ; | |
117 | : intr-tail! ( adr idx -- ) 'intr >intr-tail l! ; | |
118 | : iso-head@ ( idx -- adr ) 'intr >iso-head l@ ; | |
119 | : iso-head! ( adr idx -- ) 'intr >iso-head l! ; | |
120 | : iso-tail@ ( idx -- adr ) 'intr >iso-tail l@ ; | |
121 | : iso-tail! ( adr idx -- ) 'intr >iso-tail l! ; | |
122 | ||
123 | \ --------------------------------------------------------------------------- | |
124 | \ Endpoint descriptor (ED) as defined by the OHCI Spec; 16-byte aligned | |
125 | \ --------------------------------------------------------------------------- | |
126 | ||
127 | \ XXX If we add ed-control-tail & ed-bulk-tail, then insert-* does not have | |
128 | \ XXX to disable the function, we need to skip tail until insert is done. | |
129 | ||
130 | 0 value ed-control \ Virtual address of head of control ED list | |
131 | 0 value ed-bulk \ Virtual address of head of bulk ED list | |
132 | ||
133 | struct \ Beginning of ED | |
134 | 4 field >hced-control \ ED control info | |
135 | 4 field >hced-tdtail \ Physical address of TD tail | |
136 | 4 field >hced-tdhead \ Physical address of TD head | |
137 | 4 field >hced-next \ Physical address of next ED | |
138 | dup constant /hced | |
139 | \ Driver specific fields | |
140 | 4 field >ed-phys \ Physical address of HC ED | |
141 | 4 field >ed-next \ Pointer to the next endpoint | |
142 | 4 field >ed-prev \ Pointer to the previous endpoint | |
143 | 4 field >ed-unaligned \ Unaligned virtual address of the ED | |
144 | 4 field >ed-size \ Size of EDs+TDs | |
145 | d# 32 round-up \ Multiple of 32 bytes | |
146 | \ 32 bytes because there are cases where | |
147 | \ EDs and TDs are allocated together | |
148 | dup constant /ed \ Size of each ed | |
149 | #intr * constant /eds \ Size of all eds allocated at a time | |
150 | ||
151 | \ >hced-control constants | |
152 | 0000 constant ED_DIR_TD | |
153 | 0800 constant ED_DIR_OUT | |
154 | 1000 constant ED_DIR_IN | |
155 | 1800 constant ED_DIR_MASK | |
156 | ||
157 | 0000 constant ED_SPEED_FULL | |
158 | 2000 constant ED_SPEED_LO | |
159 | 2000 constant ED_SPEED_MASK | |
160 | ||
161 | 0000 constant ED_SKIP_OFF | |
162 | 4000 constant ED_SKIP_ON | |
163 | 4000 constant ED_SKIP_MASK | |
164 | ||
165 | 0000 constant ED_FORMAT_G | |
166 | 8000 constant ED_FORMAT_I | |
167 | 8000 constant ED_FORMAT_MASK | |
168 | ||
169 | 0000 constant ED_TOGGLE_DATA0 | |
170 | 0002 constant ED_TOGGLE_DATA1 | |
171 | 0002 constant ED_TOGGLE_MASK | |
172 | ||
173 | 0001 constant ED_HALTED | |
174 | ||
175 | : ed-data>di-data ( n -- n' ) ED_TOGGLE_MASK and if 1 else 0 then ; | |
176 | : di-data>ed-data ( n -- n' ) if ED_TOGGLE_DATA1 else ED_TOGGLE_DATA0 then ; | |
177 | ||
178 | : (set-skip) ( ed skip-bit -- ) | |
179 | >r | |
180 | dup >hced-control dup le-l@ | |
181 | ED_SKIP_MASK invert and r> or | |
182 | swap le-l! | |
183 | dup >ed-phys l@ /hced dma-sync | |
184 | ; | |
185 | : ed-set-skip ( ed -- ) ED_SKIP_ON (set-skip) ; | |
186 | : ed-unset-skip ( ed -- ) ED_SKIP_OFF (set-skip) ; | |
187 | ||
188 | \ --------------------------------------------------------------------------- | |
189 | \ Transfer Descriptor (TD) as defined by the OHCI Spec: | |
190 | \ general TDs are 16-byte aligned; isochronous TDs are 32-byte aligned. | |
191 | \ --------------------------------------------------------------------------- | |
192 | ||
193 | struct \ Beginning of General TD fields | |
194 | 4 field >hctd-control \ TD control info | |
195 | 4 field >hctd-cbp \ Physical address of current buffer pointer | |
196 | 4 field >hctd-next \ physical address of next TD | |
197 | 4 field >hctd-be \ physical address of buffer end | |
198 | dup constant /gtd | |
199 | \ Isochronous TD fields | |
200 | 2 field >hctd-offset0 \ Offset 0 / PSW 0 | |
201 | 2 field >hctd-offset1 \ Offset 1 / PSW 1 | |
202 | 2 field >hctd-offset2 \ Offset 2 / PSW 2 | |
203 | 2 field >hctd-offset3 \ Offset 3 / PSW 3 | |
204 | 2 field >hctd-offset4 \ Offset 4 / PSW 4 | |
205 | 2 field >hctd-offset5 \ Offset 5 / PSW 5 | |
206 | 2 field >hctd-offset6 \ Offset 6 / PSW 6 | |
207 | 2 field >hctd-offset7 \ Offset 7 / PSW 7 | |
208 | dup constant /itd | |
209 | \ Driver specific fields | |
210 | 4 field >td-phys \ Physical address of HC TD | |
211 | 4 field >td-next \ Virtual address of next TD | |
212 | 4 field >td-cbp \ Virtual address of current buffer pointer | |
213 | 4 field >td-pcbp \ Physical address of current buffer pointer | |
214 | 4 field >td-/cbp-all \ Buffer length (size of the entire buffer) | |
215 | \ For bulk and intr TDs | |
216 | d# 32 round-up \ Multiple of 32 bytes | |
217 | constant /td | |
218 | ||
219 | \ >hctd-control constants | |
220 | 0004.0000 constant TD_ROUND_ON | |
221 | 0000.0000 constant TD_ROUND_ERR | |
222 | 0004.0000 constant TD_ROUND_MASK | |
223 | ||
224 | 0000.0000 constant TD_DIR_SETUP | |
225 | 0008.0000 constant TD_DIR_OUT | |
226 | 0010.0000 constant TD_DIR_IN | |
227 | 0018.0000 constant TD_DIR_MASK | |
228 | ||
229 | 00c0.0000 constant TD_INTR_MIN | |
230 | 00e0.0000 constant TD_INTR_OFF | |
231 | 00e0.0000 constant TD_INTR_MASK | |
232 | ||
233 | 0000.0000 constant TD_TOGGLE_USE_ED | |
234 | 0200.0000 constant TD_TOGGLE_USE_LSB0 | |
235 | 0300.0000 constant TD_TOGGLE_USE_LSB1 | |
236 | 0100.0000 constant TD_TOGGLE_MASK | |
237 | 0c00.0000 constant TD_ERR_CNT_MASK | |
238 | ||
239 | 0000.0000 constant TD_CC_NOERROR | |
240 | 1000.0000 constant TD_CC_CRC | |
241 | 2000.0000 constant TD_CC_BITSTUFFING | |
242 | 3000.0000 constant TD_CC_DATATOGGLEMISMATCH | |
243 | 4000.0000 constant TD_CC_STALL | |
244 | 5000.0000 constant TD_CC_DEVICENOTRESPONDING | |
245 | 6000.0000 constant TD_CC_PIDCHECKFAILURE | |
246 | 7000.0000 constant TD_CC_UNEXPECTEDPID | |
247 | 8000.0000 constant TD_CC_DATAOVERRUN | |
248 | 9000.0000 constant TD_CC_DATAUNDERRUN | |
249 | c000.0000 constant TD_CC_BUFFEROVERRUN | |
250 | d000.0000 constant TD_CC_BUFFERUNDERRUN | |
251 | f000.0000 constant TD_CC_NOTACCESSED | |
252 | f000.0000 constant TD_CC_MASK | |
253 | ||
254 | : td-data>di-data ( n -- n' ) TD_TOGGLE_MASK and if 1 else 0 then ; | |
255 | : di-data>td-data ( n -- n' ) if TD_TOGGLE_USE_LSB1 else TD_TOGGLE_USE_LSB0 then ; | |
256 | ||
257 | \ --------------------------------------------------------------------------- | |
258 | ||
259 | : init-struct ( -- ) | |
260 | init-struct | |
261 | 0 to ed-control 0 to ed-bulk | |
262 | init-hcca | |
263 | init-intr | |
264 | ; | |
265 | ||
266 | \ --------------------------------------------------------------------------- | |
267 | \ ED and TDs for bulk, control and interrupt operations. | |
268 | \ ED and its list of TDs are allocated as needed. | |
269 | \ --------------------------------------------------------------------------- | |
270 | ||
271 | : init-ed ( ed.u,v,p len -- ) | |
272 | 2 pick >ed-size l! ( ed.u,v,p ) | |
273 | over >ed-phys l! ( ed,u,v ) | |
274 | >ed-unaligned l! ( ) | |
275 | ; | |
276 | ||
277 | : link-tds ( td.v td.p #tds -- ) | |
278 | 1- 0 ?do ( td.v td.p ) | |
279 | 2dup swap >td-phys l! ( td.v td.p ) | |
280 | /td + tuck over >hctd-next le-l! ( td.p' td.v ) | |
281 | dup /td + tuck swap ( td.p td.v' td.v' td.v ) | |
282 | >td-next l! ( td.p td.v ) | |
283 | swap ( td.v td.p ) | |
284 | loop | |
285 | swap >td-phys l! ( ) | |
286 | ; | |
287 | : link-edtd ( td.p #tds ed -- ) | |
288 | >r ( td.p #tds ) ( R: ed ) | |
289 | 1- /td * over + ( td.p ptail ) ( R: ed ) | |
290 | r@ >hced-tdtail le-l! ( td.p ) ( R: ed ) | |
291 | r> >hced-tdhead le-l! ( ) | |
292 | ; | |
293 | : link-edtds ( td.v td.p #tds ed -- ) | |
294 | >r 2dup r> link-edtd ( td.v td.p #tds ) \ Link ED to TD | |
295 | link-tds ( ) \ Link TDs | |
296 | ; | |
297 | : alloc-edtds ( #tds -- ed td ) | |
298 | dup >r /td * /ed + dup >r ( len ) ( R: #tds len ) | |
299 | aligned32-alloc-map-in ( ed.u,v,p ) ( R: #tds len ) | |
300 | over r@ erase ( ed.u,v,p ) ( R: #tds len ) | |
301 | 3dup r> init-ed ( ed.u,v,p ) ( R: #tds ) | |
302 | rot drop ( ed.v,p ) ( R: #tds ) | |
303 | over /ed + dup -rot ( ed td ed.p td.v ) ( R: #tds ) | |
304 | swap /ed + ( ed td td.v td.p ) ( R: #tds ) | |
305 | r> 4 pick link-edtds ( ed td ) | |
306 | ; | |
307 | : free-edtds ( ed -- ) | |
308 | >r ( R: ed ) | |
309 | r@ >ed-unaligned l@ ( ed.u ) ( R: ed ) | |
310 | r@ dup >ed-phys l@ ( ed.u,v,p ) ( R: ed ) | |
311 | r> >ed-size l@ ( ed.u,v,p size ) | |
312 | aligned32-free-map-out ( ) | |
313 | ; | |
314 | : sync-edtds ( ed -- ) | |
315 | dup >ed-phys l@ ( ed.v,p ) | |
316 | over >ed-size l@ ( ed.v,p len ) | |
317 | dma-sync ( ) | |
318 | ; | |
319 | : map-out-cbp ( td -- ) | |
320 | dup >td-cbp l@ over >td-pcbp l@ rot >td-/cbp-all l@ hcd-map-out | |
321 | ; | |
322 | ||
323 | \ --------------------------------------------------------------------------- | |
324 | \ Control scheduling | |
325 | \ --------------------------------------------------------------------------- | |
326 | ||
327 | : fixup-ed-next-prev ( ed -- ed ) | |
328 | dup >ed-prev l@ ?dup if over >ed-next l@ swap >ed-next l! then | |
329 | dup >ed-next l@ ?dup if over >ed-prev l@ swap >ed-prev l! then | |
330 | ; | |
331 | ||
332 | : insert-ed ( new-ed old-ed -- ) | |
333 | ?dup 0= if drop exit then \ No old-ed, done | |
334 | 2dup >ed-prev l! \ old-ed's prev is new-ed | |
335 | 2dup swap >ed-next l! \ new-ed's next is old-ed | |
336 | >ed-phys l@ swap >hced-next le-l! \ new-ed's hced-next is old-ed's phys | |
337 | ; | |
338 | ||
339 | : insert-control-ed ( ed -- ) | |
340 | dup ed-control insert-ed | |
341 | to ed-control | |
342 | ; | |
343 | : remove-control-ed ( ed -- ) | |
344 | fixup-ed-next-prev ( ed ) | |
345 | dup ed-control = if >ed-next l@ to ed-control else drop then | |
346 | ; | |
347 | ||
348 | \ --------------------------------------------------------------------------- | |
349 | \ Bulk scheduling | |
350 | \ --------------------------------------------------------------------------- | |
351 | ||
352 | : insert-bulk-ed ( ed -- ) | |
353 | dup ed-bulk insert-ed | |
354 | to ed-bulk | |
355 | ; | |
356 | : remove-bulk-ed ( ed -- ) | |
357 | fixup-ed-next-prev ( ed ) | |
358 | dup ed-bulk = if >ed-next l@ to ed-bulk else drop then | |
359 | ; | |
360 | ||
361 | \ --------------------------------------------------------------------------- | |
362 | \ Interrupt scheduling | |
363 | \ Schedule interrupt at the rate min(interval,2**x). | |
364 | \ | |
365 | \ XXX Need to determines which scheduling queue for that rate has the smallest | |
366 | \ committed bandwidth. | |
367 | \ | |
368 | \ XXX To really implement the various poll intervals, the simplistic way is | |
369 | \ XXX to have 32 dummy EDs for 1ms interval; 16 dummy EDs for 2ms interval; | |
370 | \ XXX 8 dummy EDs for 4ms interval; 4 dummy EDs for 8ms interval; | |
371 | \ XXX 2 dummy EDs for 16ms interval; and, 1 dummy ED for 32ms interval. | |
372 | \ XXX Then you link to the end of the lists of EDs for each interval. Ughhh! | |
373 | \ | |
374 | \ XXX For now, just implement fixed poll interval. | |
375 | \ | |
376 | \ XXX On further thought, since we're polling the intr pipeline from the | |
377 | \ XXX device driver, the driver driver can poll the intr at the interval | |
378 | \ XXX specified. And thus, the need to fully implement poll intervals at | |
379 | \ XXX the HCD level is redundant. | |
380 | \ --------------------------------------------------------------------------- | |
381 | ||
382 | 4 constant intr-interval | |
383 | ||
384 | : (insert-intr-ed) ( ed idx -- ) | |
385 | dup >r ( ed idx ) ( R: idx ) | |
386 | intr-tail@ ?dup 0= if ( ed ) ( R: idx ) | |
387 | dup r@ intr-head! ( ed ) ( R: idx ) | |
388 | dup >ed-phys l@ r@ hcca! ( ed ) ( R: idx ) | |
389 | else ( ed ted ) ( R: idx ) | |
390 | 2dup >ed-next l! ( ed ted ) ( R: idx ) | |
391 | over >ed-phys l@ over >hced-next le-l! ( ed ted ) ( R: idx ) | |
392 | over >ed-prev l! ( ed ) ( R: idx ) | |
393 | then | |
394 | r@ iso-head@ over >ed-next l! ( ed ) ( R: idx ) | |
395 | r> intr-tail! ( ) | |
396 | ; | |
397 | : insert-intr-ed ( ed interval -- ) | |
398 | drop | |
399 | #intr 0 do dup i (insert-intr-ed) intr-interval +loop drop | |
400 | ; | |
401 | ||
402 | : (remove-intr-ed) ( ed idx -- ) | |
403 | >r ( ed ) ( R: idx ) | |
404 | fixup-ed-next-prev ( ed ) ( R: idx ) | |
405 | r@ intr-head@ over = if ( ed ) ( R: idx ) | |
406 | dup >ed-next l@ dup r@ intr-head! ( ed ped ) ( R: idx ) | |
407 | dup if >ed-phys l@ then r@ hcca! | |
408 | ( ed ) ( R: idx ) | |
409 | then | |
410 | r@ intr-tail@ over = if ( ed ) ( R: idx ) | |
411 | dup >ed-prev l@ r@ intr-tail! ( ed ) ( R: idx ) | |
412 | then | |
413 | r> 2drop | |
414 | ; | |
415 | : remove-intr-ed ( ed -- ) | |
416 | #intr 0 do dup i (remove-intr-ed) intr-interval +loop drop | |
417 | ; | |
418 | ||
419 | \ --------------------------------------------------------------------------- | |
420 | \ Wait for an ED to be done and process any errors. | |
421 | \ | |
422 | \ When done? returns no error found yet, the caller should should if errors | |
423 | \ were found in the TDs. | |
424 | \ --------------------------------------------------------------------------- | |
425 | ||
426 | defer process-hc-status | |
427 | ||
428 | 0 value timeout | |
429 | ||
430 | : .td-error ( cc -- ) | |
431 | case | |
432 | TD_CC_CRC of " CRC" USB_ERR_CRC endof | |
433 | TD_CC_BITSTUFFING of " Bit Stuffing" USB_ERR_BITSTUFFING endof | |
434 | TD_CC_DATATOGGLEMISMATCH of " Data Toggle Mismatch" USB_ERR_DATATOGGLEMISMATCH endof | |
435 | TD_CC_STALL of " Stall" USB_ERR_STALL endof | |
436 | TD_CC_DEVICENOTRESPONDING of " Device Not Responding" USB_ERR_DEVICENOTRESPONDING endof | |
437 | TD_CC_PIDCHECKFAILURE of " PID Check Failure" USB_ERR_PIDCHECKFAILURE endof | |
438 | TD_CC_UNEXPECTEDPID of " Unexpected PID" USB_ERR_UNEXPECTEDPIC endof | |
439 | TD_CC_DATAOVERRUN of " Data Overrun" USB_ERR_DATAOVERRUN endof | |
440 | TD_CC_DATAUNDERRUN of " Data Underrun" USB_ERR_DATAUNDERRUN endof | |
441 | TD_CC_BUFFEROVERRUN of " Buffer Overrun" USB_ERR_BUFFEROVERRUN endof | |
442 | TD_CC_BUFFERUNDERRUN of " Buffer Underrun" USB_ERR_BUFFERUNDERRUN endof | |
443 | TD_CC_NOTACCESSED of " Not Accessed" USB_ERR_NOTACCESSED endof | |
444 | ( default ) " Unknown Error" rot USB_ERR_UNKNOWN swap | |
445 | endcase | |
446 | set-usb-error | |
447 | ; | |
448 | ||
449 | : error? ( td -- usberr ) | |
450 | begin | |
451 | dup >td-next l@ if \ Process a real TD | |
452 | dup >hctd-control le-l@ TD_CC_MASK and ?dup if | |
453 | .td-error drop 0 \ Error found in TD | |
454 | else | |
455 | >td-next l@ \ TD's ok, examine the next TD | |
456 | then | |
457 | else \ Don't need to process last dummy TD | |
458 | drop 0 | |
459 | then | |
460 | ?dup 0= until | |
461 | usb-error | |
462 | ; | |
463 | ||
464 | : ed-done? ( ed -- done? ) | |
465 | dup >hced-tdhead le-l@ dup ED_HALTED and ( ed head halted? ) | |
466 | swap h# ffff.fff0 and ( ed halted? head ) | |
467 | rot >hced-tdtail le-l@ h# ffff.fff0 and = ( halted? head=tail? ) | |
468 | or ( done? ) | |
469 | ; | |
470 | ||
471 | : done? ( ed -- error? ) | |
472 | begin | |
473 | process-hc-status | |
474 | dup sync-edtds | |
475 | dup ed-done? ?dup 0= if | |
476 | 1 ms | |
477 | timeout 1- dup to timeout 0= | |
478 | then | |
479 | until | |
480 | ed-done? 0= if " Timeout" USB_ERR_TIMEOUT set-usb-error then | |
481 | usb-error | |
482 | ; | |
483 | ||
484 | : get-actual ( td -- actual ) | |
485 | dup >hctd-cbp le-l@ ?dup if | |
486 | swap >td-pcbp l@ - | |
487 | else | |
488 | dup >hctd-be le-l@ swap >td-pcbp l@ - 1+ | |
489 | then | |
490 | ; | |
491 | ||
492 | headers | |
493 | ||
494 | \ LICENSE_BEGIN | |
495 | \ Copyright (c) 2006 FirmWorks | |
496 | \ | |
497 | \ Permission is hereby granted, free of charge, to any person obtaining | |
498 | \ a copy of this software and associated documentation files (the | |
499 | \ "Software"), to deal in the Software without restriction, including | |
500 | \ without limitation the rights to use, copy, modify, merge, publish, | |
501 | \ distribute, sublicense, and/or sell copies of the Software, and to | |
502 | \ permit persons to whom the Software is furnished to do so, subject to | |
503 | \ the following conditions: | |
504 | \ | |
505 | \ The above copyright notice and this permission notice shall be | |
506 | \ included in all copies or substantial portions of the Software. | |
507 | \ | |
508 | \ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
509 | \ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
510 | \ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
511 | \ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
512 | \ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
513 | \ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
514 | \ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
515 | \ | |
516 | \ LICENSE_END |