These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / SLOF / board-qemu / slof / virtio-scsi.fs
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
15 FALSE CONSTANT virtio-scsi-debug
16
17 2 encode-int s" #address-cells" property
18 0 encode-int s" #size-cells" property
19
20 : decode-unit 2 hex64-decode-unit ;
21 : encode-unit 2 hex64-encode-unit ;
22
23 FALSE VALUE initialized?
24
25 virtio-setup-vd VALUE virtiodev
26
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
39
40 STRUCT \ 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
47 CONSTANT vs-req-length
48
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
55     60 FIELD vs-rsp>sense
56 CONSTANT vs-rsp-length
57
58 CREATE vs-req vs-req-length allot
59 CREATE vs-rsp vs-rsp-length allot
60
61 scsi-open
62
63 \ -----------------------------------------------------------
64 \ Perform SCSI commands
65 \ -----------------------------------------------------------
66
67 0 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     swap 0100 or 10 << or 20 <<
148 ;
149
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
152 \
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 -- )
156     lxjoin (set-target)
157 ;
158
159 100 CONSTANT #target
160 : dev-max-target ( -- #target )
161     #target
162 ;
163
164 " scsi-probe-helpers.fs" included
165
166 scsi-close        \ no further scsi words required
167
168 0 VALUE queue-control-addr
169 0 VALUE queue-event-addr
170 0 VALUE queue-cmd-addr
171
172 : setup-virt-queues
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
178
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
182
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
186 ;
187
188 \ Set scsi alias if none is set yet
189 : setup-alias
190     s" scsi" find-alias 0= IF
191         s" scsi" get-node node>path set-alias
192     ELSE
193         drop
194     THEN
195 ;
196
197 : shutdown ( -- )
198     initialized? IF
199        my-phandle node>path open-dev ?dup IF
200           virtiodev virtio-scsi-shutdown
201           close-dev
202        THEN
203        FALSE to initialized?
204     THEN
205 ;
206
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
210     my-self >r
211     dup to my-self
212     \ Scan the VSCSI bus:
213     virtiodev virtio-scsi-init
214     0= IF
215         setup-virt-queues
216         scsi-find-disks
217         setup-alias
218         TRUE to initialized?
219         ['] shutdown add-quiesce-xt
220     THEN
221     \ Close the temporary instance:
222     close-node
223     r> to my-self
224 ;
225
226 : virtio-scsi-add-disk
227     " scsi-disk.fs" included
228 ;
229
230 virtio-scsi-add-disk
231 virtio-scsi-init-and-scan