1
\ *****************************************************************************
2
\ * Copyright (c) 2011 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
\ ****************************************************************************/
15
0 CONSTANT vscsi-debug
19
\ -----------------------------------------------------------
20
\ Direct DMA conversion hack
21
\ -----------------------------------------------------------
22
: l2dma ( laddr - dma_addr)
25
\ -----------------------------------------------------------
26
\ CRQ related functions
27
\ -----------------------------------------------------------
32
1000 CONSTANT CRQ-SIZE
37
\ XXX We rely on SLOF alloc-mem being aligned
38
CRQ-SIZE alloc-mem to crq-base 0 to crq-offset
39
crq-base l2dma to crq-dma
43
vscsi-unit hv-free-crq
44
crq-base CRQ-SIZE free-mem 0 to crq-base
48
\ Allocate CRQ. XXX deal with fail
52
." VSCSI: allocated crq at " crq-base . cr
56
crq-base CRQ-SIZE erase
59
vscsi-unit crq-dma CRQ-SIZE hv-reg-crq
63
." VSCSI: Error " . ." registering CRQ !" cr
69
crq-base 0 = IF EXIT THEN
72
." VSCSI: freeing crq at " crq-base . cr
77
: crq-send ( msgaddr -- true | false )
78
vscsi-unit swap hv-send-crq 0 =
81
: crq-poll ( -- true | false)
82
crq-offset crq-base + dup
84
." VSCSI: crq poll " dup .
93
crq-offset 10 + dup CRQ-SIZE >= IF drop 0 THEN to crq-offset
98
: crq-wait ( -- true | false)
100
0 BEGIN drop crq-poll dup not WHILE d# 1 ms REPEAT
102
." VSCSI: Timeout waiting response !" cr EXIT
105
." VSCSI: got crq: " crq dup l@ . ." " 4 + dup l@ . ." "
106
4 + dup l@ . ." " 4 + l@ . cr
111
\ -----------------------------------------------------------
112
\ CRQ encapsulated SRP definitions
113
\ -----------------------------------------------------------
115
01 CONSTANT VIOSRP_SRP_FORMAT
116
02 CONSTANT VIOSRP_MAD_FORMAT
117
03 CONSTANT VIOSRP_OS400_FORMAT
118
04 CONSTANT VIOSRP_AIX_FORMAT
119
06 CONSTANT VIOSRP_LINUX_FORMAT
120
07 CONSTANT VIOSRP_INLINE_FORMAT
125
1 field >crq-reserved
129
8 field >crq-iu-data-ptr
132
: srp-send-crq ( addr len -- )
134
VIOSRP_SRP_FORMAT crq >crq-format c!
135
0 crq >crq-reserved c!
137
0 crq >crq-timeout w!
138
( len ) crq >crq-iu-len w!
139
( addr ) l2dma crq >crq-iu-data-ptr x!
142
." VSCSI: Error sending CRQ !" cr
146
: srp-wait-crq ( -- [tag true] | false )
147
crq-wait not IF false EXIT THEN
149
crq >crq-format c@ VIOSRP_SRP_FORMAT <> IF
150
." VSCSI: Unsupported SRP response: "
151
crq >crq-format c@ . cr
155
crq >crq-iu-data-ptr x@ true
158
\ Add scsi functions to dictionary
162
\ -----------------------------------------------------------
164
\ -----------------------------------------------------------
168
00 CONSTANT SRP_LOGIN_REQ
169
01 CONSTANT SRP_TSK_MGMT
171
03 CONSTANT SRP_I_LOGOUT
172
c0 CONSTANT SRP_LOGIN_RSP
174
c2 CONSTANT SRP_LOGIN_REJ
175
80 CONSTANT SRP_T_LOGOUT
176
81 CONSTANT SRP_CRED_REQ
177
82 CONSTANT SRP_AER_REQ
178
41 CONSTANT SRP_CRED_RSP
179
42 CONSTANT SRP_AER_RSP
181
02 CONSTANT SRP_BUF_FORMAT_DIRECT
182
04 CONSTANT SRP_BUF_FORMAT_INDIRECT
185
1 field >srp-login-opcode
187
8 field >srp-login-tag
188
4 field >srp-login-req-it-iu-len
190
2 field >srp-login-req-buf-fmt
191
1 field >srp-login-req-flags
193
10 field >srp-login-init-port-ids
194
10 field >srp-login-trgt-port-ids
198
1 field >srp-lresp-opcode
200
4 field >srp-lresp-req-lim-delta
201
8 field >srp-lresp-tag
202
4 field >srp-lresp-max-it-iu-len
203
4 field >srp-lresp-max-ti-iu-len
204
2 field >srp-lresp-buf-fmt
205
1 field >srp-lresp-flags
206
constant /srp-login-resp
209
1 field >srp-lrej-opcode
211
4 field >srp-lrej-reason
212
8 field >srp-lrej-tag
214
2 field >srp-lrej-buf-fmt
215
constant /srp-login-rej
217
00 CONSTANT SRP_NO_DATA_DESC
218
01 CONSTANT SRP_DATA_DESC_DIRECT
219
02 CONSTANT SRP_DATA_DESC_INDIRECT
222
1 field >srp-cmd-opcode
223
1 field >srp-cmd-sol-not
225
1 field >srp-cmd-buf-fmt
226
1 field >srp-cmd-dout-desc-cnt
227
1 field >srp-cmd-din-desc-cnt
232
1 field >srp-cmd-task-attr
234
1 field >srp-cmd-add-cdb-len
235
10 field >srp-cmd-cdb
236
0 field >srp-cmd-cdb-add
240
1 field >srp-rsp-opcode
241
1 field >srp-rsp-sol-not
243
4 field >srp-rsp-req-lim-delta
246
1 field >srp-rsp-flags
247
1 field >srp-rsp-status
248
4 field >srp-rsp-dout-res-cnt
249
4 field >srp-rsp-din-res-cnt
250
4 field >srp-rsp-sense-len
251
4 field >srp-rsp-resp-len
252
0 field >srp-rsp-data
255
\ Storage for up to 256 bytes SRP request */
259
: srp-prep-cmd-nodata ( id lun -- )
261
SRP_CMD srp >srp-cmd-opcode c!
262
1 srp >srp-cmd-tag x!
263
srp >srp-cmd-lun 1 + c! \ lun
264
80 or \ select logical unit addressing method
265
srp >srp-cmd-lun c! \ id
269
: srp-prep-cmd-io ( addr len id lun -- )
270
srp-prep-cmd-nodata ( addr len )
271
swap l2dma ( len dmaaddr )
272
srp srp-len + ( len dmaaddr descaddr )
273
dup >r x! r> 8 + ( len descaddr+8 )
274
dup 0 swap l! 4 + ( len descaddr+c )
276
srp-len 10 + to srp-len
279
: srp-prep-cmd-read ( addr len id lun -- )
281
01 srp >srp-cmd-buf-fmt c! \ in direct buffer
282
1 srp >srp-cmd-din-desc-cnt c!
285
: srp-prep-cmd-write ( addr len id lun -- )
287
10 srp >srp-cmd-buf-fmt c! \ out direct buffer
288
1 srp >srp-cmd-dout-desc-cnt c!
291
: srp-send-cmd ( -- )
293
." VSCSI: Sending SCSI cmd " srp >srp-cmd-cdb c@ . cr
295
srp srp-len srp-send-crq
298
: srp-rsp-find-sense ( -- addr )
299
\ XXX FIXME: Always in same position
303
: srp-wait-rsp ( -- true | [ ascq asc sense-key false ] )
304
srp-wait-crq not IF false EXIT THEN
306
." VSCSI: Invalid CRQ response tag, want 1 got " . cr
310
srp >srp-rsp-tag x@ dup 1 <> IF
311
." VSCSI: Invalid SRP response tag, want 1 got " . cr
315
srp >srp-rsp-status c@
317
." VSCSI: Got response status: "
325
." VSCSI: Sense key: " dup .sense-text cr
333
\ -----------------------------------------------------------
335
\ -----------------------------------------------------------
337
CREATE sector d# 512 allot
339
0 INSTANCE VALUE current-id
340
0 INSTANCE VALUE current-lun
342
\ SCSI test-unit-read
343
: test-unit-ready ( -- true | [ ascq asc sense-key false ] )
344
current-id current-lun srp-prep-cmd-nodata
345
srp >srp-cmd-cdb scsi-build-test-unit-ready
350
: inquiry ( -- true | false )
351
\ WARNING: ATAPI devices with libata seem to ignore the MSB of
352
\ the allocation length... let's only ask for ff bytes
353
sector ff current-id current-lun srp-prep-cmd-read
354
ff srp >srp-cmd-cdb scsi-build-inquiry
357
dup not IF nip nip nip EXIT THEN \ swallow sense
360
: read-capacity ( -- true | false )
361
sector scsi-length-read-cap-10 current-id current-lun srp-prep-cmd-read
362
srp >srp-cmd-cdb scsi-build-read-cap-10
365
dup not IF nip nip nip EXIT THEN \ swallow sense
368
: start-stop-unit ( state# -- true | false )
369
current-id current-lun srp-prep-cmd-nodata
370
srp >srp-cmd-cdb scsi-build-start-stop-unit
373
dup not IF nip nip nip EXIT THEN \ swallow sense
376
: get-media-event ( -- true | false )
377
sector scsi-length-media-event current-id current-lun srp-prep-cmd-read
378
srp >srp-cmd-cdb scsi-build-get-media-event
381
dup not IF nip nip nip EXIT THEN \ swallow sense
384
: read-blocks ( -- addr block# #blocks blksz -- [ #read-blocks true ] | false )
385
over * ( addr block# #blocks len )
386
>r rot r> ( block# #blocks addr len )
388
2dup current-id current-lun
389
srp-prep-cmd-read ( block# #blocks addr len )
390
2swap ( addr len block# #blocks )
391
2dup srp >srp-cmd-cdb scsi-build-read-10 ( addr len block# #blocks )
392
2swap ( block# #blocks addr len )
395
IF 2drop nip true UNLOOP EXIT THEN
396
srp >srp-rsp-status c@ 8 <> IF
397
nip nip nip 2drop 2drop false EXIT
407
\ ." VSCSI: Cleaning up" cr
409
\ Disable TCE bypass:
410
vscsi-unit 0 rtas-set-tce-bypass
413
\ Initialize our vscsi instance
414
: vscsi-init ( -- true | false )
415
." VSCSI: Initializing" cr
417
\ Can't use my-unit bcs we aren't instanciating (fix this ?)
418
" reg" get-node get-package-property IF
419
." VSCSI: Not reg property !!!" 0
421
decode-int to vscsi-unit 2drop
423
\ Enable TCE bypass special qemu feature
424
vscsi-unit 1 rtas-set-tce-bypass
427
crq-init 0 <> IF false EXIT THEN
430
" "(C0 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00)" drop
432
." VSCSI: Error sending init command"
433
crq-cleanup false EXIT
438
crq-cleanup false EXIT
442
crq c@ c0 <> crq 1 + c@ 02 <> or IF
443
." VSCSI: Initial handshake failed"
444
crq-cleanup false EXIT
447
\ We should now login etc.. but we really don't need to
448
\ with our qemu model
450
\ Ensure we cleanup after booting
451
['] vscsi-cleanup add-quiesce-xt
456
\ -----------------------------------------------------------
457
\ SCSI scan at boot and child device support
458
\ -----------------------------------------------------------
460
: set-address ( lun id -- )
461
to current-id to current-lun
464
: dev-max-transfer ( -- n )
465
10000 \ Larger value seem to have problems with some CDROMs
468
: dev-get-capacity ( -- blocksize #blocks )
469
\ Make sure that there are zeros in the buffer in case something goes wrong:
471
\ Now issue the read-capacity command
475
sector scsi-get-capacity-10
478
: dev-read-blocks ( -- addr block# #blocks blksize -- #read-blocks )
482
: initial-test-unit-ready ( -- true | [ ascq asc sense-key false ] )
486
test-unit-ready dup IF UNLOOP EXIT THEN
490
: compare-sense ( ascq asc key ascq2 asc2 key2 -- true | false )
491
3 pick = ( ascq asc key ascq2 asc2 keycmp )
492
swap 4 pick = ( ascq asc key ascq2 keycmp asccmp )
493
rot 5 pick = ( ascq asc key keycmp asccmp ascqcmp )
497
0 CONSTANT CDROM-READY
498
1 CONSTANT CDROM-NOT-READY
499
2 CONSTANT CDROM-NO-DISK
500
3 CONSTANT CDROM-TRAY-OPEN
501
4 CONSTANT CDROM-INIT-REQUIRED
502
5 CONSTANT CDROM-TRAY-MAYBE-OPEN
504
: cdrom-status ( -- status )
505
initial-test-unit-ready
506
IF CDROM-READY EXIT THEN
509
." TestUnitReady sense: " 3dup . . . cr
512
3dup 1 4 2 compare-sense IF
513
3drop CDROM-NOT-READY EXIT
518
sector 2 + c@ 04 = IF
520
dup 02 and 0<> IF drop 3drop CDROM-READY EXIT THEN
521
dup 01 and 0<> IF drop 3drop CDROM-TRAY-OPEN EXIT THEN
522
drop 3drop CDROM-NO-DISK EXIT
527
3dup 2 4 2 compare-sense IF
528
3drop CDROM-INIT-REQUIRED EXIT
530
over 4 = over 2 = and IF
531
\ Format in progress... what do we do ? Just ignore
532
3drop CDROM-READY EXIT
535
3drop CDROM-NO-DISK EXIT
539
3drop CDROM-TRAY-MAYBE-OPEN
542
: cdrom-try-close-tray ( -- )
543
scsi-const-load start-stop-unit drop
546
: cdrom-must-close-tray ( -- )
547
scsi-const-load start-stop-unit not IF
548
." Tray open !" cr -65 throw
552
: dev-prep-cdrom ( -- )
555
CDROM-READY OF UNLOOP EXIT ENDOF
556
CDROM-NO-DISK OF ." No medium !" cr -65 THROW ENDOF
557
CDROM-TRAY-OPEN OF cdrom-must-close-tray ENDOF
558
CDROM-INIT-REQUIRED OF cdrom-try-close-tray ENDOF
559
CDROM-TRAY-MAYBE-OPEN OF cdrom-try-close-tray ENDOF
563
." Drive not ready !" cr -65 THROW
566
: dev-prep-disk ( -- )
567
initial-test-unit-ready 0= IF
568
." Disk not ready!" cr
573
: vscsi-create-disk ( lun id -- )
574
" disk" 0 " vio-vscsi-device.fs" included
577
: vscsi-create-cdrom ( lun id -- )
578
" cdrom" 1 " vio-vscsi-device.fs" included
581
: wrapped-inquiry ( -- true | false )
582
inquiry not IF false EXIT THEN
583
\ Skip devices with PQ != 0
584
sector inquiry-data>peripheral c@ e0 and 0 =
588
: vscsi-find-disks ( -- )
589
." VSCSI: Looking for disks" cr
590
#dev 0 DO \ check 8 devices (no LUNs)
594
\ XXX FIXME: Check top bits to ignore unsupported units
595
\ and maybe provide better printout & more cases
596
sector inquiry-data>peripheral c@ CASE
597
0 OF ." DISK : " 0 i vscsi-create-disk ENDOF
598
5 OF ." CD-ROM : " 0 i vscsi-create-cdrom ENDOF
599
7 OF ." OPTICAL : " 0 i vscsi-create-cdrom ENDOF
600
e OF ." RED-BLOCK: " 0 i vscsi-create-disk ENDOF
601
dup dup OF ." ? (" . 8 emit 29 emit 5 spaces ENDOF
603
sector .inquiry-text cr
608
\ Remove scsi functions from word list
612
" scsi" find-alias 0= IF
613
" scsi" get-node node>path set-alias
619
: vscsi-init-and-scan ( -- )
620
\ Create instance for scanning:
621
0 0 get-node open-node ?dup 0= IF EXIT THEN
624
\ Scan the VSCSI bus:
629
\ Close the temporary instance: