diff options
-rw-r--r-- | board-qemu/slof/vio-vscsi-device.fs | 10 | ||||
-rw-r--r-- | board-qemu/slof/vio-vscsi.fs | 112 | ||||
-rw-r--r-- | slof/fs/scsi-support.fs | 32 |
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) \ *************************************************************************** |