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\ Citrine storage controller. 152dup type 16 17device-name s" ide" device-type 18 19 203 encode-int s" #address-cells" property 210 encode-int s" #size-cells" property 22 23: decode-unit 3 hex-decode-unit ; 24: encode-unit 3 hex-encode-unit ; 25 26 27: >ioa [ 10 config-l@ -10 and ] LITERAL + ; 28: ioa@ >ioa rl@-le ; 29: ioa! >ioa rl!-le ; 30 31 32\ Clear request completion doorbell. 332 228 ioa! 34 35\ status 36CREATE ioasa 200 allot ioasa 200 erase \ can reduce to 8 later 37 38\ request/response queue 39CREATE rrq 100 allot rrq 100 erase \ can be smaller 40 41\ data descriptor 42CREATE ioadl 8 allot 43 44\ control block 45CREATE ioarcb 80 allot ioarcb 80 erase 46ioarcb dup l! 4760708090 ioarcb c + l! \ user handle 48ioadl ioarcb 2c + l! \ read ioadl 49ioasa ioarcb 34 + l! 200 ioarcb 38 + w! 50 51\ ioa config data (max. 16 devices) 52CREATE ioacfg 404 allot ioacfg 404 erase 53CREATE setsupbuff 2c allot 54 setsupbuff 2c erase 55 2c setsupbuff w! 56 1 setsupbuff 3 + c! 57 58: wait-ready ( -- ) 59 82800000 214 ioa! 60 80000000 BEGIN dup 224 ioa@ cr .s dup 8000000 and IF 61 cr ." Unit check on SAS-Controller detected" 62 cr 42c ioa@ . 63 8 110 ioa! 64 BEGIN cr 0 config-l@ dup . ffffffff <> UNTIL 65\ ABORT" Unit check on SAS-Controller detected" 66 THEN 67 and 68 UNTIL drop 69; 70 71\ wait-ready 72 73: wait-ioa ( int-mask -- ) BEGIN dup 224 ioa@ and UNTIL drop ; 74: init-ioa ( -- ) 82800000 214 ioa! 80000000 wait-ioa ; 75: do-request ( -- ) ioasa 20 erase ioarcb 404 ioa! 76 2 wait-ioa 2 228 ioa! 77; 78 79: setup-ioarcb ( rsrc type addr len -- ) 80 tuck 49000000 or ioadl l! ioadl 4 + l! \ setup ioadl 81 ioarcb 20 + l! ioadl ioarcb 2c + l! 8 ioarcb 30 + l! \ set len, ioadl addr 82 ioarcb 3e + c! ioarcb 8 + l! \ set type and resource 83 ioarcb 40 + 40 erase ; 84 85: setup-wrioarcb ( rsrc type addr len -- ) 86 tuck 49000000 or ioadl l! ioadl 4 + l! \ setup ioadl 87 ioarcb 1C + l! ioadl ioarcb 24 + l! 8 ioarcb 28 + l! \ set len, ioadl addr 88 ioarcb 3e + c! ioarcb 8 + l! \ set type and resource 89 ioarcb 40 + 40 erase ; 90 91: setup-idrrq ( rrq len -- ) 92 c4 ioarcb 42 + c! 8 lshift ioarcb 48 + l! ioarcb 44 + l! ; 93: do-idrrq ( -- ) -1 1 0 0 setup-ioarcb rrq 100 setup-idrrq do-request ; 94 95: setup-query ( len -- ) c5 ioarcb 42 + c! 8 lshift ioarcb 48 + l! ; 96: do-query ( -- ) -1 1 ioacfg 404 setup-ioarcb 404 setup-query do-request ; 97 98: setup-startUnit ( -- ) 1b ioarcb 42 + c! 3 ioarcb 46 + c! ; 99: do-startUnit ( hndl -- ) 0 0 0 setup-ioarcb setup-startUnit do-request ; 100 101: setup-setsupported ( len -- ) 80 ioarcb 40 + c! fb ioarcb 42 + c! 8 lshift ioarcb 48 + l! ; 102: do-setsupported ( -- ) -1 1 setsupbuff 2c setup-wrioarcb 2c setup-setsupported do-request ; 103 104\ ******************************** 105\ read capacity 106\ ******************************** 107CREATE cap 8 allot 108 109: setup-cap ( -- ) 25 ioarcb 42 + c! cap 8 erase ; 110: do-cap ( rsrc addr -- ) 111 >r 0 r> 8 setup-ioarcb setup-cap do-request ; 112 113: .id ( id -- ) ." @" lwsplit 2 0.r ." ," wbsplit 2 0.r ." ," 2 0.r ; 114 115: .cap ( rsrc -- ) 116 cap do-cap cap l@ cap 4 + l@ * d# 50000000 + d# 100000000 / 117 base @ >r decimal d# 10 /mod 4 .r ." ." 0 .r ." GB" r> base ! ; 118 119\ ******************************** 120\ Test Unit Ready 121\ ******************************** 122: setup-test-unit-ready ( -- ) 123 00 ioarcb 42 + c! \ SCSI cmd: Test-Unit-Ready 124; 125 126: do-test-unit-ready ( rsrc -- ) 127 0 0 0 setup-ioarcb ( rsrc type addr len -- ) 128 setup-test-unit-ready 129 do-request 130; 131 132\ ******************************** 133\ Check devices 134\ ******************************** 135: check-device ( ioacfg-entry -- ) 136 dup 2 + w@ 2001 and 0<> \ generic or raid disk 137 IF \ is an IOA resource ? 138 dup 8 + l@ ( ioacfg-entry rsrc ) \ get resource handle 139 8 0 140 DO ( ioacfg-entry rsrc ) 141 dup do-test-unit-ready ( ioacfg-entry rsrc ) 142 ioasa l@ 0= \ read returned status 143 IF 144 LEAVE 145 THEN 146 LOOP 147 drop ( ioacfg-entry ) 148 THEN 149 drop ( ) 150; 151 152: check-devices ( -- ) 153 ioacfg 4 + ( ioacfg-entry ) \ config block for 16 devices 154 ioacfg c@ 0 \ amount of detected devices 155 ?DO 156 dup 157 check-device ( ioacfg-entry ) 158 40 + 159 LOOP 160 drop 161; 162 163\ ******************************** 164\ Show Devices 165\ ******************************** 166: show-device ( ioacfg-entry -- ) 167 cr ." " dup 2 + w@ 168 dup 8000 and IF ." Controller :" THEN 169 dup 2000 and IF ." Disk (RAID Member):" THEN 170 dup 0002 and IF ." Disk (Volume Set) :" THEN 171 0001 and IF ." Disk (Generic) :" THEN 172 space dup 4 + l@ ffffff and dup ffffff <> IF 173 .id 174 ELSE drop 9 spaces THEN space 175 dup 1c + 8 type space dup 24 + 10 type 176 dup 2 + w@ 8000 and 0= IF 177 space dup 8 + l@ .cap 178 THEN drop 179; 180 181: show-devices ( -- ) 182 ioacfg 4 + ioacfg c@ 0 183 ?DO dup show-device 40 + LOOP drop 184; 185 186: setup-read ( lba len -- ) \ len is in blocks 187 28 ioarcb 42 + c! 188 swap ioarcb 44 + l! 189 8 lshift ioarcb 48 + l! 190; 191 192: do-read ( hndl lba len addr -- ) \ len is in blocks 193 over >r rot >r swap 0 -rot 200 * ( 0 hndl addr len* ) 194 setup-ioarcb r> r> ( lba len ) 195 setup-read do-request 196; 197 198: make-subnode ( rsrc-type rsrc-handle id -- ) 199 rot 2 and IF \ only device which are part of a RAID should be started 200 over do-startUnit \ at least on citrine there are problems starting 201 \ Generic SCSI devices 202 THEN do-setsupported 203 dup ffffff <> IF 204 \ we need max-#blocks for citrine-disk.fs 205 ( rsrc id ) 206 over cap do-cap cap l@ ( rsrc id max-#blocks ) 207 swap rot swap ( max-#block rsrc id ) \ this is what citrine-disk.fs expects... 208 s" citrine-disk.fs" included 209 ELSE 210 2drop 211 THEN 212; 213 214: make-subnodes ( -- ) 215 ioacfg 4 + ioacfg c@ 0 ?DO dup 2 + w@ dup ( ioacfg rsrc-type rsrc-type ) 216 A000 \ 8000 = Resource Subtype is IOA Focal Point. 217 \ 2000 = Device is a member of a data redundancy group (eg. RAID). 218 \ (1000 = Device is designated for use as a hot spare. 219 \ Unfortunately obsidian reports disk which are not part of 220 \ of a RAID also as hot space even if they are not.) 221 \ all these devices should not appeat in DT 222 \ SIS40 page 60 223 and 0= IF 224 swap dup ( rsrc-type ioacfg ioacfg ) 225 8 + l@ over 4 + l@ ( rsrc-type ioacfg rsrc-handle rsrc-addr ) 226 ffffff and 2swap swap 2swap ( ioacfg rsrc-type rsrc-handle rsrc-addr ) 227 make-subnode ELSE drop THEN 40 + LOOP drop ; 228 229: do-it ( -- ) 230 init-ioa do-idrrq 231 do-query 232 check-devices 233 show-devices 234; 235 236: setup-shutdown ( -- ) 237 f7 ioarcb 42 + c! 0 ioarcb 48 + l! 0 ioarcb 44 + l! ; 238: do-shutdown ( -- ) -1 1 0 0 setup-ioarcb setup-shutdown do-request ; 239 240: open true ; 241: close ; 242 243: start ['] do-it CATCH IF cr ." Citrine disabled" ELSE make-subnodes THEN ; 244 245cr start cr cr 246