Annotation of qemu/roms/SLOF/slof/fs/usb/usb-storage.fs, revision 1.1.1.2

1.1       root        1: \ *****************************************************************************
1.1.1.2 ! root        2: \ * Copyright (c) 2004, 2011 IBM Corporation
1.1       root        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
                      8: \ *
                      9: \ * Contributors:
                     10: \ *     IBM Corporation - initial implementation
                     11: \ ****************************************************************************/
                     12: 
1.1.1.2 ! root       13: s" entered usb-storage.fs" usb-debug-print
1.1       root       14: 
                     15: \ -----------------------------------------------------------
                     16: \ OF properties
                     17: \ -----------------------------------------------------------
                     18: 
                     19: s" storage" device-name
                     20: s" block" device-type
                     21: 
                     22: 2 encode-int s" #address-cells" property
                     23: 0 encode-int s" #size-cells" property
                     24: 
                     25: \ -----------------------------------------------------------
                     26: \ Specific properties
                     27: \ -----------------------------------------------------------
                     28: 
                     29: 8 VALUE mps-bulk-out
                     30: 8 VALUE mps-bulk-in
                     31: 8 VALUE mps-dcp
                     32: 0 VALUE bulk-in-ep
                     33: 0 VALUE bulk-out-ep
                     34: 0 VALUE bulk-in-toggle
                     35: 0 VALUE bulk-out-toggle
                     36: 0 VALUE lun
                     37: 0 VALUE my-usb-address
                     38: 
                     39: 
                     40: \ ----------------------------------------------------------
                     41: \ Instance specific values
                     42: \ ----------------------------------------------------------
                     43: 
                     44: INSTANCE VARIABLE ihandle-bulk
                     45: INSTANCE VARIABLE ihandle-deblocker
                     46: INSTANCE VARIABLE flag
                     47: INSTANCE VARIABLE count
1.1.1.2 ! root       48: 4000 CONSTANT max-transfer
1.1       root       49: 200   VALUE block-size           \ default (512 Bytes)
                     50: -1    VALUE max-block-num        \ highest reported block-number
                     51: 
                     52: 
                     53: \ -------------------------------------------------------
                     54: \ General Constants
                     55: \ -------------------------------------------------------
                     56: 
                     57: 0f CONSTANT SCSI-COMMAND-OFFSET
                     58: 
                     59: 
                     60: \ -------------------------------------------------------
1.1.1.2 ! root       61: \ DMA-able buffers
        !            62: \ -------------------------------------------------------
        !            63: 
        !            64: STRUCT
        !            65:    max-transfer FIELD >read-buffer
        !            66:    80 FIELD >response-buffer
        !            67:    40 FIELD >command-buffer
        !            68:    10 FIELD >csw-buffer
        !            69:    8  FIELD >cfg-buffer
        !            70: CONSTANT /dma-buf
        !            71: 
        !            72: 0 VALUE dma-buf
        !            73: 0 VALUE dma-buf-phys
        !            74: 
        !            75: : (dma-buf-init)  ( -- )
        !            76:    /dma-buf s" dma-alloc" $call-parent TO dma-buf
        !            77:    dma-buf /dma-buf 0 s" dma-map-in" $call-parent TO dma-buf-phys
        !            78: 
        !            79:    s" storage dma-buf = " dma-buf usb-debug-print-val
        !            80: ;
        !            81: 
        !            82: : (dma-buf-free)  ( -- )
        !            83:    dma-buf dma-buf-phys /dma-buf s" dma-map-out" $call-parent
        !            84:    dma-buf /dma-buf s" dma-free" $call-parent
        !            85:    0 TO dma-buf
        !            86:    0 TO dma-buf-phys
        !            87: ;
        !            88: 
        !            89: 
        !            90: \ -------------------------------------------------------
1.1       root       91: \ All support methods inherited from parent or imported
                     92: \ from support packages are included here. Also included
                     93: \ are the internal methods
                     94: \ -------------------------------------------------------
                     95: 
                     96: s" usb-storage-support.fs" INCLUDED
                     97: 
                     98: \ ---------------------------------------------------------------
                     99: \ COLON Definitions: Implementation of Standard SCSI commands
                    100: \ over USB OHCI
                    101: \ ---------------------------------------------------------------
                    102: 
                    103: 
                    104: \ to use the general bulk command a lot of global variables
                    105: \ must be set. See for example the inquiry command.
                    106: 0 VALUE bulk-cnt
                    107: 0 VALUE bulk-cmd-len
                    108: 0 VALUE itest
1.1.1.2 ! root      109: 0 VALUE resp-buffer
        !           110: 0 VALUE resp-size
1.1       root      111: : do-bulk-command ( resp-buffer resp-size -- TRUE | FALSE )
                    112:    TO resp-size
                    113:    TO resp-buffer
                    114:    \ dump buffer in debug-mode
                    115:    usb-debug-flag
                    116:    IF
1.1.1.2 ! root      117:       dma-buf >command-buffer 0E + c@ TO bulk-cmd-len 
1.1       root      118:       s" cmd-length: " bulk-cmd-len usb-debug-print-val
1.1.1.2 ! root      119:       dma-buf >command-buffer bulk-cmd-len 0E + dump cr
1.1       root      120:    THEN
                    121: 
                    122:    6 TO bulk-cnt \ 2 old value
                    123:    FALSE dup
                    124:    BEGIN
                    125:       0=
                    126:       WHILE
                    127:       drop
                    128:       \ prepare and send bulk CBW
1.1.1.2 ! root      129:       1 1 bulk-out-toggle dma-buf >command-buffer 1f mps-bulk-out
1.1       root      130:                ( pt ed-type toggle buffer length mps-bulk-out )
                    131:       my-usb-address bulk-out-ep 7 lshift or
                    132:                ( pt ed-type toggle buffer length mps address )
                    133:       rw-endpoint swap                      ( TRUE toggle | FALSE toggle )
                    134:       to bulk-out-toggle                ( TRUE | FALSE )
                    135:       IF
                    136:          s" resp-size : " resp-size usb-debug-print-val
                    137:          resp-size 0<>
                    138:          IF       \ do we need a response ?!
                    139:                   \ read the bulk response
                    140:             0 1 bulk-in-toggle resp-buffer resp-size mps-bulk-in
                    141:                      ( pt ed-type toggle buffer length mps-bulk-in )
                    142:             my-usb-address bulk-in-ep 7 lshift or
                    143:                      ( pt ed-type toggle buffer length mps address )
                    144:             rw-endpoint swap                       ( TRUE toggle | FALSE toggle )
                    145:             to bulk-in-toggle                      ( TRUE | FALSE )
                    146:          ELSE
                    147:             TRUE
                    148:          THEN
                    149:          IF               \ read the bulk CSW
1.1.1.2 ! root      150:             0 1 bulk-in-toggle dma-buf >csw-buffer D mps-bulk-in
1.1       root      151:                      ( pt ed-type toggle buffer length mps-bulk-in )
                    152:             my-usb-address bulk-in-ep 7 lshift or
                    153:                      ( pt ed-type toggle buffer length mps address )
                    154:             rw-endpoint swap                    ( TRUE toggle | FALSE toggle )
                    155:             to bulk-in-toggle                   ( TRUE | FALSE )
                    156:             IF
                    157:                    s" Command successful." usb-debug-print
                    158:                    TRUE dup
                    159:             ELSE
                    160:                s" Command failed in CSW stage" usb-debug-print
                    161:                    FALSE dup
                    162:             THEN
                    163:          ELSE
                    164:             s" Command failed while receiving DATA... read CSW..." usb-debug-print
                    165:             \ STALLED: Get CSW to send the CBW again
1.1.1.2 ! root      166:             0 1 bulk-in-toggle dma-buf >csw-buffer D mps-bulk-in
1.1       root      167:                      ( pt ed-type toggle buffer length mps-bulk-in )
                    168:             my-usb-address bulk-in-ep 7 lshift or
                    169:                      ( pt ed-type toggle buffer length mps address )
                    170:             rw-endpoint swap                    ( TRUE toggle | FALSE toggle )
                    171:             to bulk-in-toggle                   ( TRUE | FALSE )
                    172:             IF
1.1.1.2 ! root      173:                s" OK evaluate the CSW ..." usb-debug-print
        !           174:                dma-buf >csw-buffer c + c@ dup TO itest
        !           175:                s" CSW Status: " itest usb-debug-print-val
        !           176:                dup
1.1       root      177:                2 =
                    178:                IF \ Phase Error
                    179:                       s" Phase error do a bulk reset-recovery ..." usb-debug-print
                    180:                   bulk-out-ep bulk-in-ep my-usb-address
                    181:                   bulk-reset-recovery-procedure
                    182:                THEN
                    183:                \ ELSE
                    184:                    \ don't abort if the read fails.
                    185:                    1 =
                    186:                IF \ Command failed
                    187:                   s" Command Failed do a bulk-reset-recovery" usb-debug-print
                    188:                   bulk-out-ep bulk-in-ep my-usb-address
                    189:                   bulk-reset-recovery-procedure
                    190:                THEN
                    191:                 THEN
                    192:             FALSE dup
                    193:          THEN
                    194:       ELSE
                    195:          s" Command failed while Sending CBW ..." usb-debug-print
                    196:          FALSE dup
                    197:       THEN
                    198:       bulk-cnt 1 - TO bulk-cnt
                    199:       bulk-cnt 0=
                    200:       IF
                    201:          2drop FALSE dup
                    202:       THEN
                    203:    REPEAT
                    204: ;
                    205: 
                    206: 
                    207: \ ---------------------------------------------------------------
                    208: \ Method to 1. Send the INQUIRY command 2. Receive and analyse
                    209: \ (pending) INQUIRY data
                    210: \ ---------------------------------------------------------------
                    211: scsi-open
                    212: usb-debug-flag to scsi-param-debug  \ copy debug flag
                    213: 
                    214: 24 CONSTANT inquiry-length    \ was 20
                    215: 
                    216: : inquiry ( -- )
                    217:    s" usb-storage: inquiry" usb-debug-print
1.1.1.2 ! root      218:    dma-buf >command-buffer 1 inquiry-length 80 lun scsi-length-inquiry
1.1       root      219:    ( address tag transfer-len direction lun command-len )
                    220:    build-cbw
1.1.1.2 ! root      221:    inquiry-length dma-buf >command-buffer SCSI-COMMAND-OFFSET +   ( alloc-len address  )
1.1       root      222:    scsi-build-inquiry
1.1.1.2 ! root      223:    dma-buf >response-buffer inquiry-length erase      \ provide clean buffer
        !           224:    dma-buf >response-buffer inquiry-length do-bulk-command
1.1       root      225:    IF
                    226:      s" Successfully read INQUIRY data" usb-debug-print
                    227:      0d emit space space
1.1.1.2 ! root      228:      dma-buf >response-buffer c@  \ get 'Peripheral Device Type' (PDT)
1.1       root      229:      CASE
                    230:         0   OF ." BLOCK-DEV: " ENDOF  \ SCSI Block Device
                    231:         5   OF ." CD-ROM   : " ENDOF
                    232:         7   OF ." OPTICAL  : " ENDOF
                    233:         e   OF ." RED-BLOCK: " ENDOF  \ SCSI Reduced Block Device
                    234:         dup dup OF ." ? (" . 8 emit 29 emit 2 spaces ENDOF
                    235:      ENDCASE
                    236:      space
                    237:      \ create vendor identification in device property
1.1.1.2 ! root      238:      dma-buf >response-buffer 8 + 16 encode-string s" ident-str" property
        !           239:      dma-buf >response-buffer .inquiry-text
1.1       root      240:    ELSE
                    241:      5040 error" (USB) Device transaction error. (inquiry)"
                    242:      ABORT
                    243:    THEN
                    244: ;
                    245: 
                    246: \ ---------------------------------------------------------------
                    247: \ Method to 1. Send the READ CAPACITY command
                    248: \           2. Recieve and analyse the response data
                    249: \ ---------------------------------------------------------------
                    250: 
                    251: : read-capacity ( -- )
                    252:    s" usb-storage: read-capacity" usb-debug-print
1.1.1.2 ! root      253:    dma-buf >command-buffer 1 8  80 lun  scsi-length-read-cap-10
1.1       root      254:    ( address tag transfer-len direction lun command-len )
                    255:    build-cbw 
1.1.1.2 ! root      256:    \ dma-buf >command-buffer 30 dump cr      \ dump the command buffer
        !           257:    dma-buf >command-buffer SCSI-COMMAND-OFFSET +      ( address )   
1.1       root      258:    scsi-build-read-cap-10
                    259:    lun 5 lshift
1.1.1.2 ! root      260:    dma-buf >command-buffer SCSI-COMMAND-OFFSET +      ( address )
1.1       root      261:    read-cap-10>reserved1 c!
                    262: 
1.1.1.2 ! root      263:    dma-buf >response-buffer 8 erase          \ provide clean buffer
        !           264:    dma-buf >response-buffer 8 do-bulk-command
1.1       root      265:    IF
                    266:      s" Successfully read READ CAPACITY data" usb-debug-print
                    267:    ELSE
                    268:      5040 error" (USB) Device transaction error. (capacity)"
                    269:      ABORT
                    270:    THEN
                    271: ;
                    272: 
                    273: 
                    274: \ -------------------------------------------------------------------
                    275: \ Method to 1. Send TEST UNIT READY command 2. Analyse the status
                    276: \ of the response
                    277: \ -------------------------------------------------------------------
                    278: 
                    279: : test-unit-ready ( -- TRUE | FALSE )
1.1.1.2 ! root      280:    dma-buf >command-buffer 1 0 80 lun scsi-length-test-unit-ready    \ was: 0c
1.1       root      281:    ( address tag transfer-len direction lun command-len )
                    282:    build-cbw
1.1.1.2 ! root      283:    dma-buf >command-buffer SCSI-COMMAND-OFFSET +      ( address )
1.1       root      284:    scsi-build-test-unit-ready                ( cdb -- )
1.1.1.2 ! root      285:    dma-buf >response-buffer 0 do-bulk-command
1.1       root      286:    IF
                    287:      s" Successfully read test unit ready data" usb-debug-print
1.1.1.2 ! root      288:      s" Test Unit STATUS availabe in dma-buf >csw-buffer" usb-debug-print
        !           289:      dma-buf >csw-buffer 0c + c@ 0=  IF
1.1       root      290:        s" Test Unit Command Successfully Executed" usb-debug-print
                    291:        TRUE                             ( TRUE )
                    292:      ELSE
                    293:        s" Test Unit Command Failed to execute" usb-debug-print
                    294:        FALSE                            ( FALSE )
                    295:      THEN
                    296:    ELSE
                    297:      \ TRUE ABORT" USB device transaction error. (test-unit-ready)"
                    298:       5040 error" (USB) Device transaction error. (test-unit-ready)"
                    299:       ABORT
                    300:    THEN
                    301: ;
                    302: 
                    303: \ ****************************************************
                    304: \ multiple checks of 'test-unit-ready' with timeout
                    305: \ ****************************************************
                    306: : wait-for-unit-ready            ( -- TRUE|FALSE )
                    307:    s" --> WAIT: test-unit-ready ... " usb-debug-print
                    308:    d# 100                        ( count )   \ up to 10 seconds
                    309:    BEGIN                         ( count )
                    310:       dup 0>                     ( count flag )
                    311:       test-unit-ready      \ dup IF 2b ELSE 2d THEN emit
                    312:       not and    ( count flag )
                    313:       WHILE
                    314:       1-                         ( count )
                    315:       d# 100 wait-proceed        \ wait 100 ms
                    316:    REPEAT                        ( count )
                    317:    0=
                    318:    IF
                    319:       s" **  Device not ready **  " usb-debug-print
                    320:       FALSE
                    321:    ELSE
                    322:       TRUE
                    323:    THEN
                    324: ;
                    325: 
                    326: 
                    327: \ -------------------------------------------------
                    328: \ Method to 1. read sense data 2. analyse sesnse
                    329: \ data(pending)
                    330: \ ------------------------------------------------
                    331: 
                    332: : request-sense ( -- )
                    333:    s" request-sense: Command ready." usb-debug-print
1.1.1.2 ! root      334:    dma-buf >command-buffer 1 12 80 lun scsi-length-request-sense
1.1       root      335:    ( address tag transfer-len direction lun command-len )
                    336:    build-cbw
                    337: 
1.1.1.2 ! root      338:    12 dma-buf >command-buffer SCSI-COMMAND-OFFSET +   ( alloc-len cdb )
        !           339:    scsi-build-request-sense                           ( alloc-len cdb -- )
1.1       root      340: 
1.1.1.2 ! root      341:    dma-buf >response-buffer 12 do-bulk-command
1.1       root      342:    IF
                    343:       s" Read Sense data successfully" usb-debug-print
1.1.1.2 ! root      344:       \   dma-buf >response-buffer 12 dump cr      \ dump the rsponsed message
1.1       root      345:    ELSE
                    346:      \ TRUE ABORT" USB device transaction error. (request-sense)"
                    347:      5040 error" (USB) Device transaction error. (request-sense)"
                    348:      ABORT
                    349:    THEN
                    350: ;
                    351: 
                    352: : start ( -- )
1.1.1.2 ! root      353:    dma-buf >command-buffer 1 0 80 lun scsi-length-start-stop-unit
1.1       root      354:    ( address tag transfer-len direction lun command-len )
                    355:    build-cbw
                    356: 
1.1.1.2 ! root      357:    dma-buf >command-buffer SCSI-COMMAND-OFFSET +      ( cdb )
        !           358:    scsi-const-start scsi-build-start-stop-unit        ( state# cdb -- )
1.1       root      359: 
1.1.1.2 ! root      360:    dma-buf >response-buffer 0 do-bulk-command
1.1       root      361:    IF
                    362:      s" Start successfully" usb-debug-print
                    363:    ELSE
                    364:      \ TRUE ABORT" USB device transaction error. (start)"
                    365:      5040 error" (USB) Device transaction error. (start)"
                    366:      ABORT
                    367:    THEN
                    368: ;
                    369: 
                    370: 
                    371: \ To transmit SCSI Stop command
                    372: 
                    373: : stop ( -- )
1.1.1.2 ! root      374:    dma-buf >command-buffer 1 0 80 lun scsi-length-start-stop-unit
1.1       root      375:    ( address tag transfer-len direction lun command-len )
                    376:    build-cbw
                    377: 
1.1.1.2 ! root      378:    dma-buf >command-buffer SCSI-COMMAND-OFFSET +      ( cdb )
        !           379:    scsi-const-stop scsi-build-start-stop-unit         ( state# cdb -- )
1.1       root      380: 
1.1.1.2 ! root      381:    dma-buf >response-buffer 0 do-bulk-command
1.1       root      382:    IF
                    383:      s" Stop successfully" usb-debug-print
                    384:    ELSE
                    385:      \ TRUE ABORT" USB device transaction error. (stop)"
                    386:      5040 error" (USB) Device transaction error. (stop)"
                    387:      ABORT
                    388:    THEN
                    389: ;
                    390: 
                    391: 
                    392: 0 VALUE temp1
                    393: 0 VALUE temp2
                    394: 0 VALUE temp3
                    395: 
                    396: 
                    397: \ -------------------------------------------------------------
                    398: \          block device's seek
                    399: \ -------------------------------------------------------------
                    400: \ if anything is wrong in the boot device, a seek-request can
                    401: \ occur that exceeds the limits of the device in the following
                    402: \ read-command. So checking is required and the appropriate
                    403: \ return-value has to be returned
                    404: \ Spec requires -1 if operation fails and 0 or 1 if it succeeds !!
                    405: \ -------------------------------------------------------------
                    406: 
                    407: : seek ( pos-lo pos-hi -- status )
                    408:    2dup lxjoin max-block-num block-size * >
                    409:    IF
                    410:       ." ** Seek Error: pos too large ("
                    411:       dup . over . ." -> " max-block-num block-size * .
                    412:       ." ) ** " cr
                    413:       -1                   \ see spec-1275 page 183
                    414:    ELSE
                    415:       s" seek" ihandle-deblocker @ $call-method
                    416:    THEN
                    417: ;
                    418: 
                    419: 
                    420: \ -------------------------------------------------------------
                    421: \          block device's read
                    422: \ -------------------------------------------------------------
                    423: 
                    424: : read ( address length -- actual )
                    425:    s" read" ihandle-deblocker @  $call-method
                    426: ;
                    427: 
                    428: 
                    429: \ -------------------------------------------------------------
                    430: \         read-blocks to be used by deblocker
                    431: \ -------------------------------------------------------------
                    432: : read-blocks ( address block# #blocks -- #read-blocks )
                    433:    2dup + max-block-num >
                    434:    IF
                    435:       ." ** Requested block too large "
                    436:       2dup + ." (" .d ." -> " max-block-num .d
                    437:       bs emit ." ) ... read aborted **" cr
                    438:       nip nip                       \ leave #blocks on stack
                    439:    ELSE
1.1.1.2 ! root      440:       block-size *
        !           441:       dma-buf >command-buffer      ( address block# transfer-len command-buffer )
1.1       root      442:       1 2 pick 80 lun 0c build-cbw ( address block# transfer-len )
                    443:       dup to temp1                 ( address block# transfer-len )
                    444:       block-size /                 ( address block# #blocks )
1.1.1.2 ! root      445:       dma-buf >command-buffer      ( address block# #blocks command-addr )
1.1       root      446:       SCSI-COMMAND-OFFSET +        ( address block# #blocks cdb )
1.1.1.2 ! root      447:       scsi-build-read?             ( address cdblength )
        !           448:       dma-buf >command-buffer 0e + c!   \ update bCBWCBLength-field with resulting CDB length
        !           449:       dma-buf >read-buffer temp1   ( address read-buffer transfer-len )
        !           450:       do-bulk-command              ( address )
1.1       root      451:       IF
1.1.1.2 ! root      452:         dma-buf >read-buffer swap temp1    ( read-buffer address transfer-len )
        !           453:         move
1.1       root      454:         s" Read  data successfully" usb-debug-print
                    455:       ELSE
1.1.1.2 ! root      456:         drop
1.1       root      457:         5040 error" (USB) Device transaction error. (read-blocks)"
                    458:         ABORT
                    459:       THEN
                    460:       temp1 block-size /  ( #read-blocks )
                    461:    THEN
                    462: ;
                    463: 
                    464: \ ------------------------------------------------
                    465: \ To bring the the media to seekable and readable
                    466: \ condition.
                    467: \ ------------------------------------------------
                    468: 
                    469: d# 800 CONSTANT media-ready-retry
                    470: 
                    471: : make-media-ready ( -- )
                    472:    s" usb-storage: make-media-ready" usb-debug-print
                    473:    0  flag !
                    474:    0  count !
                    475:    BEGIN
                    476:       flag @  0=
                    477:    WHILE
                    478:       test-unit-ready IF
                    479:          s" Media ready for access." usb-debug-print
                    480:          1  flag !
                    481:       ELSE
                    482:          count @  1 +  count !
                    483:          count @ media-ready-retry = IF
                    484:             1 flag !
                    485:             5000 error" (USB) Media or drive not ready for this blade."
                    486:             ABORT
                    487:          THEN
                    488:          request-sense
1.1.1.2 ! root      489:          dma-buf >response-buffer scsi-get-sense-ID? ( addr -- false | sense-ID true )
1.1       root      490:          IF
                    491:             ffff00 AND     \ remaining: sense-key ASC
                    492:             CASE
                    493:                023a00 OF   \ MEDIUM NOT PRESENT (02 3a 00)
                    494:                   5010 error" (USB) No Media found! Check for the drawer/inserted media."
                    495:                   ABORT
                    496:                ENDOF
                    497: 
                    498:                020400 OF   \ LOGICAL DRIVE NOT READY - INITIALIZATION REQUIRED
                    499:                   5010 error" (USB) No Media found! Check for the drawer/inserted media."
                    500:                   ABORT
                    501:                ENDOF
                    502: 
                    503:                033000 OF   \ CANNOT READ MEDIUM - UNKNOWN FORMAT
                    504:                   5020 error" (USB) Unknown media format."
                    505:                   ABORT
                    506:                ENDOF
                    507:             ENDCASE
                    508:          THEN
                    509:       THEN
                    510:       d# 10 ms             \ wait maximum 10ms * 800 (=8s)
                    511:    REPEAT
                    512:    usb-debug-flag IF
                    513:       ." make-media-ready finished after "
                    514:       count @ decimal . hex ." tries." cr
                    515:    THEN
                    516: ;
                    517: 
                    518: \ ------------------------------------------------
                    519: \ read and show devices capacity
                    520: \ ------------------------------------------------
                    521: : .showcap
                    522:    space
                    523:    test-unit-ready drop             \ initial command
                    524:    request-sense
1.1.1.2 ! root      525:    dma-buf >response-buffer scsi-get-sense-ID? ( addr -- false | sense-ID true )
1.1       root      526:    IF
                    527:       dup FFFF00 and 023a00 =       ( sense-id flag )
                    528:       IF
                    529:          023a02 =                   \ see sense-codes SPC-3 clause 4.5.6
                    530:          IF
                    531:             ."  Tray Open!"
                    532:          ELSE
                    533:             ."    No Media"
                    534:          THEN
                    535:       ELSE                          ( sense-id )
                    536:          drop
                    537:          wait-for-unit-ready
                    538:          IF
                    539:             read-capacity
1.1.1.2 ! root      540:             dma-buf >response-buffer scsi-get-capacity-10 space .capacity-text
1.1       root      541:          ELSE
                    542:             request-sense
1.1.1.2 ! root      543:             dma-buf >response-buffer scsi-get-sense-ID? ( addr -- false | sense-ID true )
1.1       root      544:             IF
                    545:                dup ff0000 and 040000 =       \ sense-code = 4 ?
                    546:                IF
                    547:                   ." *HW-ERROR*"
                    548:                ELSE
1.1.1.2 ! root      549:                   ( sense-ID )
        !           550:                   CASE
1.1       root      551:                      \ see SPC-3 clause 4.5.6
                    552:                      023a00 OF ."   No Media " ENDOF
                    553:                      023a02 OF ." Tray Open! " ENDOF
                    554:                      dup    OF ."          ? " ENDOF
                    555:                   ENDCASE
                    556:                THEN
                    557:             THEN
                    558:          THEN
                    559:       THEN
                    560:    ELSE
                    561:       ."       ??   "
                    562:    THEN
                    563: ;
                    564: 
                    565: 
                    566: 
                    567: : init-dev-ready
                    568:    test-unit-ready drop
                    569:    4 >r                \ loop-counter
                    570:    0 0
                    571:    BEGIN
                    572:       2drop
                    573:       request-sense
1.1.1.2 ! root      574:       dma-buf >response-buffer scsi-get-sense-data      ( ascq asc sense-key )
1.1       root      575:       0<>  r> 1- dup >r 0<> AND          \ loop-counter or sense-key
                    576:       WHILE
                    577:    REPEAT
                    578:    2drop
                    579:    r> drop
                    580: ;
                    581: 
                    582: 
                    583: 
                    584: scsi-close        \ no further scsi words required
                    585: 
                    586: 
                    587: \ Set up the block-size of the device, using the READ CAPACITY command.
                    588: \ Note: Media must be ready (=> make-media-ready) or READ CAPACITY
                    589: \ might fail!
                    590: 
                    591: : (init-block-size)
                    592:    read-capacity
1.1.1.2 ! root      593:    dma-buf >response-buffer l@ dup 0<>
1.1       root      594:    IF
                    595:       to max-block-num        \ highest block-number
                    596:    ELSE
                    597:       -1 to max-block-num     \ indeterminate
                    598:    THEN
1.1.1.2 ! root      599:    dma-buf >response-buffer 4 + 
1.1       root      600:    l@ to block-size
                    601:    s" usb-storage: block-size=" block-size usb-debug-print-val
                    602: ;
                    603: 
                    604: 
                    605: \ Standard OF methods
                    606: 
                    607: : open ( -- TRUE )
                    608:    s" usb-storage: open" usb-debug-print
1.1.1.2 ! root      609:    (dma-buf-init)
1.1       root      610:    ihandle-bulk s" bulk" (open-package)
                    611: 
                    612:    make-media-ready
                    613:    (init-block-size)           \ Init block-size before opening the deblocker
                    614: 
                    615:    ihandle-deblocker s" deblocker" (open-package)
                    616: 
                    617:    s" disk-label" find-package IF  ( phandle )
                    618:       usb-debug-flag IF ." my-args for disk-label = " my-args swap . . cr THEN
                    619:       my-args rot interpose
                    620:    THEN
                    621:    TRUE                        ( TRUE )
                    622: ;
                    623: 
                    624: 
                    625: : close  ( -- )
                    626:    ihandle-deblocker (close-package)
                    627:    ihandle-bulk (close-package)
1.1.1.2 ! root      628:    (dma-buf-free)
1.1       root      629: ;
                    630: 
                    631: 
                    632: \ Set device name according to type
                    633: 
                    634: : (init-device-name)  ( -- )
                    635:    init-dev-ready
                    636:    inquiry
1.1.1.2 ! root      637:    dma-buf >response-buffer c@
1.1       root      638:    CASE
                    639:       1  OF .showcap s" tape"    device-name ENDOF
                    640:       5  OF .showcap s" cdrom"   device-name s" CDROM found" usb-debug-print ENDOF
                    641:       0  OF .showcap s" sbc-dev" device-name s" SBC Direct access device" usb-debug-print ENDOF
                    642:       7  OF .showcap s" optical" device-name s" Optical memory found" usb-debug-print ENDOF
                    643:       0E OF .showcap s" rbc-dev" device-name s" RBC direct acces device found" usb-debug-print ENDOF
                    644:       \ dup OF s" storage" device-name ENDOF
                    645:    ENDCASE
                    646: ;
                    647: 
                    648: 
                    649: \ Initial device node setup
                    650: 
                    651: : (initial-setup)
1.1.1.2 ! root      652:    (dma-buf-init)
1.1       root      653:    ihandle-bulk s" bulk" (open-package)
1.1.1.2 ! root      654: 
1.1       root      655:    device-init
                    656:    (init-device-name)
                    657:    set-drive-alias
                    658:    200 to block-size       \ Default block-size, will be overwritten in "open"
1.1.1.2 ! root      659: 
1.1       root      660:    ihandle-bulk (close-package)
1.1.1.2 ! root      661:    (dma-buf-free)
1.1       root      662: ;
                    663: 
                    664: (initial-setup)
                    665: 
1.1.1.2 ! root      666: s" leaving usb-storage.fs" usb-debug-print

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.