aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-07-19 16:44:17 +1000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-07-19 16:44:17 +1000
commit7279655af2eba855bd2df61303d25abd1eeb2300 (patch)
tree367b81b79cc81b2d6df45da56e0b47a2bf8e4636
parent748d6ae8aeec30fbc8257d939a9f79f7d50c4182 (diff)
downloadSLOF-qemu-slof-20120719.zip
SLOF-qemu-slof-20120719.tar.gz
SLOF-qemu-slof-20120719.tar.bz2
vscsi updates to match IBM OFW variantqemu-slof-20120719
This update our vscsi to encode unit-addresses the same way as IBM proprietary OFW does, and adds support for the vscsi-report-lun method. This fixes booting with grub2 on fedora. It also means that we now support devices with LUNs. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--board-qemu/slof/vio-vscsi-device.fs10
-rw-r--r--board-qemu/slof/vio-vscsi.fs112
-rw-r--r--slof/fs/scsi-support.fs32
3 files changed, 114 insertions, 40 deletions
diff --git a/board-qemu/slof/vio-vscsi-device.fs b/board-qemu/slof/vio-vscsi-device.fs
index fcebe8e..30b9d15 100644
--- a/board-qemu/slof/vio-vscsi-device.fs
+++ b/board-qemu/slof/vio-vscsi-device.fs
@@ -11,21 +11,22 @@
\ ****************************************************************************/
\ Create new VSCSI child device
-\ ( lun id $name is_cdrom -- )
+\ ( target $name is_cdrom -- )
\ Create device
new-device
VALUE is_cdrom
-2swap ( $name lun id )
+rot ( $name target )
\ Set reg & unit
-2dup set-unit encode-phys " reg" property
+dup set-unit-64 xlsplit encode-phys " reg" property
\ Set name
2dup device-name
+
2dup find-alias 0= IF
get-node node>path set-alias
ELSE 3drop THEN
@@ -48,7 +49,8 @@ s" block" device-type
INSTANCE VARIABLE deblocker
: open ( -- true | false )
- my-unit " set-address" $call-parent
+ \ ." OPEN: [" .s ." ] unit is " my-unit . . ." [" .s ." ]" cr
+ my-unit lxjoin " set-target" $call-parent
is_cdrom IF " dev-prep-cdrom" ELSE " dev-prep-disk" THEN $call-parent
" dev-max-transfer" $call-parent to max-transfer
diff --git a/board-qemu/slof/vio-vscsi.fs b/board-qemu/slof/vio-vscsi.fs
index 0976cba..f3f1fc1 100644
--- a/board-qemu/slof/vio-vscsi.fs
+++ b/board-qemu/slof/vio-vscsi.fs
@@ -256,17 +256,15 @@ constant /srp-rsp
CREATE srp 100 allot
0 VALUE srp-len
-: srp-prep-cmd-nodata ( id lun -- )
+: srp-prep-cmd-nodata ( srplun -- )
srp /srp-cmd erase
SRP_CMD srp >srp-cmd-opcode c!
1 srp >srp-cmd-tag x!
- srp >srp-cmd-lun 1 + c! \ lun
- 80 or \ select logical unit addressing method
- srp >srp-cmd-lun c! \ id
+ srp >srp-cmd-lun x! \ 8 bytes lun
/srp-cmd to srp-len
;
-: srp-prep-cmd-io ( addr len id lun -- )
+: srp-prep-cmd-io ( addr len srplun -- )
srp-prep-cmd-nodata ( addr len )
swap l2dma ( len dmaaddr )
srp srp-len + ( len dmaaddr descaddr )
@@ -276,13 +274,13 @@ CREATE srp 100 allot
srp-len 10 + to srp-len
;
-: srp-prep-cmd-read ( addr len id lun -- )
+: srp-prep-cmd-read ( addr len srplun -- )
srp-prep-cmd-io
01 srp >srp-cmd-buf-fmt c! \ in direct buffer
1 srp >srp-cmd-din-desc-cnt c!
;
-: srp-prep-cmd-write ( addr len id lun -- )
+: srp-prep-cmd-write ( addr len srplun -- )
srp-prep-cmd-io
10 srp >srp-cmd-buf-fmt c! \ out direct buffer
1 srp >srp-cmd-dout-desc-cnt c!
@@ -336,12 +334,11 @@ CREATE srp 100 allot
CREATE sector d# 512 allot
-0 INSTANCE VALUE current-id
-0 INSTANCE VALUE current-lun
+8000000000000000 INSTANCE VALUE current-target
\ SCSI test-unit-read
: test-unit-ready ( -- true | [ ascq asc sense-key false ] )
- current-id current-lun srp-prep-cmd-nodata
+ current-target srp-prep-cmd-nodata
srp >srp-cmd-cdb scsi-build-test-unit-ready
srp-send-cmd
srp-wait-rsp
@@ -350,15 +347,23 @@ CREATE sector d# 512 allot
: inquiry ( -- true | false )
\ WARNING: ATAPI devices with libata seem to ignore the MSB of
\ the allocation length... let's only ask for ff bytes
- sector ff current-id current-lun srp-prep-cmd-read
+ sector ff current-target srp-prep-cmd-read
ff srp >srp-cmd-cdb scsi-build-inquiry
srp-send-cmd
srp-wait-rsp
dup not IF nip nip nip EXIT THEN \ swallow sense
;
+: report-luns ( -- true | false )
+ sector 200 current-target srp-prep-cmd-read
+ 200 srp >srp-cmd-cdb scsi-build-report-luns
+ srp-send-cmd
+ srp-wait-rsp
+ dup not IF nip nip nip EXIT THEN \ swallow sense
+;
+
: read-capacity ( -- true | false )
- sector scsi-length-read-cap-10 current-id current-lun srp-prep-cmd-read
+ sector scsi-length-read-cap-10 current-target srp-prep-cmd-read
srp >srp-cmd-cdb scsi-build-read-cap-10
srp-send-cmd
srp-wait-rsp
@@ -366,7 +371,7 @@ CREATE sector d# 512 allot
;
: start-stop-unit ( state# -- true | false )
- current-id current-lun srp-prep-cmd-nodata
+ current-target srp-prep-cmd-nodata
srp >srp-cmd-cdb scsi-build-start-stop-unit
srp-send-cmd
srp-wait-rsp
@@ -374,7 +379,7 @@ CREATE sector d# 512 allot
;
: get-media-event ( -- true | false )
- sector scsi-length-media-event current-id current-lun srp-prep-cmd-read
+ sector scsi-length-media-event current-target srp-prep-cmd-read
srp >srp-cmd-cdb scsi-build-get-media-event
srp-send-cmd
srp-wait-rsp
@@ -385,7 +390,7 @@ CREATE sector d# 512 allot
over * ( addr block# #blocks len )
>r rot r> ( block# #blocks addr len )
5 0 DO
- 2dup current-id current-lun
+ 2dup current-target
srp-prep-cmd-read ( block# #blocks addr len )
2swap ( addr len block# #blocks )
2dup srp >srp-cmd-cdb scsi-build-read-10 ( addr len block# #blocks )
@@ -457,8 +462,10 @@ CREATE sector d# 512 allot
\ SCSI scan at boot and child device support
\ -----------------------------------------------------------
-: set-address ( lun id -- )
- to current-id to current-lun
+\ We use SRP luns of the form 8000 | (bus << 8) | (id << 5) | lun
+\ in the top 16 bits of the 64-bit LUN
+: set-target ( srplun -- )
+ to current-target
;
: dev-max-transfer ( -- n )
@@ -570,11 +577,11 @@ CREATE sector d# 512 allot
THEN
;
-: vscsi-create-disk ( lun id -- )
+: vscsi-create-disk ( srplun -- )
" disk" 0 " vio-vscsi-device.fs" included
;
-: vscsi-create-cdrom ( lun id -- )
+: vscsi-create-cdrom ( srplun -- )
" cdrom" 1 " vio-vscsi-device.fs" included
;
@@ -585,24 +592,57 @@ CREATE sector d# 512 allot
;
8 CONSTANT #dev
+
+: vscsi-report-luns ( -- array ndev )
+ \ array of pointers, up to 8 devices
+ #dev 3 << alloc-mem dup
+ 0 ( devarray devcur ndev )
+ #dev 0 DO
+ i 8 << 8000 or 30 << set-target
+ report-luns IF
+ sector l@ ( devarray devcur ndev size )
+ sector 8 + swap ( devarray devcur ndev lunarray size )
+ dup 8 + dup alloc-mem ( devarray devcur ndev lunarray size size+ mem )
+ dup rot 0 fill ( devarray devcur ndev lunarray size mem )
+ dup >r swap move r> ( devarray devcur ndev mem )
+ dup sector l@ 3 >> 0 DO ( devarray devcur ndev mem memcur )
+ dup dup x@ j 8 << 8000 or or 30 << swap x! 8 +
+ LOOP drop
+ rot ( devarray ndev mem devcur )
+ dup >r x! r> 8 + ( devarray ndev devcur )
+ swap 1 +
+ THEN
+ LOOP
+ nip
+;
+
: vscsi-find-disks ( -- )
- ." VSCSI: Looking for disks" cr
- #dev 0 DO \ check 8 devices (no LUNs)
- 0 i set-address
- wrapped-inquiry IF
- ." SCSI ID " i .
- \ XXX FIXME: Check top bits to ignore unsupported units
- \ and maybe provide better printout & more cases
- sector inquiry-data>peripheral c@ CASE
- 0 OF ." DISK : " 0 i vscsi-create-disk ENDOF
- 5 OF ." CD-ROM : " 0 i vscsi-create-cdrom ENDOF
- 7 OF ." OPTICAL : " 0 i vscsi-create-cdrom ENDOF
- e OF ." RED-BLOCK: " 0 i vscsi-create-disk ENDOF
- dup dup OF ." ? (" . 8 emit 29 emit 5 spaces ENDOF
- ENDCASE
- sector .inquiry-text cr
- THEN
- LOOP
+ ." VSCSI: Looking for devices" cr
+ vscsi-report-luns
+ 0 DO
+ dup x@
+ BEGIN
+ dup x@
+ dup 0= IF drop FALSE ELSE
+ set-target wrapped-inquiry IF
+ ." " current-target (u.) type ." "
+ \ XXX FIXME: Check top bits to ignore unsupported units
+ \ and maybe provide better printout & more cases
+ \ XXX FIXME: Actually check for LUNs
+ sector inquiry-data>peripheral c@ CASE
+ 0 OF ." DISK : " current-target vscsi-create-disk ENDOF
+ 5 OF ." CD-ROM : " current-target vscsi-create-cdrom ENDOF
+ 7 OF ." OPTICAL : " current-target vscsi-create-cdrom ENDOF
+ e OF ." RED-BLOCK: " current-target vscsi-create-disk ENDOF
+ dup dup OF ." ? (" . 8 emit 29 emit 5 spaces ENDOF
+ ENDCASE
+ sector .inquiry-text cr
+ THEN
+ 8 + TRUE
+ THEN
+ UNTIL drop
+ 8 +
+ LOOP drop
;
\ Remove scsi functions from word list
diff --git a/slof/fs/scsi-support.fs b/slof/fs/scsi-support.fs
index 4c6e1d1..d4b260b 100644
--- a/slof/fs/scsi-support.fs
+++ b/slof/fs/scsi-support.fs
@@ -55,6 +55,38 @@ CONSTANT scsi-length-test-unit-ready
;
\ ***************************************************************************
+\ SCSI-Command: REPORT LUNS
+\ Type: Primary Command
+\ ***************************************************************************
+\ Forth Word: scsi-build-report-luns ( cdb -- )
+\ ***************************************************************************
+\ report all LUNs supported by a device
+\ ***************************************************************************
+\ command code:
+a0 CONSTANT scsi-cmd-report-luns
+\ CDB structure:
+STRUCT
+ /c FIELD report-luns>operation-code \ a0h
+ 1 FIELD report-luns>reserved \ unused
+ /c FIELD report-luns>select-report \ report select byte
+ 3 FIELD report-luns>reserved2 \ unused
+ /l FIELD report-luns>alloc-length \ report length
+ 1 FIELD report-luns>reserved3 \ unused
+ /c FIELD report-luns>control \ control byte
+CONSTANT scsi-length-report-luns
+
+\ cdb build:
+\ all fields are zeroed
+: scsi-build-report-luns ( alloc-len cdb -- )
+ dup scsi-length-report-luns erase \ 12 bytes CDB
+ scsi-cmd-report-luns over ( alloc-len cdb cmd cdb )
+ report-luns>operation-code c! ( alloc-len cdb )
+ scsi-param-control over report-luns>control c! ( alloc-len cdb )
+ report-luns>alloc-length l! \ size of Data-In Buffer
+ scsi-length-report-luns to scsi-param-size \ update CDB length
+;
+
+\ ***************************************************************************
\ SCSI-Command: REQUEST SENSE
\ Type: Primary Command (SPC-3 clause 6.27)
\ ***************************************************************************