|
|
1.1 root 1: \ *****************************************************************************
2: \ * Copyright (c) 2004, 2008 IBM Corporation
3: \ * All rights reserved.
4: \ * This program and the accompanying materials
5: \ * are made available under the terms of the BSD License
6: \ * which accompanies this distribution, and is available at
7: \ * http://www.opensource.org/licenses/bsd-license.php
8: \ *
9: \ * Contributors:
10: \ * IBM Corporation - initial implementation
11: \ ****************************************************************************/
12:
13:
14: \ ----------------------------------------------------------------------------
15: \ On detection of a hub after reading the device descriptor this package has to
16: \ be called so that the hub enumeration is done to idenitify the down stream
17: \ device
18: \ --------------------------------------------------------------------------
19: \ OF properties
20: \ --------------------------------------------------------------------------
21:
22:
23: s" hub" device-name
24: s" usb" device-type
25: 1 encode-int s" #address-cells" property
26: 0 encode-int s" #size-cells" property
27:
28: \ converts physical address to text unit string
29:
30:
31: : encode-unit ( port-addr -- unit-str unit-len ) 1 hex-encode-unit ;
32:
33:
34: \ Converts text unit string to phyical address
35:
36:
37: : decode-unit ( addr len -- port-addr ) 1 hex-decode-unit ;
38:
39: 0 VALUE new-device-address
40: 0 VALUE port-number
41: 0 VALUE MPS-DCP
42: 0 VALUE mps
43: 0 VALUE my-usb-address
44:
45: 00 value device-speed
46:
47:
48: \ Get parameters passed from the parent.
49:
50: : mps-property-set ( -- )
51: s" HUB Compiling mps-property-set " usb-debug-print
52: s" USB-ADDRESS" get-my-property ( TRUE | prop-addr prop-len FALSE )
53: IF
54: s" notpossible" usb-debug-print
55: ELSE
56: decode-int nip nip to my-usb-address
57: THEN
58: s" MPS-DCP" get-my-property ( TRUE | prop-addr prop-len FALSE )
59: IF
60: s" MPS-DCP property not found Assuming 8 as MAX PACKET SIZE" ( str len )
61: usb-debug-print
62: s" for the default control pipe" usb-debug-print
63: 8 to MPS-DCP
64: ELSE
65: s" MPS-DCP property found!!" usb-debug-print ( prop-addr prop-len FALSE )
66: decode-int nip nip to MPS-DCP
67: THEN
68: ;
69:
70:
71: \ --------------------------------------------------------------------------
72: \ Constant declarations
73: \ --------------------------------------------------------------------------
74:
75:
76: 2303080000000000 CONSTANT hppwr-set
77: 2301080000000000 CONSTANT hppwr-clear
78: 2303040000000000 CONSTANT hprst-set
79: A300000000000400 CONSTANT hpsta-get
80: 2303010000000000 CONSTANT hpena-set
81: A006002900000000 CONSTANT hubds-get
82: 8 CONSTANT DEFAULT-CONTROL-MPS
83: 12 CONSTANT DEVICE-DESCRIPTOR-LEN
84: 9 CONSTANT CONFIG-DESCRIPTOR-LEN
85: 20 CONSTANT BULK-CONFIG-DESCRIPTOR-LEN
86:
87:
88: \ TODO:
89: \ CONFIG-DESCRIPTOR-LEN should be only 9. The interface
90: \ and endpoint descriptors returned along with config
91: \ descriptor are variable and 0x19 is a very wrong VALUE
92: \ to specify for this #define.
93:
94:
95: 1 CONSTANT DEVICE-DESCRIPTOR-TYPE
96: 1 CONSTANT DEVICE-DESCRIPTOR-TYPE-OFFSET
97: 4 CONSTANT DEVICE-DESCRIPTOR-DEVCLASS-OFFSET
98: 7 CONSTANT DEVICE-DESCRIPTOR-MPS-OFFSET
99: 9 CONSTANT HUB-DEVICE-CLASS
100: 0 CONSTANT NO-CLASS
101:
102:
103: \ --------------------------------------------------------------------------
104: \ Temporary Variable declarations
105: \ --------------------------------------------------------------------------
106:
107: 00 VALUE temp1
108: 00 VALUE temp2
109: 00 VALUE temp3
110: 00 VALUE po2pg \ Power On to Power Good
111:
112:
113: \ --------------------------------------------------------------------------
1.1.1.2 ! root 114: \ DMA buffer allocations
1.1 root 115: \ --------------------------------------------------------------------------
116:
1.1.1.2 ! root 117: : dma-alloc s" dma-alloc" $call-parent ;
! 118: : dma-map-in s" dma-map-in" $call-parent ;
! 119: : dma-map-out s" dma-map-out" $call-parent ;
! 120: : dma-free s" dma-free" $call-parent ;
1.1 root 121:
1.1.1.2 ! root 122:
! 123: 0 INSTANCE VALUE setup-packet \ 8 bytes for setup packet
! 124: 0 INSTANCE VALUE ch-buffer \ 1 byte character buffer
1.1 root 125:
126: INSTANCE VARIABLE dd-buffer
127: INSTANCE VARIABLE cd-buffer
128:
129: \ TODO:
130: \ Should arrive a proper value for the size of the "cd-buffer"
131:
1.1.1.2 ! root 132: STRUCT
! 133: 8 FIELD >setup-packet \ 8 bytes for setup packet
! 134: DEVICE-DESCRIPTOR-LEN FIELD >dd-buffer
! 135: BULK-CONFIG-DESCRIPTOR-LEN FIELD >cd-buffer
! 136: 8 chars FIELD >status-buffer
! 137: 9 chars FIELD >hd-buffer
! 138: 1 chars FIELD >ch-buffer \ character buffer
! 139: CONSTANT /hub-buf
1.1 root 140:
1.1.1.2 ! root 141: 0 INSTANCE VALUE hub-buf
! 142: 0 INSTANCE VALUE hub-buf-phys
1.1 root 143:
144: : (allocate-mem) ( -- )
1.1.1.2 ! root 145: /hub-buf dma-alloc TO hub-buf
! 146: hub-buf /hub-buf 0 dma-map-in TO hub-buf-phys
! 147:
! 148: hub-buf >setup-packet TO setup-packet
! 149: hub-buf >ch-buffer TO ch-buffer
! 150: hub-buf >dd-buffer dd-buffer !
! 151: hub-buf >cd-buffer cd-buffer !
! 152:
! 153: s" hub-buf = " hub-buf usb-debug-print-val
1.1 root 154: ;
155:
156:
157: : (de-allocate-mem) ( -- )
1.1.1.2 ! root 158: hub-buf hub-buf-phys /hub-buf dma-map-out
! 159: hub-buf /hub-buf dma-free
! 160: 0 TO hub-buf
! 161: 0 TO hub-buf-phys
! 162: 0 TO setup-packet
! 163: 0 TO ch-buffer
! 164: 0 dd-buffer !
! 165: 0 cd-buffer !
1.1 root 166: ;
167:
168:
169: \ standard open firmware methods
170:
171: : open ( -- TRUE )
172: (allocate-mem)
173: TRUE
174: ;
175:
176: : close ( -- )
177: (de-allocate-mem)
178: ;
179:
180:
181: \ --------------------------------------------------------------------------
182: \ Parent's method
183: \ --------------------------------------------------------------------------
184:
185:
186: : controlxfer ( dir addr dlen setup-packet MPS ep-fun -- TRUE|FALSE )
187: s" controlxfer" $call-parent
188: ;
189:
190: : control-std-set-address ( speedbit -- usb-address TRUE|FALSE )
191: s" control-std-set-address" $call-parent
192: ;
193:
194: : control-std-get-device-descriptor
195: ( data-buffer data-len MPS funcAddr -- TRUE|FALSE )
196: s" control-std-get-device-descriptor" $call-parent
197: ;
198:
199: : control-std-get-configuration-descriptor
200: ( data-buffer data-len MPS funcAddr -- TRUE|FALSE )
201: s" control-std-get-configuration-descriptor" $call-parent
202: ;
203:
204: : control-std-get-maxlun
205: ( MPS fun-addr dir data-buff data-len -- TRUE|FALSE )
206: s" control-std-get-maxlun" $call-parent
207: ;
208:
209: : control-std-set-configuration
210: ( configvalue FuncAddr -- TRUE|FALSE )
211: s" control-std-set-configuration" $call-parent
212: ;
213:
214: : control-std-get-string-descriptor
215: ( StringIndex data-buffer data-len MPS FuncAddr -- TRUE|FALSE )
216: s" control-std-get-string-descriptor" $call-parent
217: ;
218:
219: : rw-endpoint
220: ( pt ed-type toggle buffer length mps address -- toggle TRUE|toggle FALSE )
221: s" rw-endpoint" $call-parent
222: ;
223:
224: : debug-td ( -- )
225: s" debug-td" $call-parent
226: ;
227:
228: \ *** NEW ****
229: : control-bulk-reset ( MPS fun-addr dir data-buff data-len -- TRUE | FALSE )
230: s" control-bulk-reset" $call-parent
231: ;
232:
233:
234: \ --------------------------------------------------------------------------
235: \ HUB specific methods
236: \ --------------------------------------------------------------------------
237: \ To bring on the power on a valid port of a hub with a valid USB address
238: \ --------------------------------------------------------------------------
239:
240:
241: : control-hub-port-power-set ( port# -- TRUE|FALSE )
242: hppwr-set setup-packet ! ( port#)
243: setup-packet 4 + c!
244: 0 0 0 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE | FALSE )
245: ;
246:
247:
248: \ --------------------------------------------------------------------------
249: \ To put power off on ports where device detection or enumeration has failed
250: \ --------------------------------------------------------------------------
251:
252:
253: : control-hub-port-power-clear ( port#-- TRUE|FALSE )
254: hppwr-clear setup-packet ! ( port#)
255: setup-packet 4 + c!
256: 0 0 0 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE )
257: ;
258:
259:
260: \ -------------------------------------------------------------------------
261: \ To reset a valid port of a hub with a valid USB
262: \ address
263: \ --------------------------------------------------------------------------
264:
265:
266: : control-hub-port-reset-set ( port# -- TRUE|FALSE )
267: hprst-set setup-packet ! ( port# )
268: setup-packet 4 + c!
269: 0 0 0 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE )
270: ;
271:
272:
273: \ -------------------------------------------------------------------------
274: \ To enable a particular valid port of a hub with a valid USB address
275: \ -------------------------------------------------------------------------
276:
277:
278: : control-hub-port-enable ( port# -- TRUE|FALSE )
279: hpena-set setup-packet ! ( port# )
280: setup-packet 4 + c!
281: 0 0 0 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE )
282: ;
283:
284:
285: \ -------------------------------------------------------------------------
286: \ To get the status of a valid port of a hub with
287: \ a valid USB address
288: \ -------------------------------------------------------------------------
289:
290:
291: : control-hub-port-status-get ( buffer port# -- TRUE|FALSE )
292: hpsta-get setup-packet ! ( buffer port# )
293: setup-packet 4 + c! ( buffer )
294: 0 swap 4 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE )
295: ;
296:
297:
298: \ --------------------------------------------------------------------------
299: \ To get the hub descriptor to understand how many ports are vailable and the
300: \ specs of those ports
301: \ ---------------------------------------------------------------------------
302:
303:
304: : control-get-hub-descriptor ( buffer buffer-length -- TRUE|FALSE )
305: hubds-get setup-packet !
306: dup setup-packet 6 + w!-le ( buffer buffer-length )
307: 0 -rot setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE )
308: ;
309:
310:
311: s" usb-enumerate.fs" INCLUDED
312:
313:
314: : hub-configure-port ( port# -- )
315:
316: \ this port has been powered on
317: \ send reset to enable port and
318: \ start device detection by hub
319: \ some devices require a long timeout here (10s)
320:
321: \ Step 1: check if reset state ended
322:
323: BEGIN ( port# )
1.1.1.2 ! root 324: hub-buf >status-buffer 4 erase ( port# )
! 325: hub-buf >status-buffer over
! 326: control-hub-port-status-get drop ( port# )
! 327: hub-buf >status-buffer w@-le 102 and 0= ( port# TRUE|FALSE )
1.1 root 328: WHILE ( port# )
1.1.1.2 ! root 329: REPEAT ( port# )
1.1 root 330: po2pg 3 * ms \ wait for bPwrOn2PwrGood*3 ms
331:
332: \ STEP 2: Reset the port.
333: \ (this also enables the port)
334: dup control-hub-port-reset-set drop ( port# )
335: BEGIN ( port# )
1.1.1.2 ! root 336: hub-buf >status-buffer 4 erase ( port# )
! 337: hub-buf >status-buffer over
! 338: control-hub-port-status-get drop ( port# )
! 339: hub-buf >status-buffer w@-le 10 and ( port# TRUE|FALSE )
1.1 root 340: WHILE ( port# )
341: REPEAT ( port# )
342:
343: \ STEP 3: Check if a device is connected to the port.
344:
1.1.1.2 ! root 345: hub-buf >status-buffer 4 erase ( port# )
! 346: hub-buf >status-buffer over
! 347: control-hub-port-status-get drop ( port# )
! 348: hub-buf >status-buffer w@-le 103 and 103 <> ( port# TRUE|FALSE )
! 349: s" Port status bits: " hub-buf >status-buffer w@-le usb-debug-print-val
1.1 root 350: IF ( port# )
1.1.1.2 ! root 351: drop
1.1 root 352: s" Connect status: No device connected " usb-debug-print
353: EXIT
354: THEN
355:
356:
357: \ STEP 4: Assign an address to this device.
358:
1.1.1.2 ! root 359: hub-buf >status-buffer w@-le 200 and 4 lshift \ get speed bit
! 360: dup to device-speed \ store speed bit
1.1 root 361: ( port# speedbit )
362: control-std-set-address ( port# usb-addr TRUE|FALSE )
363: 50 ms ( port# usb-addr TRUE|FALSE )
364: debug-td ( port# usb-addr TRUE|FALSE )
365: IF ( port# usb-addr )
366: device-speed or ( port# usb-addr+speedbit )
367: to new-device-address ( port# )
368: to port-number
369: dd-buffer @ DEVICE-DESCRIPTOR-LEN erase
370: dd-buffer @ DEFAULT-CONTROL-MPS DEFAULT-CONTROL-MPS new-device-address
371: ( buffer mps mps usb-addr )
372: control-std-get-device-descriptor ( TRUE|FALSE )
373: IF
374: dd-buffer @ DEVICE-DESCRIPTOR-TYPE-OFFSET + c@ ( descriptor-type )
375: DEVICE-DESCRIPTOR-TYPE <> ( TRUE|FALSE )
376: IF
377: s" HUB: ERROR!! Invalid Device Descriptor for the new device"
378: usb-debug-print
379: ELSE
380: dd-buffer @ DEVICE-DESCRIPTOR-MPS-OFFSET + c@ to mps
381:
382: \ Re-read the device descriptor again with the known MPS.
383:
384: dd-buffer @ DEVICE-DESCRIPTOR-LEN erase
385: dd-buffer @ DEVICE-DESCRIPTOR-LEN mps new-device-address
386: ( buffer descp-len mps usb-addr )
387: \ s" DEVICE DESCRIPTOR: " usb-debug-print
388: control-std-get-device-descriptor invert
389: IF
390: s" ** reading dev-descriptor failed ** " usb-debug-print
391: THEN
392: create-usb-device-tree
393: THEN
394: ELSE
395: s" ERROR!! Failed to get device descriptor" usb-debug-print
396: THEN
397: ELSE ( port# )
398: s" USB Set Adddress failed!!" usb-debug-print ( port# )
399: s" Clearing Port Power..." usb-debug-print ( port# )
400: control-hub-port-power-clear ( TRUE|FALSE )
401: IF
402: s" Port power down " usb-debug-print
403: ELSE
404: s" Unable to clear port power!!!" usb-debug-print
405: THEN
406: THEN
407: ;
408:
409:
410: \ ---------------------------------------------------------------------------
411: \ To enumerate all the valid ports of hub
412: \ TODO:
413: \ 1. Remove hardcoded constants.
414: \ 2. Remove Endian Dependencies.
415: \ 3. Return values of controlxfer should be checked.
416: \ ---------------------------------------------------------------------------
417:
418: : hub-enumerate ( -- )
419: cd-buffer @ CONFIG-DESCRIPTOR-LEN erase
420:
421: \ Get HUB configuration and SET the configuration
422: \ note: remove hard-coded constants.
423:
424: cd-buffer @ CONFIG-DESCRIPTOR-LEN MPS-DCP my-usb-address
425: ( buffer descp-len mps usb-address )
426: control-std-get-configuration-descriptor drop
427: cd-buffer @ 1+ c@ 2 <> IF
428: s" Unable to read configuration descriptor" usb-debug-print
429: EXIT
430: THEN
431: cd-buffer @ 4 + c@ 1 <> IF
432: s" Not a valid HUB config descriptor" usb-debug-print
433: EXIT
434: THEN
435:
436: \ TODO: Do further checkings on the returned Configuration descriptor
437: \ before proceeding to accept it.
438:
439: cd-buffer @ 5 + c@ to temp1 \ Store the configuration in temp1
440: temp1 my-usb-address control-std-set-configuration drop
441: my-usb-address to temp1
1.1.1.2 ! root 442: hub-buf >hd-buffer 9 erase
! 443: hub-buf >hd-buffer 9 control-get-hub-descriptor drop
1.1 root 444:
445: \ PENDING: 1. Check Return value.
446: \ 2. HUB descriptor size is variable. Currently we r hardcoding
447: \ a value of 9.
448:
1.1.1.2 ! root 449: hub-buf >hd-buffer 2 + c@ to temp2 \ number of downstream ports
1.1 root 450:
451: s" HUB: Found " usb-debug-print
452: s" number of downstream hub ports! : " temp2 usb-debug-print-val
1.1.1.2 ! root 453: hub-buf >hd-buffer 5 + c@ to po2pg \ get bPwrOn2PwrGood
1.1 root 454:
455: \ power on all present hub ports
456: \ to allow slow devices to set up
457:
458: temp2 1+ 1 DO
459: i control-hub-port-power-set drop
460: d# 20 ms
461: LOOP
462:
463: d# 200 ms \ some devices need a long time (10s)
464:
465: \ now start detection and configuration for these ports
466:
467: temp2 1+ 1 DO
468: s" hub-configure-port: " i usb-debug-print-val
469: i hub-configure-port
470: LOOP
471: ;
472:
473:
474: \ --------------------------------------------------------------------------
475: \ To initialize hub
476: \ --------------------------------------------------------------------------
477:
478: (allocate-mem)
479: mps-property-set
480: hub-enumerate
481: (de-allocate-mem)
482:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.