aboutsummaryrefslogtreecommitdiff
path: root/slof/fs/usb/usb-storage.fs
diff options
context:
space:
mode:
Diffstat (limited to 'slof/fs/usb/usb-storage.fs')
-rw-r--r--slof/fs/usb/usb-storage.fs464
1 files changed, 464 insertions, 0 deletions
diff --git a/slof/fs/usb/usb-storage.fs b/slof/fs/usb/usb-storage.fs
new file mode 100644
index 0000000..642e46a
--- /dev/null
+++ b/slof/fs/usb/usb-storage.fs
@@ -0,0 +1,464 @@
+\ *****************************************************************************
+\ * Copyright (c) 2004, 2007 IBM Corporation
+\ * All rights reserved.
+\ * This program and the accompanying materials
+\ * are made available under the terms of the BSD License
+\ * which accompanies this distribution, and is available at
+\ * http://www.opensource.org/licenses/bsd-license.php
+\ *
+\ * Contributors:
+\ * IBM Corporation - initial implementation
+\ ****************************************************************************/
+
+
+\ -----------------------------------------------------------
+\ OF properties
+\ -----------------------------------------------------------
+
+s" storage" device-name
+s" block" device-type
+
+2 encode-int s" #address-cells" property
+0 encode-int s" #size-cells" property
+
+
+\ -----------------------------------------------------------
+\ Specific properties
+\ -----------------------------------------------------------
+
+8 VALUE mps-bulk-out
+8 VALUE mps-bulk-in
+8 VALUE mps-dcp
+0 VALUE bulk-in-ep
+0 VALUE bulk-out-ep
+0 VALUE bulk-in-toggle
+0 VALUE bulk-out-toggle
+0 VALUE lun
+0 VALUE my-usb-address
+
+
+\ ----------------------------------------------------------
+\ Instance specific values
+\ ----------------------------------------------------------
+
+0 VALUE csw-buffer
+0e VALUE cfg-buffer
+0 VALUE response-buffer
+0 VALUE command-buffer
+0 VALUE resp-size
+0 VALUE resp-buffer
+INSTANCE VARIABLE ihandle-bulk
+INSTANCE VARIABLE ihandle-scsi
+INSTANCE VARIABLE ihandle-deblocker
+INSTANCE VARIABLE flag
+INSTANCE VARIABLE count
+0 VALUE max-transfer
+0 VALUE block-size
+
+
+\ -------------------------------------------------------
+\ General Constants
+\ -------------------------------------------------------
+
+0f CONSTANT SCSI-COMMAND-OFFSET
+
+
+\ -------------------------------------------------------
+\ All support methods inherited from parent or imported
+\ from support packages are included here. Also included
+\ are the internal methods
+\ -------------------------------------------------------
+
+s" usb-storage-support.fs" INCLUDED
+
+\ ---------------------------------------------------------------
+\ COLON Definitions: Implementation of Standard SCSI commands
+\ over USB OHCI
+\ ---------------------------------------------------------------
+
+
+\ to use the general bulk command a lot of global variables
+\ must be set. See for example the inquiry command.
+0 VALUE bulk-cnt
+: do-bulk-command ( resp-buffer resp-size -- TRUE | FALSE )
+ TO resp-size
+ TO resp-buffer
+ 2 TO bulk-cnt
+ FALSE dup
+ BEGIN 0= WHILE
+ drop
+ \ prepare and send bulk CBW
+ 1 1 bulk-out-toggle command-buffer 1f mps-bulk-out
+ ( pt ed-type toggle buffer length mps-bulk-out )
+ my-usb-address bulk-out-ep 7 lshift or
+ ( pt ed-type toggle buffer length mps address )
+ rw-endpoint swap ( TRUE toggle | FALSE toggle )
+ to bulk-out-toggle ( TRUE | FALSE )
+ IF
+ resp-size 0<> IF \ do we need a response ?!
+ \ read the bulk response
+ 0 1 bulk-in-toggle resp-buffer resp-size mps-bulk-in
+ ( pt ed-type toggle buffer length mps-bulk-in )
+ my-usb-address bulk-in-ep 7 lshift or
+ ( pt ed-type toggle buffer length mps address )
+ rw-endpoint swap ( TRUE toggle | FALSE toggle )
+ to bulk-in-toggle ( TRUE | FALSE )
+ ELSE
+ TRUE
+ THEN
+ IF
+ \ read the bulk CSW
+ 0 1 bulk-in-toggle csw-buffer D mps-bulk-in
+ ( pt ed-type toggle buffer length mps-bulk-in )
+ my-usb-address bulk-in-ep 7 lshift or
+ ( pt ed-type toggle buffer length mps address )
+ rw-endpoint swap ( TRUE toggle | FALSE toggle )
+ to bulk-in-toggle ( TRUE | FALSE )
+ IF
+ s" Command successful." usb-debug-print
+ TRUE dup
+ ELSE
+ s" Command failed in CSW stage" usb-debug-print
+ FALSE dup
+ THEN
+ ELSE
+ s" Command failed while receiving DATA... read CSW..." usb-debug-print
+ \ STALLED: Get CSW to send the CBW again
+ 0 1 bulk-in-toggle csw-buffer D mps-bulk-in
+ ( pt ed-type toggle buffer length mps-bulk-in )
+ my-usb-address bulk-in-ep 7 lshift or
+ ( pt ed-type toggle buffer length mps address )
+ rw-endpoint swap ( TRUE toggle | FALSE toggle )
+ to bulk-in-toggle ( TRUE | FALSE )
+ IF
+ s" OK evaluate the CSW ..." usb-debug-print
+ csw-buffer c + l@-le
+ 2 = IF \ Phase Error
+ s" do a bulk reset-recovery ..." usb-debug-print
+ bulk-out-ep bulk-in-ep my-usb-address
+ bulk-reset-recovery-procedure
+ THEN
+ \ ELSE
+ \ don't abort if the read fails.
+ THEN
+ FALSE dup
+ THEN
+ ELSE
+ s" Command failed while Sending CBW ..." usb-debug-print
+ FALSE dup
+ THEN
+ bulk-cnt 1 - TO bulk-cnt
+ bulk-cnt 0= IF
+ 2drop FALSE dup
+ THEN
+ REPEAT
+;
+
+\ ---------------------------------------------------------------
+\ Method to 1. Send the INQUIRY command 2. Recieve and analyse
+\ (pending) INQUIRY data
+\ ---------------------------------------------------------------
+
+: inquiry ( -- )
+ s" usb-storage: inquiry" usb-debug-print
+ command-buffer 1 20 80 lun 0c
+ ( address tag transfer-len direction lun command-len )
+ build-cbw
+ command-buffer SCSI-COMMAND-OFFSET + 20 ( address alloc-len )
+ build-inquiry
+ response-buffer 20
+ do-bulk-command
+ IF
+ s" Successfully read INQUIRY data" usb-debug-print
+ s" Inquiry data for 0x20 bytes availabe in Response buffer"
+ usb-debug-print
+ ELSE
+ \ TRUE ABORT" USB device transaction error. (inquiry)"
+ 5040 error" (USB) Device transaction error. (inquiry)"
+ ABORT
+ THEN
+;
+
+\ ---------------------------------------------------------------
+\ Method to 1. Send the READ CAPACITY command
+\ 2. Recieve and analyse the response data
+\ ---------------------------------------------------------------
+
+: read-capacity ( -- )
+ s" usb-storage: read-capacity" usb-debug-print
+ command-buffer 1 8 80 lun 0c
+ ( address tag transfer-len direction lun command-len )
+ build-cbw
+ command-buffer SCSI-COMMAND-OFFSET + ( address )
+ build-read-capacity
+ response-buffer 8 do-bulk-command
+ IF
+ s" Successfully read READ CAPACITY data" usb-debug-print
+ ELSE
+ \ TRUE ABORT" USB device transaction error. (capacity)"
+ 5040 error" (USB) Device transaction error. (capacity)"
+ ABORT
+ THEN
+;
+
+
+\ --------------------------------------------------------------------
+\ Method to 1. Send TEST UNIT READY command 2. Analyse the status
+\ of the response
+\ -------------------------------------------------------------------
+
+: test-unit-ready ( -- TRUE | FALSE )
+ command-buffer 1 0 80 lun 0c
+ ( address tag transfer-len direction lun command-len )
+ build-cbw
+ command-buffer SCSI-COMMAND-OFFSET + ( address )
+ build-test-unit-ready
+ response-buffer 0 do-bulk-command
+ IF
+ s" Successfully read test unit ready data" usb-debug-print
+ s" Test Unit STATUS availabe in csw-buffer" usb-debug-print
+ csw-buffer 0c + c@ 0= IF
+ s" Test Unit Command Successfully Executed" usb-debug-print
+ TRUE ( TRUE )
+ ELSE
+ s" Test Unit Command Failed to execute" usb-debug-print
+ FALSE ( FALSE )
+ THEN
+ ELSE
+ \ TRUE ABORT" USB device transaction error. (test-unit-ready)"
+ 5040 error" (USB) Device transaction error. (test-unit-ready)"
+ ABORT
+ THEN
+;
+
+\ -------------------------------------------------
+\ Method to 1. read sense data 2. analyse sesnse
+\ data(pending)
+\ ------------------------------------------------
+
+: request-sense ( -- )
+ s" request-sense: Command ready." usb-debug-print
+ command-buffer 1 12 80 lun 0c
+ ( address tag transfer-len direction lun command-len )
+ build-cbw
+ command-buffer SCSI-COMMAND-OFFSET + 12 ( address alloc-len )
+ build-request-sense
+ response-buffer 12 do-bulk-command
+ IF
+ s" Read Sense data successfully" usb-debug-print
+ ELSE
+ \ TRUE ABORT" USB device transaction error. (request-sense)"
+ 5040 error" (USB) Device transaction error. (request-sense)"
+ ABORT
+ THEN
+;
+
+: start ( -- )
+ command-buffer 1 0 80 lun 0c
+ ( address tag transfer-len direction lun command-len )
+ build-cbw
+ command-buffer SCSI-COMMAND-OFFSET + ( address )
+ build-start
+ response-buffer 0 do-bulk-command
+ IF
+ s" Start successfully" usb-debug-print
+ ELSE
+ \ TRUE ABORT" USB device transaction error. (start)"
+ 5040 error" (USB) Device transaction error. (start)"
+ ABORT
+ THEN
+;
+
+
+\ To transmit SCSI Stop command
+
+: stop ( -- )
+ command-buffer 1 0 80 lun 0c
+ ( address tag transfer-len direction lun command-len )
+ build-cbw
+ command-buffer SCSI-COMMAND-OFFSET + ( address )
+ build-stop
+ response-buffer 0 do-bulk-command
+ IF
+ s" Stop successfully" usb-debug-print
+ ELSE
+ \ TRUE ABORT" USB device transaction error. (stop)"
+ 5040 error" (USB) Device transaction error. (stop)"
+ ABORT
+ THEN
+;
+
+
+0 VALUE temp1
+0 VALUE temp2
+0 VALUE temp3
+
+
+\ -------------------------------------------------------------
+\ block device's seek
+\ -------------------------------------------------------------
+
+: seek ( pos-hi pos-lo -- status )
+ s" seek" ihandle-deblocker @ $call-method
+;
+
+
+\ -------------------------------------------------------------
+\ block device's read
+\ -------------------------------------------------------------
+
+: read ( address length -- actual )
+ s" read" ihandle-deblocker @ $call-method
+;
+
+
+\ -------------------------------------------------------------
+\ read-blocks to be used by deblocker
+\ -------------------------------------------------------------
+: read-blocks ( address block# #blocks -- #read-blocks )
+ block-size * command-buffer ( address block# transfer-len command-buffer )
+ 1 2 pick 80 lun 0c build-cbw ( address block# transfer-len )
+ dup to temp1 ( address block# transfer-len)
+ block-size / ( address block# #blocks )
+ command-buffer ( address block# #block command-addr )
+ SCSI-COMMAND-OFFSET + -rot ( address command-addr block# #blocks )
+ build-read ( address )
+ temp1 do-bulk-command
+ IF
+ s" Read Sense data successfully" usb-debug-print
+ ELSE
+ \ TRUE ABORT" USB device transaction error. (read-blocks)"
+ 5040 error" (USB) Device transaction error. (read-blocks)"
+ ABORT
+ THEN
+ temp1 block-size / ( #read-blocks )
+;
+
+\ ------------------------------------------------
+\ To bring the the media to seekable and readable
+\ condition.
+\ ------------------------------------------------
+
+0 VALUE temp1
+0 VALUE temp2
+0 VALUE temp3
+d# 800 CONSTANT media-ready-retry
+
+: make-media-ready ( -- )
+ s" usb-storage: make-media-ready" usb-debug-print
+ 0 flag !
+ 0 count !
+ BEGIN
+ flag @ 0=
+ WHILE
+ test-unit-ready IF
+ s" Media ready for access." usb-debug-print
+ 1 flag !
+ ELSE
+ count @ 1 + count !
+ count @ media-ready-retry = IF
+ 1 flag !
+ 5000 error" (USB) Media or drive not ready for this blade."
+ ABORT
+ THEN
+ request-sense
+ response-buffer return-request-sense
+ ( FALSE | ascq asc sense-key TRUE )
+ IF
+ to temp1 ( ascq asc )
+ to temp2 ( ascq )
+ to temp3
+ temp1 2 = temp2 3a = and ( TRUE | FALSE )
+ IF
+ 5010 error" (USB) No Media found! Check for the drawer/inserted media."
+ ABORT
+ THEN
+ temp1 2 = temp2 06 = and ( TRUE | FALSE )
+ IF
+ 5020 error" (USB) Unknown media format."
+ ABORT
+ THEN
+ temp1 0<> temp2 4 = temp3 2 = and and ( TRUE | FALSE )
+ IF
+ start stop
+ THEN
+ THEN
+ THEN
+ d# 10 ms
+ REPEAT
+ usb-debug-flag IF
+ ." make-media-ready finished after "
+ count @ decimal . hex ." tries." cr
+ THEN
+;
+
+
+\ Set up the block-size of the device, using the READ CAPACITY command.
+\ Note: Media must be ready (=> make-media-ready) or READ CAPACITY
+\ might fail!
+
+: (init-block-size)
+ read-capacity
+ response-buffer 4 +
+ l@ to block-size
+ s" usb-storage: block-size=" block-size usb-debug-print-val
+;
+
+
+\ Standard OF methods
+
+: open ( -- TRUE )
+ s" usb-storage: open" usb-debug-print
+ ihandle-bulk s" bulk" (open-package)
+ ihandle-scsi s" scsi" (open-package)
+
+ make-media-ready
+ (init-block-size) \ Init block-size before opening the deblocker
+
+ ihandle-deblocker s" deblocker" (open-package)
+
+ s" disk-label" find-package IF ( phandle )
+ usb-debug-flag IF ." my-args for disk-label = " my-args swap . . cr THEN
+ my-args rot interpose
+ THEN
+ TRUE ( TRUE )
+;
+
+
+: close ( -- )
+ ihandle-deblocker (close-package)
+ ihandle-scsi (close-package)
+ ihandle-bulk (close-package)
+;
+
+
+\ Set device name according to type
+
+: (init-device-name) ( -- )
+ inquiry
+ response-buffer c@
+ CASE
+ 1 OF s" tape" device-name ENDOF
+ 5 OF s" cdrom" device-name ENDOF
+ \ dup OF s" storage" device-name ENDOF
+ ENDCASE
+;
+
+
+\ Initial device node setup
+
+: (initial-setup)
+ ihandle-bulk s" bulk" (open-package)
+ ihandle-scsi s" scsi" (open-package)
+
+ device-init
+ (init-device-name)
+ set-cdrom-alias
+ 200 to block-size \ Default block-size, will be overwritten in "open"
+ 10000 to max-transfer
+
+ ihandle-bulk (close-package)
+ ihandle-scsi (close-package)
+;
+
+(initial-setup)