[SLOF] [PATCH 2/4] scsi: Add SCSI block write support

Thomas Huth thuth at redhat.com
Thu Nov 10 02:43:36 AEDT 2016


Using the SCSI commands WRITE-10 and WRITE-16, we can
implement block write support for SCSI disks.

Signed-off-by: Thomas Huth <thuth at redhat.com>
---
 slof/fs/scsi-disk.fs    | 32 +++++++++++++++++++++++++++
 slof/fs/scsi-support.fs | 58 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+)

diff --git a/slof/fs/scsi-disk.fs b/slof/fs/scsi-disk.fs
index bcaa19e..b98cc07 100644
--- a/slof/fs/scsi-disk.fs
+++ b/slof/fs/scsi-disk.fs
@@ -95,6 +95,34 @@ CREATE cdb 10 allot
     dup 0<> IF " read-blocks" dump-scsi-error -65 throw ELSE drop THEN
 ;
 
+: write-blocks ( addr block# #blocks -- #written )
+    scsi-disk-debug? IF
+        ." SCSI-DISK: write-blocks " .s cr
+    THEN
+
+    \ Bound check
+    2dup + max-block-num > IF
+        ." SCSI-DISK: Access beyond end of device ! " cr
+        3drop 0 EXIT
+    THEN
+
+    dup block-size *                            ( addr block# #blocks len )
+    >r rot r>                                   ( block# #blocks addr len )
+    2swap                                       ( addr len block# #blocks )
+    dup >r
+    cdb                                         ( addr len block# #blocks cdb )
+    max-block-num FFFFFFFF > IF
+        scsi-build-write-16
+    ELSE
+        scsi-build-write-10
+    THEN
+    r> -rot                                     ( #blocks addr len )
+    scsi-dir-write cdb scsi-param-size 10
+    retry-scsi-command
+                                                ( #blocks [ sense-buf sense-len ] stat )
+    dup 0<> IF s" write-blocks" dump-scsi-error -65 throw ELSE drop THEN
+;
+
 : (inquiry) ( size -- buffer | NULL )
     dup cdb scsi-build-inquiry
     \ 16 retries for inquiry to flush out any UAs
@@ -342,6 +370,10 @@ CREATE cdb 10 allot
 : read ( addr len -- actual )
     s" read" deblocker @ $call-method ;
 
+: write ( addr len -- actual )
+    s" write" deblocker @ $call-method
+;
+
 \ Get rid of SCSI bits
 scsi-close
 
diff --git a/slof/fs/scsi-support.fs b/slof/fs/scsi-support.fs
index d24c8a1..608e468 100644
--- a/slof/fs/scsi-support.fs
+++ b/slof/fs/scsi-support.fs
@@ -531,6 +531,64 @@ CONSTANT scsi-length-read-16
 ;
 
 \ ***************************************************************************
+\ SCSI-Command: WRITE (10)
+\         Type: Block Command
+\ ***************************************************************************
+\ Forth Word:   scsi-build-write-10  ( block# #blocks cdb -- )
+\ ***************************************************************************
+\ command code
+2A CONSTANT scsi-cmd-write-10
+
+\ CDB structure
+STRUCT
+   /c FIELD write-10>operation-code
+   /c FIELD write-10>protect
+   /l FIELD write-10>block-address            \ logical block address (32bits)
+   /c FIELD write-10>group
+   /w FIELD write-10>length                   \ transfer length (16-bits)
+   /c FIELD write-10>control
+CONSTANT scsi-length-write-10
+
+: scsi-build-write-10                         ( block# #blocks cdb -- )
+   >r                                         ( block# #blocks )  ( R: -- cdb )
+   r@ scsi-length-write-10 erase              \ 10 bytes CDB
+   scsi-cmd-write-10 r@ write-10>operation-code c! ( block# #blocks )
+   r@ write-10>length w!                      ( block# )
+   r@ write-10>block-address l!               (  )
+   scsi-param-control r> write-10>control c!  ( R: cdb -- )
+   scsi-length-write-10 to scsi-param-size    \ update CDB length
+;
+
+\ ***************************************************************************
+\ SCSI-Command: WRITE (16)
+\         Type: Block Command
+\ ***************************************************************************
+\ Forth Word:   scsi-build-write-16  ( block# #blocks cdb -- )
+\ ***************************************************************************
+\ command code
+8A CONSTANT scsi-cmd-write-16
+
+\ CDB structure
+STRUCT
+   /c FIELD write-16>operation-code
+   /c FIELD write-16>protect                  \ RDPROTECT, DPO, FUA, FUA_NV
+   /x FIELD write-16>block-address            \ LBA
+   /l FIELD write-16>length                   \ Transfer length (32-bits)
+   /c FIELD write-16>group                    \ Group number
+   /c FIELD write-16>control
+CONSTANT scsi-length-write-16
+
+: scsi-build-write-16                         ( block# #blocks cdb -- )
+   >r                                         ( block# #blocks )  ( R: -- cdb )
+   r@ scsi-length-write-16 erase              \ 16 bytes CDB
+   scsi-cmd-write-16 r@ write-16>operation-code c! ( block# #blocks )
+   r@ write-16>length l!                      ( block# )
+   r@ write-16>block-address x!               (  )
+   scsi-param-control r> write-16>control c!  ( R: cdb -- )
+   scsi-length-write-16 to scsi-param-size    \ update CDB length
+;
+
+\ ***************************************************************************
 \ SCSI-Command: START STOP UNIT
 \         Type: Block Command (SBC-3 clause 5.19)
 \ ***************************************************************************
-- 
1.8.3.1



More information about the SLOF mailing list