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
10 \ * IBM Corporation - initial implementation
11 \ ****************************************************************************/
13 ." Populating " pwd cr
15 FALSE CONSTANT virtio-scsi-debug
17 2 encode-int s" #address-cells" property
18 0 encode-int s" #size-cells" property
20 : decode-unit 2 hex64-decode-unit ;
21 : encode-unit 2 hex64-encode-unit ;
23 FALSE VALUE initialized?
25 virtio-setup-vd VALUE virtiodev
27 STRUCT \ 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
38 CONSTANT vs-cfg-length
40 STRUCT \ virtio-scsi-req
43 /c FIELD vs-req>task-attr
47 CONSTANT vs-req-length
49 STRUCT \ 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
56 CONSTANT vs-rsp-length
58 CREATE vs-req vs-req-length allot
59 CREATE vs-rsp vs-rsp-length allot
63 \ -----------------------------------------------------------
64 \ Perform SCSI commands
65 \ -----------------------------------------------------------
67 0 INSTANCE VALUE current-target
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
74 \ Note: stat is -1 for "hw error" (ie, error queuing the command or
75 \ getting the response).
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
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
87 \ Populate the request
88 current-target vs-req vs-req>lun x!
89 vs-req vs-req>cdb swap move
92 vs-req vs-rsp virtiodev
96 ." VIRTIO-SCSI: Queuing failure !" cr
100 \ Check virtio response
101 vs-rsp vs-rsp>response c@ CASE
103 5 OF drop 0 0 8 EXIT ENDOF \ Busy
104 dup OF 0 0 -1 EXIT ENDOF \ Anything else -> HW error
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
115 vs-rsp vs-rsp>sense swap
117 over scsi-get-sense-data
118 ." VIRTIO-SCSI: Sense key [ " dup . ." ] " .sense-text
119 ." ASC,ASCQ: " . . cr
125 \ --------------------------------
126 \ Include the generic host helpers
127 \ --------------------------------
129 " scsi-host-helpers.fs" included
131 \ FIXME: Check max transfer coming from virtio config
132 : max-transfer ( -- n )
133 10000 \ Larger value seem to have problems with some CDROMs
136 \ -----------------------------------------------------------
137 \ SCSI scan at boot and child device support
138 \ -----------------------------------------------------------
140 \ We use SRP luns of the form 01000000 | (target << 16) | lun
141 \ in the top 32 bits of the 64-bit LUN
146 : dev-generate-srplun ( target lun-id -- srplun )
147 swap 0100 or 10 << or 20 <<
150 \ We obtain here a unit address on the stack, since our #address-cells
151 \ is 2, the 64-bit srplun is split in two cells that we need to join
153 \ Note: This diverges a bit from the original OF scsi spec as the two
154 \ cells are the 2 words of a 64-bit SRP LUN
155 : set-address ( srplun.lo srplun.hi -- )
160 : dev-max-target ( -- #target )
164 " scsi-probe-helpers.fs" included
166 scsi-close \ no further scsi words required
168 0 VALUE queue-control-addr
169 0 VALUE queue-event-addr
170 0 VALUE queue-cmd-addr
173 \ add 3 queues 0-controlq, 1-eventq, 2-cmdq
174 \ fixme: do we need to find more than the above 3 queues if exists
175 virtiodev 0 virtio-get-qsize virtio-vring-size
176 alloc-mem to queue-control-addr
177 virtiodev 0 queue-control-addr virtio-set-qaddr
179 virtiodev 1 virtio-get-qsize virtio-vring-size
180 alloc-mem to queue-event-addr
181 virtiodev 1 queue-event-addr virtio-set-qaddr
183 virtiodev 2 virtio-get-qsize virtio-vring-size
184 alloc-mem to queue-cmd-addr
185 virtiodev 2 queue-cmd-addr virtio-set-qaddr
188 \ Set scsi alias if none is set yet
190 s" scsi" find-alias 0= IF
191 s" scsi" get-node node>path set-alias
199 my-phandle node>path open-dev ?dup IF
200 virtiodev virtio-scsi-shutdown
203 FALSE to initialized?
207 : virtio-scsi-init-and-scan ( -- )
208 \ Create instance for scanning:
209 0 0 get-node open-node ?dup 0= IF ." exiting " cr EXIT THEN
212 \ Scan the VSCSI bus:
213 virtiodev virtio-scsi-init
219 ['] shutdown add-quiesce-xt
221 \ Close the temporary instance:
226 : virtio-scsi-add-disk
227 " scsi-disk.fs" included
231 virtio-scsi-init-and-scan