1\ ***************************************************************************** 2\ * Copyright (c) 2012 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." Populating " pwd cr 14 15FALSE CONSTANT virtio-scsi-debug 16 172 encode-int s" #address-cells" property 180 encode-int s" #size-cells" property 19 20: decode-unit 2 hex64-decode-unit ; 21: encode-unit 2 hex64-encode-unit ; 22 23FALSE VALUE initialized? 24 25virtio-setup-vd VALUE virtiodev 26 27STRUCT \ virtio-scsi-config 28 /l FIELD vs-cfg>num-queues 29 /l FIELD vs-cfg>seg-max 30 /l FIELD vs-cfg>max-sectors 31 /l FIELD vs-cfg>cmd-per-lun 32 /l FIELD vs-cfg>event-info-size 33 /l FIELD vs-cfg>sense_size 34 /l FIELD vs-cfg>cdb-size 35 /w FIELD vs-cfg>max-channel 36 /w FIELD vs-cfg>max-target 37 /l FIELD vs-cfg>max-lun 38CONSTANT vs-cfg-length 39 40STRUCT \ virtio-scsi-req 41 8 FIELD vs-req>lun 42 8 FIELD vs-req>tag 43 /c FIELD vs-req>task-attr 44 /c FIELD vs-req>prio 45 /c FIELD vs-req>crn 46 20 FIELD vs-req>cdb 47CONSTANT vs-req-length 48 49STRUCT \ virtio-scsi-resp 50 /l FIELD vs-rsp>sense-len 51 /l FIELD vs-rsp>residual 52 /w FIELD vs-rsp>status-qualifier 53 /c FIELD vs-rsp>status 54 /c FIELD vs-rsp>response 55 60 FIELD vs-rsp>sense 56CONSTANT vs-rsp-length 57 58CREATE vs-req vs-req-length allot 59CREATE vs-rsp vs-rsp-length allot 60 61scsi-open 62 63\ ----------------------------------------------------------- 64\ Perform SCSI commands 65\ ----------------------------------------------------------- 66 670 INSTANCE VALUE current-target 68 69\ SCSI command. We do *NOT* implement the "standard" execute-command 70\ because that doesn't have a way to return the sense buffer back, and 71\ we do have auto-sense with some hosts. Instead we implement a made-up 72\ do-scsi-command. 73\ 74\ Note: stat is -1 for "hw error" (ie, error queuing the command or 75\ getting the response). 76\ 77\ A sense buffer is returned whenever the status is non-0 however 78\ if sense-len is 0 then no sense data is actually present 79\ 80 81: execute-scsi-command ( buf-addr buf-len dir cmd-addr cmd-len -- ... ) 82 ( ... [ sense-buf sense-len ] stat ) 83 \ Cleanup virtio request and response 84 vs-req vs-req-length erase 85 vs-rsp vs-rsp-length erase 86 87 \ Populate the request 88 current-target vs-req vs-req>lun x! 89 vs-req vs-req>cdb swap move 90 91 \ Send it 92 vs-req vs-rsp virtiodev 93 virtio-scsi-send 94 95 0 <> IF 96 ." VIRTIO-SCSI: Queuing failure !" cr 97 0 0 -1 EXIT 98 THEN 99 100 \ Check virtio response 101 vs-rsp vs-rsp>response c@ CASE 102 0 OF ENDOF \ Good 103 5 OF drop 0 0 8 EXIT ENDOF \ Busy 104 dup OF 0 0 -1 EXIT ENDOF \ Anything else -> HW error 105 ENDCASE 106 107 \ Other error status 108 vs-rsp vs-rsp>status c@ dup 0<> IF 109 vs-rsp vs-rsp>sense-len l@ dup 0= IF 110 \ This relies on auto-sense from qemu... if that isn't always the 111 \ case we should request sense here 112 ." VIRTIO-SCSI: No sense data" cr 113 0 EXIT 114 THEN 115 vs-rsp vs-rsp>sense swap 116 virtio-scsi-debug IF 117 over scsi-get-sense-data 118 ." VIRTIO-SCSI: Sense key [ " dup . ." ] " .sense-text 119 ." ASC,ASCQ: " . . cr 120 THEN 121 rot 122 THEN 123; 124 125\ -------------------------------- 126\ Include the generic host helpers 127\ -------------------------------- 128 129" scsi-host-helpers.fs" included 130 131\ FIXME: Check max transfer coming from virtio config 132: max-transfer ( -- n ) 133 10000 \ Larger value seem to have problems with some CDROMs 134; 135 136\ ----------------------------------------------------------- 137\ SCSI scan at boot and child device support 138\ ----------------------------------------------------------- 139 140\ We use SRP luns of the form 01000000 | (target << 16) | lun 141\ in the top 32 bits of the 64-bit LUN 142: (set-target) 143 to current-target 144; 145 146: dev-generate-srplun ( target lun-id -- srplun ) 147 dup ff > IF 4000 or THEN \ Use the LUN "flat space addressing method" 148 swap 0100 or 10 << or 20 << 149; 150 151\ We obtain here a unit address on the stack, since our #address-cells 152\ is 2, the 64-bit srplun is split in two cells that we need to join 153\ 154\ Note: This diverges a bit from the original OF scsi spec as the two 155\ cells are the 2 words of a 64-bit SRP LUN 156: set-address ( srplun.lo srplun.hi -- ) 157 lxjoin (set-target) 158; 159 160100 CONSTANT #target 161: dev-max-target ( -- #target ) 162 #target 163; 164 165" scsi-probe-helpers.fs" included 166 167scsi-close \ no further scsi words required 168 169\ Set scsi alias if none is set yet 170: setup-alias 171 s" scsi" find-alias 0= IF 172 s" scsi" get-node node>path set-alias 173 ELSE 174 drop 175 THEN 176; 177 178: shutdown ( -- ) 179 initialized? IF 180 my-phandle node>path open-dev ?dup IF 181 virtiodev virtio-scsi-shutdown 182 close-dev 183 THEN 184 FALSE to initialized? 185 THEN 186; 187 188: virtio-scsi-init-and-scan ( -- ) 189 \ Create instance for scanning: 190 0 0 get-node open-node ?dup 0= IF ." exiting " cr EXIT THEN 191 my-self >r 192 dup to my-self 193 \ Scan the VSCSI bus: 194 virtiodev virtio-scsi-init 195 0= IF 196 scsi-find-disks 197 setup-alias 198 TRUE to initialized? 199 ['] shutdown add-quiesce-xt 200 THEN 201 \ Close the temporary instance: 202 close-node 203 r> to my-self 204; 205 206: virtio-scsi-add-disk 207 " scsi-disk.fs" included 208; 209 210virtio-scsi-add-disk 211virtio-scsi-init-and-scan 212