Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | \ ========== Copyright Header Begin ========================================== |
2 | \ | |
3 | \ Hypervisor Software File: usbutils.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: @(#)usbutils.fth 1.33 04/09/22 | |
43 | \ purpose: | |
44 | \ copyright: Copyright 2004 Sun Microsystems, Inc. All Rights Reserved | |
45 | \ copyright: Use is subject to license terms. | |
46 | ||
47 | external | |
48 | ||
49 | \ XXX Must use set-report(output) request. | |
50 | \ : set-leds ( which-leds? -- ) | |
51 | \ ; | |
52 | ||
53 | \ Nothing here yet because we're not sure if bell will be supported in | |
54 | \ USB keyboards. | |
55 | \ XXX called from ring-bell in keyboard.fth | |
56 | : ring-keyboard-bell ( -- ?? ) | |
57 | ; | |
58 | ||
59 | \ Do a set-protocol to get to boot mode. | |
60 | \ Interface Protocol == 0 (Keyboard). | |
61 | ||
62 | : set-kbd-bootmode ( -- hw-err? | stat 0 ) | |
63 | h# 21 set-prtcl-buff^v >ctrl-pkt-breqtype c! \ class request | |
64 | h# b set-prtcl-buff^v >ctrl-pkt-brequest c! \ 0xb=set protocol | |
65 | 0 set-prtcl-buff^v >ctrl-pkt-wvalue le-w! \ 0=boot protocol | |
66 | my-interface set-prtcl-buff^v >ctrl-pkt-windex le-w! | |
67 | 0 set-prtcl-buff^v >ctrl-pkt-wlength le-w! \ 0=no data | |
68 | ||
69 | my-speed | |
70 | 1 \ dir; no, don't xfer data from device to mem | |
71 | 0max-packet \ max-pkt | |
72 | 0 \ buf-adr; no data coming back | |
73 | 0 \ buf-len; no data coming back | |
74 | set-prtcl-buff^v \ pkt-adr | |
75 | /ctrl-pkt \ pkt-len | |
76 | my-endpt \ endpt | |
77 | my-addr \ usb-adr | |
78 | ( low-speed? dir max-pkt buf-adr buf-len rqst-adr rqst-len end-pt usb-adr ) | |
79 | ||
80 | execute-control ( hw-err? | stat 0 ) | |
81 | ; | |
82 | ||
83 | : get-kbd-protocol ( -- hw-err? | stat 0 ) | |
84 | h# a1 set-prtcl-buff^v >ctrl-pkt-breqtype c! \ class request | |
85 | h# 3 set-prtcl-buff^v >ctrl-pkt-brequest c! \ 0x3=get protocol | |
86 | 0 set-prtcl-buff^v >ctrl-pkt-wvalue le-w! | |
87 | my-interface set-prtcl-buff^v >ctrl-pkt-windex le-w! | |
88 | 1 set-prtcl-buff^v >ctrl-pkt-wlength le-w! \ 1=#bytes data | |
89 | ||
90 | my-speed | |
91 | 0 \ dir; yes, do xfer data from device to mem | |
92 | 0max-packet \ max-pkt | |
93 | 1-byte^v \ buf-adr for data coming back | |
94 | 0 over c! \ clear 1 data byte | |
95 | 1 \ len of data coming back | |
96 | set-prtcl-buff^v \ pkt-adr | |
97 | /ctrl-pkt \ pkt-len | |
98 | my-endpt \ endpt | |
99 | my-addr \ usb-adr | |
100 | ( low-speed? dir max-pkt buf-adr buf-len rqst-adr rqst-len end-pt usb-adr ) | |
101 | ||
102 | execute-control ( hw-err? | stat 0 ) | |
103 | ; | |
104 | ||
105 | : set-kbd-idle ( -- hw-err? | stat 0 ) | |
106 | h# 21 set-prtcl-buff^v >ctrl-pkt-breqtype c! \ class request | |
107 | h# a set-prtcl-buff^v >ctrl-pkt-brequest c! \ 0xa=set idle | |
108 | h# 7d00 set-prtcl-buff^v >ctrl-pkt-wvalue le-w! \ idle=125x4 ms. | |
109 | my-interface set-prtcl-buff^v >ctrl-pkt-windex le-w! | |
110 | 0 set-prtcl-buff^v >ctrl-pkt-wlength le-w! \ 0=no data | |
111 | ||
112 | my-speed | |
113 | 1 \ dir; no, don't xfer data from device to mem | |
114 | 0max-packet \ max-pkt | |
115 | 0 \ buf-adr; no data coming back | |
116 | 0 \ buf-len; no data coming back | |
117 | set-prtcl-buff^v \ pkt-adr | |
118 | /ctrl-pkt \ pkt-len | |
119 | my-endpt \ endpt | |
120 | my-addr \ usb-adr | |
121 | ( low-speed? dir max-pkt buf-adr buf-len rqst-adr rqst-len end-pt usb-adr ) | |
122 | ||
123 | execute-control ( hw-err? | stat 0 ) | |
124 | ; | |
125 | ||
126 | : get-kbd-idle ( -- hw-err? | stat 0 ) | |
127 | h# a1 set-prtcl-buff^v >ctrl-pkt-breqtype c! \ class request | |
128 | 2 set-prtcl-buff^v >ctrl-pkt-brequest c! \ 2=get idle | |
129 | 0 set-prtcl-buff^v >ctrl-pkt-wvalue le-w! | |
130 | my-interface set-prtcl-buff^v >ctrl-pkt-windex le-w! | |
131 | 1 set-prtcl-buff^v >ctrl-pkt-wlength le-w! \ 1=#bytes data | |
132 | ||
133 | my-speed | |
134 | 0 \ dir; yes, do xfer data from device to mem | |
135 | 0max-packet \ max-pkt | |
136 | 1-byte^v \ buf-adr for data coming back | |
137 | 0 over c! \ clear 1 byte of data | |
138 | 1 \ len of data coming back | |
139 | set-prtcl-buff^v \ pkt-adr | |
140 | /ctrl-pkt \ pkt-len | |
141 | my-endpt \ endpt | |
142 | my-addr \ usb-adr | |
143 | ( low-speed? dir max-pkt buf-adr buf-len rqst-adr rqst-len end-pt usb-adr ) | |
144 | ||
145 | execute-control ( hw-err? | stat 0 ) | |
146 | ; | |
147 | ||
148 | ||
149 | \ We've received a stall status when checking the interrupt status with | |
150 | \ the HA. Make a certain number of attempts to unstall, and then throw | |
151 | \ when the last attempt is unsuccessful. | |
152 | ||
153 | : issue-unstall ( -- hw-err? | stat 0 ) | |
154 | unstall-cnt 9 > if | |
155 | \ poop maybe we should attempt to reset the device, then reconfigure | |
156 | \ it for boot mode and set the ticker again, and keep track of *that* | |
157 | \ process for x number of times... | |
158 | ." USB console device could not be unstalled..." cr | |
159 | true throw | |
160 | else | |
161 | \ issue the unstall via execute-control | |
162 | 1 std-pkt-buff^v >ctrl-pkt-breqtype c! \ 0x1= clear feature | |
163 | 1 std-pkt-buff^v >ctrl-pkt-brequest c! \ 0x1=CLEAR_FEATURE | |
164 | 0 std-pkt-buff^v >ctrl-pkt-wvalue le-w! \ 0=ENDPOINT_STALL | |
165 | my-int-endpt std-pkt-buff^v >ctrl-pkt-windex le-w! | |
166 | 0 std-pkt-buff^v >ctrl-pkt-wlength le-w! \ 0=no data | |
167 | ||
168 | my-speed | |
169 | 1 \ dir=no xfer data usb->mem | |
170 | /ctrl-pkt \ max-pkt = len of outgoing request | |
171 | 0 0 \ buf-adr, buf-len | |
172 | get-descr-buff^v \ request-adr | |
173 | /ctrl-pkt \ request-len | |
174 | my-endpt \ endpoint | |
175 | my-addr \ usb-adr | |
176 | ( speed dir max-pkt buf-adr buf-len rqst-adr rqst-len end-pt usb-adr ) | |
177 | ||
178 | execute-control ( hw-err? | stat 0 ) | |
179 | ||
180 | unstall-cnt 1+ to unstall-cnt | |
181 | then | |
182 | ; | |
183 | ||
184 | ||
185 | : attempt-unstall ( -- ack|nak|stall ) | |
186 | issue-unstall ( hw-err?|stat 0 ) | |
187 | 0<> if | |
188 | true throw \ hw-err during unstall attempt | |
189 | then | |
190 | ; | |
191 | ||
192 | ||
193 | \ headers \ XXX for debugging | |
194 | ||
195 | 5 constant no-response-error | |
196 | ||
197 | 0 value no-response-cnt | |
198 | ||
199 | : possible-no-response ( hw-err -- hw-err ) | |
200 | dup no-response-error = if | |
201 | no-response-cnt 1+ to no-response-cnt | |
202 | then | |
203 | ; | |
204 | ||
205 | defer maybe-message | |
206 | ||
207 | : .no-response ( -- ) | |
208 | ['] noop to maybe-message \ publish once only | |
209 | ." USB keyboard not responding, please power cycle." cr | |
210 | ; | |
211 | ||
212 | ' .no-response to maybe-message | |
213 | ||
214 | : not-responding? ( -- not-there? ) | |
215 | no-response-cnt d# 10 >= | |
216 | ; | |
217 | ||
218 | : dummy-keys ( -- Stop-a? ) | |
219 | keybuff-curr^v /key-info-buff erase | |
220 | eval-key-data | |
221 | ; | |
222 | ||
223 | \ Send off to the HA/parent to see if a keyboard packet is present, | |
224 | \ and if so then send the data off to the key evaluation routine. | |
225 | \ Check for hardware status errors, and also check for usb NAK (no | |
226 | \ packets waiting) and STALL (indicating a usb function problem). | |
227 | ||
228 | : poll-usb ( -- stopA? ) | |
229 | not-responding? if \ essentially no recovery | |
230 | maybe-message | |
231 | dummy-keys exit \ dummy to clear other code | |
232 | then | |
233 | keybuff-curr^v our-ha-token @ int-transaction-status ( hw-err?|stat 0) | |
234 | ?dup if ( hw-err ) | |
235 | possible-no-response drop | |
236 | dummy-keys exit \ dummy to clear other code | |
237 | then ( stat ) | |
238 | ||
239 | 0 to no-response-cnt \ still responding | |
240 | ||
241 | case | |
242 | h# 6 of \ nak | |
243 | false | |
244 | endof ( no-Stop-a ) | |
245 | ||
246 | h# e of \ stall | |
247 | \ poop turn-off tick timer? | |
248 | \ poop turn-off host timer? | |
249 | begin | |
250 | attempt-unstall ( ack|nack|stall ) | |
251 | \ unstall attempt has built-in "max count" | |
252 | \ loop check; does throw when at max count | |
253 | 2 = if ( ) \ ack rcvd from unstall | |
254 | true ( loop-exit-flag ) | |
255 | else \ nack or stall from unstall attempt | |
256 | false ( loop-noexit-flag ) | |
257 | then | |
258 | until ( ) | |
259 | \ poop turn-on tick timer? | |
260 | \ poop turn-on host timer? | |
261 | false ( no-Stop-A ) | |
262 | endof | |
263 | ||
264 | 2 of \ ack | |
265 | eval-key-data ( Stop-A? ) | |
266 | endof ( Stop-A? ) | |
267 | endcase | |
268 | ; | |
269 | ||
270 | ||
271 | \ If keyboard "interrupts" were already running then turn them off. | |
272 | ||
273 | : makesure-kbdints-off ( -- ) | |
274 | our-ha-token @ dup -1 <> if ( token ) | |
275 | disable-int-transactions to ha-toggle ( ) | |
276 | -1 our-ha-token ! ( ) | |
277 | else | |
278 | drop ( ) | |
279 | then | |
280 | ; | |
281 | ||
282 | ||
283 | \ For "reset", turn off repeat-interrupt-request if it's already on and | |
284 | \ set the token to -1 to indicate interrupts are off. Set up the device | |
285 | \ to be a "boot" device, and initialize software variables. Then send 1 | |
286 | \ interrupt request and look at its status to see if the keyboard is | |
287 | \ (still) there. If there and everything is ok then turn on the repeated | |
288 | \ interrupts, and link our tick timer to check the the status | |
289 | \ periodically. | |
290 | \ [ For the Sun keyboards, reset was in the probe.fth file. ] | |
291 | ||
292 | : init-kbd ( -- ) | |
293 | makesure-kbdints-off ( ) | |
294 | ['] set-kbd-bootmode do-ctrl/err-loop ( ) | |
295 | ['] set-kbd-idle do-ctrl/err-loop | |
296 | clear-keyboard ( ) | |
297 | ; | |
298 | ||
299 | \ from parent device node if an interface, from my node if combined device | |
300 | : set-my-0max-packet ( -- ) | |
301 | " 0max-packet" get-inherited-property ( true | adr len false ) | |
302 | if | |
303 | ." Unable to get 0max-packet for usb keyboard." cr | |
304 | true throw | |
305 | else | |
306 | decode-int to 0max-packet | |
307 | 2drop | |
308 | then | |
309 | ; | |
310 | ||
311 | \ low-speed property from my node only, else is regular speed | |
312 | : set-my-speed ( -- ) | |
313 | " low-speed" get-my-property ( true | adr len false ) | |
314 | if \ regular speed | |
315 | false | |
316 | else \ low speed | |
317 | 2drop true | |
318 | then | |
319 | to my-speed | |
320 | ; | |
321 | ||
322 | : set-my-addr ( -- ) | |
323 | " assigned-address" get-inherited-property ( true | addr len false ) | |
324 | if | |
325 | ." Unable to get assigned address for usb keyboard." cr | |
326 | true throw | |
327 | else | |
328 | decode-int to my-addr 2drop | |
329 | then | |
330 | ; | |
331 | ||
332 | : $>endpt ( addr len -- n ) \ this better work, no throw | |
333 | base @ >r hex | |
334 | dup if | |
335 | $number if \ XXX dreadfully wrong, no enpt # | |
336 | cr ." missing endpoint#" | |
337 | 1 \ XXX probably wrong here | |
338 | then | |
339 | else 2drop 1 \ default to endpt 1 | |
340 | then | |
341 | r> base ! | |
342 | ; | |
343 | ||
344 | : $>packet ( addr len -- n ) | |
345 | base @ >r hex | |
346 | dup if | |
347 | $number if \ XXX dreadfully wrong, no max-pkt# | |
348 | cr ." missing max-packet#" | |
349 | 8 \ Sun default | |
350 | then | |
351 | else 2drop 8 \ Sun default; seriously wrong | |
352 | then | |
353 | r> base ! | |
354 | ; | |
355 | ||
356 | \ read endpoints and max-packets | |
357 | : set-my-endpts ( -- ) | |
358 | " endpoints" get-inherited-property ( true | addr len false ) | |
359 | if | |
360 | ." Unable to get endpoints for usb keyboard." cr | |
361 | true throw | |
362 | else | |
363 | decode-string 2swap 2drop | |
364 | ascii , left-parse-string 2drop \ always 0, for my-endpt ( control ) | |
365 | ascii , left-parse-string 2drop \ could use for 0max-packet | |
366 | ascii , left-parse-string \ assume this is the interrupt endpt | |
367 | $>endpt h# f and \ XXX dumping direction for now | |
368 | to my-int-endpt | |
369 | ascii , left-parse-string \ its max-packet | |
370 | $>packet to my-int-max-packet | |
371 | 2drop ( ) \ dump any other endpts for now | |
372 | then | |
373 | ; | |
374 | ||
375 | : set-my-interface ( -- ) | |
376 | " interface#" get-my-property \ must be in my node | |
377 | if \ seriously wrong | |
378 | 0 \ Sun default | |
379 | else | |
380 | decode-int | |
381 | nip nip | |
382 | then | |
383 | to my-interface | |
384 | ; | |
385 | ||
386 | \ The country layout is determined in the open routine, and the | |
387 | \ keymap presence/correctness is determined at that time also. | |
388 | \ True is returned if everything is OK, otherwise false is returned. | |
389 | ||
390 | \ 0 instance value kbd-driver | |
391 | : install-device ( -- everything-ok? ) | |
392 | -1 our-ha-token ! 1 to ha-toggle | |
393 | ||
394 | set-my-0max-packet set-my-speed | |
395 | set-my-addr set-my-endpts | |
396 | set-my-interface | |
397 | ||
398 | init-kbd | |
399 | ||
400 | \ forced-keyboard-mode? or ( ok? ) | |
401 | ||
402 | 8 \ ms | |
403 | our-toggle \ toggle | |
404 | my-speed | |
405 | 0 \ dir = xfer from USB to host (us) | |
406 | my-int-max-packet | |
407 | 8 \ buf-len; max length for data being returned | |
408 | my-int-endpt \ endpoint | |
409 | my-addr \ usb-adr | |
410 | ( ms toggle low-speed? dir max-pkt buf-len endpoint usb-adr ) | |
411 | ||
412 | enable-int-transactions ( HAtoken ) | |
413 | ||
414 | dup if ( HAtoken ) | |
415 | our-ha-token ! true ( yes-ok ) | |
416 | else ( not-ok ) | |
417 | \ A returned token of 0 indicates that the HA wouldn't honor our | |
418 | \ request, meaning that one of the parameters is probably bogus. | |
419 | ." HostAdapter didn't honor keyboard enable-int-transactions." cr | |
420 | drop true throw | |
421 | then | |
422 | ; | |
423 | ||
424 | : alloc-vaddr-buffs ( -- ) | |
425 | /ctrl-pkt dma-alloc to set-prtcl-buff^v | |
426 | /ctrl-pkt dma-alloc to get-descr-buff^v | |
427 | /hid-descriptor dma-alloc to hid-descr-buff^v | |
428 | /key-info-buff dma-alloc to keybuff-curr^v | |
429 | /ctrl-pkt dma-alloc to std-pkt-buff^v | |
430 | 1 dma-alloc to 1-byte^v | |
431 | ; | |
432 | ||
433 | ||
434 | : dealloc-vaddr-buffs ( -- ) | |
435 | set-prtcl-buff^v /ctrl-pkt dma-free | |
436 | get-descr-buff^v /ctrl-pkt dma-free | |
437 | hid-descr-buff^v /hid-descriptor dma-free | |
438 | keybuff-curr^v /key-info-buff dma-free | |
439 | std-pkt-buff^v /ctrl-pkt dma-free | |
440 | 1-byte^v 1 dma-free | |
441 | ; |