1 \ *****************************************************************************
2 \ * Copyright (c) 2004, 2008 IBM Corporation
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
10 \ * IBM Corporation - initial implementation
11 \ ****************************************************************************/
13 \ ************************************************
14 \ create a new scsi word-list named 'scsi-words'
15 \ ************************************************
16 vocabulary scsi-words \ create new word list named 'scsi-words'
17 also scsi-words definitions \ place next definitions into new list
19 \ for some commands specific parameters are used, which normally
20 \ need not to be altered. These values are preset at include time
21 \ or explicit by a call of 'scsi-supp-init'
22 false value scsi-param-debug \ common debugging flag
23 d# 0 value scsi-param-size \ length of CDB processed last
24 h# 0 value scsi-param-control \ control word for CDBs as defined in SAM-4
25 d# 0 value scsi-param-errors \ counter for detected errors
27 \ utility to increment error counter
29 scsi-param-errors 1 + to scsi-param-errors
32 \ ***************************************************************************
33 \ SCSI-Command: TEST UNIT READY
34 \ Type: Primary Command (SPC-3 clause 6.33)
35 \ ***************************************************************************
36 \ Forth Word: scsi-build-test-unit-ready ( cdb -- )
37 \ ***************************************************************************
38 \ checks if a device is ready to receive commands
39 \ ***************************************************************************
41 00 CONSTANT scsi-cmd-test-unit-ready
44 /c FIELD test-unit-ready>operation-code \ 00h
45 4 FIELD test-unit-ready>reserved \ unused
46 /c FIELD test-unit-ready>control \ control byte as specified in SAM-4
47 CONSTANT scsi-length-test-unit-ready
50 \ all fields are zeroed
51 : scsi-build-test-unit-ready ( cdb -- )
52 dup scsi-length-test-unit-ready erase ( cdb )
53 scsi-param-control swap test-unit-ready>control c! ( )
54 scsi-length-test-unit-ready to scsi-param-size \ update CDB length
57 \ ***************************************************************************
58 \ SCSI-Command: REPORT LUNS
59 \ Type: Primary Command
60 \ ***************************************************************************
61 \ Forth Word: scsi-build-report-luns ( cdb -- )
62 \ ***************************************************************************
63 \ report all LUNs supported by a device
64 \ ***************************************************************************
66 a0 CONSTANT scsi-cmd-report-luns
69 /c FIELD report-luns>operation-code \ a0h
70 1 FIELD report-luns>reserved \ unused
71 /c FIELD report-luns>select-report \ report select byte
72 3 FIELD report-luns>reserved2 \ unused
73 /l FIELD report-luns>alloc-length \ report length
74 1 FIELD report-luns>reserved3 \ unused
75 /c FIELD report-luns>control \ control byte
76 CONSTANT scsi-length-report-luns
79 \ all fields are zeroed
80 : scsi-build-report-luns ( alloc-len cdb -- )
81 dup scsi-length-report-luns erase \ 12 bytes CDB
82 scsi-cmd-report-luns over ( alloc-len cdb cmd cdb )
83 report-luns>operation-code c! ( alloc-len cdb )
84 scsi-param-control over report-luns>control c! ( alloc-len cdb )
85 report-luns>alloc-length l! \ size of Data-In Buffer
86 scsi-length-report-luns to scsi-param-size \ update CDB length
89 \ ***************************************************************************
90 \ SCSI-Command: REQUEST SENSE
91 \ Type: Primary Command (SPC-3 clause 6.27)
92 \ ***************************************************************************
93 \ Forth Word: scsi-build-request-sense ( cdb -- )
94 \ ***************************************************************************
95 \ for return data a buffer of at least 252 bytes must be present!
96 \ see spec: SPC-3 (r23) / clauses 4.5 and 6.27
97 \ ***************************************************************************
99 03 CONSTANT scsi-cmd-request-sense
102 /c FIELD request-sense>operation-code \ 03h
103 3 FIELD request-sense>reserved \ unused
104 /c FIELD request-sense>allocation-length \ buffer-length for data response
105 /c FIELD request-sense>control \ control byte as specified in SAM-4
106 CONSTANT scsi-length-request-sense
109 : scsi-build-request-sense ( alloc-len cdb -- )
110 >r ( alloc-len ) ( R: -- cdb )
111 r@ scsi-length-request-sense erase ( alloc-len )
112 scsi-cmd-request-sense r@ ( alloc-len cmd cdb )
113 request-sense>operation-code c! ( alloc-len )
114 dup d# 252 > \ buffer length too big ?
117 drop d# 252 \ replace with 252
119 dup d# 18 < \ allocated buffer too small ?
122 drop 0 \ reject return data
125 r@ request-sense>allocation-length c! ( )
126 scsi-param-control r> request-sense>control c! ( alloc-len cdb ) ( R: cdb -- )
127 scsi-length-request-sense to scsi-param-size \ update CDB length
130 \ ----------------------------------------
131 \ SCSI-Response: SENSE_DATA
132 \ ----------------------------------------
133 70 CONSTANT scsi-response(request-sense-0)
134 71 CONSTANT scsi-response(request-sense-1)
137 /c FIELD sense-data>response-code \ 70h (current errors) or 71h (deferred errors)
138 /c FIELD sense-data>obsolete
139 /c FIELD sense-data>sense-key \ D3..D0 = sense key, D7 = EndOfMedium
140 /l FIELD sense-data>info
141 /c FIELD sense-data>alloc-length \ <= 244 (for max size)
142 /l FIELD sense-data>command-info
143 /c FIELD sense-data>asc \ additional sense key
144 /c FIELD sense-data>ascq \ additional sense key qualifier
145 /c FIELD sense-data>unit-code
146 3 FIELD sense-data>key-specific
147 /c FIELD sense-data>add-sense-bytes \ start of appended extra bytes
148 CONSTANT scsi-length-sense-data
150 \ ----------------------------------------
151 \ get from SCSI response block:
152 \ - Additional Sense Code Qualifier
153 \ - Additional Sense Code
155 \ ----------------------------------------
156 \ Forth Word: scsi-get-sense-data ( addr -- ascq asc sense-key )
157 \ ----------------------------------------
158 : scsi-get-sense-data ( addr -- ascq asc sense-key )
160 r@ sense-data>response-code c@ 7f and 72 >= IF
162 r@ 2 + c@ ( ascq asc )
163 r> 1 + c@ 0f and ( ascq asc sense-key )
165 r@ sense-data>ASCQ c@ ( ascq )
166 r@ sense-data>ASC c@ ( ascq asc )
167 r> sense-data>sense-key c@ 0f and ( ascq asc sense-key ) ( R: addr -- )
171 \ --------------------------------------------------------------------------
172 \ Forth Word: scsi-get-sense-data? ( addr -- false | ascq asc sense-key true )
173 \ --------------------------------------------------------------------------
174 : scsi-get-sense-data? ( addr -- false | ascq asc sense-key true )
176 sense-data>response-code c@
177 7e AND dup 70 = swap 72 = or \ Response code (some devices have MSB set)
179 scsi-get-sense-data TRUE
181 drop FALSE \ drop addr
186 \ --------------------------------------------------------------------------
187 \ Forth Word: scsi-get-sense-ID? ( addr -- false | sense-ID true )
188 \ same as scsi-get-sense-data? but returns
189 \ a single word composed of: sense-key<<16 | asc<<8 | ascq
190 \ --------------------------------------------------------------------------
191 : scsi-get-sense-ID? ( addr -- false | ascq asc sense-key true )
193 sense-data>response-code c@
194 7e AND 70 = \ Response code (some devices have MSB set)
196 scsi-get-sense-data ( ascq asc sense-key )
197 10 lshift ( ascq asc sense-key16 )
198 swap 8 lshift or ( ascq sense-key+asc )
199 swap or \ 24-bit sense-ID ( sense-key+asc+ascq )
202 drop FALSE \ drop addr
206 \ ***************************************************************************
207 \ SCSI-Command: INQUIRY
208 \ Type: Primary Command (SPC-3 clause 6.4)
209 \ ***************************************************************************
210 \ Forth Word: scsi-build-inquiry ( alloc-len cdb -- )
211 \ ***************************************************************************
213 12 CONSTANT scsi-cmd-inquiry
217 /c FIELD inquiry>operation-code \ 0x12
218 /c FIELD inquiry>reserved \ + EVPD-Bit (vital product data)
219 /c FIELD inquiry>page-code \ page code for vital product data (if used)
220 /w FIELD inquiry>allocation-length \ length of Data-In-Buffer
221 /c FIELD inquiry>control \ control byte as specified in SAM-4
222 CONSTANT scsi-length-inquiry
224 \ Setup command INQUIRY
225 : scsi-build-inquiry ( alloc-len cdb -- )
226 dup scsi-length-inquiry erase \ 6 bytes CDB
227 scsi-cmd-inquiry over ( alloc-len cdb cmd cdb )
228 inquiry>operation-code c! ( alloc-len cdb )
229 scsi-param-control over inquiry>control c! ( alloc-len cdb )
230 inquiry>allocation-length w! \ size of Data-In Buffer
231 scsi-length-inquiry to scsi-param-size \ update CDB length
234 \ ----------------------------------------
235 \ block structure of inquiry return data:
236 \ ----------------------------------------
238 /c FIELD inquiry-data>peripheral \ qualifier and device type
239 /c FIELD inquiry-data>reserved1
240 /c FIELD inquiry-data>version \ supported SCSI version (1,2,3)
241 /c FIELD inquiry-data>data-format
242 /c FIELD inquiry-data>add-length \ total block length - 4
243 /c FIELD inquiry-data>flags1
244 /c FIELD inquiry-data>flags2
245 /c FIELD inquiry-data>flags3
246 d# 8 FIELD inquiry-data>vendor-ident \ vendor string
247 d# 16 FIELD inquiry-data>product-ident \ device string
248 /l FIELD inquiry-data>product-revision \ revision string
249 d# 20 FIELD inquiry-data>vendor-specific \ optional params
250 \ can be increased by vendor specific fields
251 CONSTANT scsi-length-inquiry-data
253 \ ***************************************************************************
254 \ SCSI-Command: READ CAPACITY (10)
255 \ Type: Block Command (SBC-3 clause 5.12)
256 \ ***************************************************************************
257 \ Forth Word: scsi-build-read-capacity-10 ( cdb -- )
258 \ ***************************************************************************
259 25 CONSTANT scsi-cmd-read-capacity-10 \ command code
261 STRUCT \ SCSI 10-byte CDB structure
262 /c FIELD read-cap-10>operation-code
263 /c FIELD read-cap-10>reserved1
264 /l FIELD read-cap-10>lba
265 /w FIELD read-cap-10>reserved2
266 /c FIELD read-cap-10>reserved3
267 /c FIELD read-cap-10>control
268 CONSTANT scsi-length-read-cap-10
270 \ Setup READ CAPACITY (10) command
271 : scsi-build-read-cap-10 ( cdb -- )
272 dup scsi-length-read-cap-10 erase ( cdb )
273 scsi-cmd-read-capacity-10 over ( cdb cmd cdb )
274 read-cap-10>operation-code c! ( cdb )
275 scsi-param-control swap read-cap-10>control c! ( )
276 scsi-length-read-cap-10 to scsi-param-size \ update CDB length
279 \ ----------------------------------------
280 \ get from SCSI response block:
281 \ - Additional Sense Code Qualifier
282 \ - Additional Sense Code
284 \ ----------------------------------------
285 \ Forth Word: scsi-get-capacity-10 ( addr -- block-size #blocks )
286 \ ----------------------------------------
289 /l FIELD read-cap-10-data>max-lba
290 /l FIELD read-cap-10-data>block-size
291 CONSTANT scsi-length-read-cap-10-data
294 : scsi-get-capacity-10 ( addr -- block-size #blocks )
295 >r ( addr -- ) ( R: -- addr )
296 r@ read-cap-10-data>block-size l@ ( block-size )
297 r> read-cap-10-data>max-lba l@ ( block-size #blocks ) ( R: addr -- )
300 \ ***************************************************************************
301 \ SCSI-Command: READ CAPACITY (16)
302 \ Type: Block Command (SBC-3 clause 5.13)
303 \ ***************************************************************************
304 \ Forth Word: scsi-build-read-capacity-16 ( cdb -- )
305 \ ***************************************************************************
306 9e CONSTANT scsi-cmd-read-capacity-16 \ command code
308 STRUCT \ SCSI 16-byte CDB structure
309 /c FIELD read-cap-16>operation-code
310 /c FIELD read-cap-16>service-action
311 /l FIELD read-cap-16>lba-high
312 /l FIELD read-cap-16>lba-low
313 /l FIELD read-cap-16>allocation-length \ should be 32
314 /c FIELD read-cap-16>reserved
315 /c FIELD read-cap-16>control
316 CONSTANT scsi-length-read-cap-16
318 \ Setup READ CAPACITY (16) command
319 : scsi-build-read-cap-16 ( cdb -- )
321 scsi-length-read-cap-16 erase ( )
322 scsi-cmd-read-capacity-16 ( code )
323 r@ read-cap-16>operation-code c! ( )
324 10 r@ read-cap-16>service-action c!
325 d# 32 \ response size 32 bytes
326 r@ read-cap-16>allocation-length l! ( )
327 scsi-param-control r> read-cap-16>control c! ( R: cdb -- )
328 scsi-length-read-cap-16 to scsi-param-size \ update CDB length
331 \ ----------------------------------------
332 \ get from SCSI response block:
333 \ - Block Size (in Bytes)
335 \ ----------------------------------------
336 \ Forth Word: scsi-get-capacity-16 ( addr -- block-size #blocks )
337 \ ----------------------------------------
338 \ Block structure for return data
340 /l FIELD read-cap-16-data>max-lba-high \ upper quadlet of Max-LBA
341 /l FIELD read-cap-16-data>max-lba-low \ lower quadlet of Max-LBA
342 /l FIELD read-cap-16-data>block-size \ logical block length in bytes
343 /c FIELD read-cap-16-data>protect \ type of protection (4 bits)
344 /c FIELD read-cap-16-data>exponent \ logical blocks per physical blocks
345 /w FIELD read-cap-16-data>lowest-aligned \ first LBA of a phsy. block
346 10 FIELD read-cap-16-data>reserved \ 16 reserved bytes
347 CONSTANT scsi-length-read-cap-16-data \ results in 32
350 : scsi-get-capacity-16 ( addr -- block-size #blocks )
352 r@ read-cap-16-data>block-size l@ ( block-size )
353 r@ read-cap-16-data>max-lba-high l@ ( block-size #blocks-high )
354 d# 32 lshift ( block-size #blocks-upper )
355 r> read-cap-16-data>max-lba-low l@ + ( block-size #blocks ) ( R: addr -- )
358 \ ***************************************************************************
359 \ SCSI-Command: MODE SENSE (10)
360 \ Type: Primary Command (SPC-3 clause 6.10)
361 \ ***************************************************************************
362 \ Forth Word: scsi-build-mode-sense-10 ( alloc-len subpage page cdb -- )
363 \ ***************************************************************************
364 5a CONSTANT scsi-cmd-mode-sense-10
368 /c FIELD mode-sense-10>operation-code
369 /c FIELD mode-sense-10>res-llbaa-dbd-res
370 /c FIELD mode-sense-10>pc-page-code \ page code + page control
371 /c FIELD mode-sense-10>sub-page-code
372 3 FIELD mode-sense-10>reserved2
373 /w FIELD mode-sense-10>allocation-length
374 /c FIELD mode-sense-10>control
375 CONSTANT scsi-length-mode-sense-10
377 : scsi-build-mode-sense-10 ( alloc-len subpage page cdb -- )
378 >r ( alloc-len subpage page ) ( R: -- cdb )
379 r@ scsi-length-mode-sense-10 erase \ 10 bytes CDB
380 scsi-cmd-mode-sense-10 ( alloc-len subpage page cmd )
381 r@ mode-sense-10>operation-code c! ( alloc-len subpage page )
382 10 r@ mode-sense-10>res-llbaa-dbd-res c! \ long LBAs accepted
383 r@ mode-sense-10>pc-page-code c! ( alloc-len subpage )
384 r@ mode-sense-10>sub-page-code c! ( alloc-len )
385 r@ mode-sense-10>allocation-length w! ( )
387 scsi-param-control r> mode-sense-10>control c! ( R: cdb -- )
388 scsi-length-mode-sense-10 to scsi-param-size \ update CDB length
391 \ return data processing
392 \ (see spec: SPC-3 clause 7.4.3)
395 /w FIELD mode-sense-10-data>head-length
396 /c FIELD mode-sense-10-data>head-medium
397 /c FIELD mode-sense-10-data>head-param
398 /c FIELD mode-sense-10-data>head-longlba
399 /c FIELD mode-sense-10-data>head-reserved
400 /w FIELD mode-sense-10-data>head-descr-len
401 CONSTANT scsi-length-mode-sense-10-data
403 \ ****************************************
404 \ This function shows the mode page header
405 \ helpful for further analysis
406 \ ****************************************
407 : .mode-sense-data ( addr -- )
409 dup mode-sense-10-data>head-length
410 w@ ." Mode Length: " .d space
411 dup mode-sense-10-data>head-medium
412 c@ ." / Medium Type: " .d space
413 dup mode-sense-10-data>head-longlba
414 c@ ." / Long LBA: " .d space
415 mode-sense-10-data>head-descr-len
416 w@ ." / Descr. Length: " .d
419 \ ***************************************************************************
420 \ SCSI-Command: READ (6)
421 \ Type: Block Command (SBC-3 clause 5.7)
422 \ ***************************************************************************
423 \ Forth Word: scsi-build-read-6 ( block# #blocks cdb -- )
424 \ ***************************************************************************
425 \ this SCSI command uses 21 bits to represent start LBA
426 \ and 8 bits to specify the numbers of blocks to read
427 \ The value of 0 blocks is interpreted as 256 blocks
430 08 CONSTANT scsi-cmd-read-6
434 /c FIELD read-6>operation-code \ 08h
435 /c FIELD read-6>block-address-msb \ upper 5 bits
436 /w FIELD read-6>block-address \ lower 16 bits
437 /c FIELD read-6>length \ number of blocks to read
438 /c FIELD read-6>control \ CDB control
439 CONSTANT scsi-length-read-6
441 : scsi-build-read-6 ( block# #blocks cdb -- )
442 >r ( block# #blocks ) ( R: -- cdb )
443 r@ scsi-length-read-6 erase \ 6 bytes CDB
444 scsi-cmd-read-6 r@ read-6>operation-code c! ( block# #blocks )
446 \ check block count to read (#blocks)
447 dup d# 255 > \ #blocks exceeded limit ?
450 drop 1 \ replace with any valid number
452 r@ read-6>length c! \ set #blocks to read
454 \ check starting block number (block#)
455 dup 1fffff > \ check address upper limit
458 drop \ remove original block#
459 1fffff \ replace with any valid address
462 r@ read-6>block-address-msb c! \ set upper 5 bits
464 r@ read-6>block-address w! \ set lower 16 bits
465 scsi-param-control r> read-6>control c! ( R: cdb -- )
466 scsi-length-read-6 to scsi-param-size \ update CDB length
469 \ ***************************************************************************
470 \ SCSI-Command: READ (10)
471 \ Type: Block Command (SBC-3 clause 5.8)
472 \ ***************************************************************************
473 \ Forth Word: scsi-build-read-10 ( block# #blocks cdb -- )
474 \ ***************************************************************************
476 28 CONSTANT scsi-cmd-read-10
480 /c FIELD read-10>operation-code
481 /c FIELD read-10>protect
482 /l FIELD read-10>block-address \ logical block address (32bits)
483 /c FIELD read-10>group
484 /w FIELD read-10>length \ transfer length (16-bits)
485 /c FIELD read-10>control
486 CONSTANT scsi-length-read-10
488 : scsi-build-read-10 ( block# #blocks cdb -- )
489 >r ( block# #blocks ) ( R: -- cdb )
490 r@ scsi-length-read-10 erase \ 10 bytes CDB
491 scsi-cmd-read-10 r@ read-10>operation-code c! ( block# #blocks )
492 r@ read-10>length w! ( block# )
493 r@ read-10>block-address l! ( )
494 scsi-param-control r> read-10>control c! ( R: cdb -- )
495 scsi-length-read-10 to scsi-param-size \ update CDB length
498 \ ***************************************************************************
499 \ SCSI-Command: READ (12)
500 \ Type: Block Command (SBC-3 clause 5.9)
501 \ ***************************************************************************
502 \ Forth Word: scsi-build-read-12 ( block# #blocks cdb -- )
503 \ ***************************************************************************
505 a8 CONSTANT scsi-cmd-read-12
509 /c FIELD read-12>operation-code \ code: a8
510 /c FIELD read-12>protect \ RDPROTECT, DPO, FUA, FUA_NV
511 /l FIELD read-12>block-address \ lba
512 /l FIELD read-12>length \ transfer length (32bits)
513 /c FIELD read-12>group \ group number
514 /c FIELD read-12>control
515 CONSTANT scsi-length-read-12
517 : scsi-build-read-12 ( block# #blocks cdb -- )
518 >r ( block# #blocks ) ( R: -- cdb )
519 r@ scsi-length-read-12 erase \ 12 bytes CDB
520 scsi-cmd-read-12 r@ read-12>operation-code c! ( block# #blocks )
521 r@ read-12>length l! ( block# )
522 r@ read-12>block-address l! ( )
523 scsi-param-control r> read-12>control c! ( R: cdb -- )
524 scsi-length-read-12 to scsi-param-size \ update CDB length
527 \ ***************************************************************************
528 \ SCSI-Command: READ with autodetection of required command
529 \ read(10) or read(12) depending on parameter size
530 \ (read(6) removed because obsolete in some cases (USB))
531 \ Type: Block Command
532 \ ***************************************************************************
533 \ Forth Word: scsi-build-read? ( block# #blocks cdb -- )
535 \ +----------------+---------------------------|
536 \ | block# (lba) | #block (transfer-length) |
537 \ +-----------+----------------+---------------------------|
538 \ | read-6 | 16-Bits | 8 Bits |
539 \ | read-10 | 32-Bits | 16 Bits |
540 \ | read-12 | 32-Bits | 32 Bits |
541 \ ***************************************************************************
542 : scsi-build-read? ( block# #blocks cdb -- length )
543 over ( block# #blocks cdb #blocks )
544 fffe > \ tx-length (#blocks) exceeds 16-bit limit ?
546 scsi-build-read-12 ( block# #blocks cdb -- )
547 scsi-length-read-12 ( length )
548 ELSE ( block# #blocks cdb )
549 scsi-build-read-10 ( block# #blocks cdb -- )
550 scsi-length-read-10 ( length )
554 \ ***************************************************************************
555 \ SCSI-Command: START STOP UNIT
556 \ Type: Block Command (SBC-3 clause 5.19)
557 \ ***************************************************************************
558 \ Forth Word: scsi-build-start-stop-unit ( state# cdb -- )
559 \ ***************************************************************************
561 1b CONSTANT scsi-cmd-start-stop-unit
565 /c FIELD start-stop-unit>operation-code
566 /c FIELD start-stop-unit>immed
567 /w FIELD start-stop-unit>reserved
568 /c FIELD start-stop-unit>pow-condition
569 /c FIELD start-stop-unit>control
570 CONSTANT scsi-length-start-stop-unit
572 \ START/STOP constants
573 \ (see spec: SBC-3 clause 5.19)
574 f1 CONSTANT scsi-const-active-power \ param used for start-stop-unit
575 f2 CONSTANT scsi-const-idle-power \ param used for start-stop-unit
576 f3 CONSTANT scsi-const-standby-power \ param used for start-stop-unit
577 3 CONSTANT scsi-const-load \ param used for start-stop-unit
578 2 CONSTANT scsi-const-eject \ param used for start-stop-unit
579 1 CONSTANT scsi-const-start
580 0 CONSTANT scsi-const-stop
582 : scsi-build-start-stop-unit ( state# cdb -- )
583 >r ( state# ) ( R: -- cdb )
584 r@ scsi-length-start-stop-unit erase \ 6 bytes CDB
585 scsi-cmd-start-stop-unit r@ start-stop-unit>operation-code c!
588 4 lshift \ shift to upper nibble
590 r@ start-stop-unit>pow-condition c! ( )
591 scsi-param-control r> start-stop-unit>control c! ( R: cdb -- )
592 scsi-length-start-stop-unit to scsi-param-size \ update CDB length
595 \ ***************************************************************************
596 \ SCSI-Command: SEEK(10)
597 \ Type: Block Command (obsolete)
598 \ ***************************************************************************
599 \ Forth Word: scsi-build-seek ( state# cdb -- )
600 \ Obsolete function (last listed in spec SBC / Nov. 1997)
601 \ implemented only for the sake of completeness
602 \ ***************************************************************************
604 2b CONSTANT scsi-cmd-seek
608 /c FIELD seek>operation-code
609 /c FIELD seek>reserved1
611 3 FIELD seek>reserved2
612 /c FIELD seek>control
613 CONSTANT scsi-length-seek
615 : scsi-build-seek ( lba cdb -- )
616 >r ( lba ) ( R: -- cdb )
617 r@ scsi-length-seek erase \ 10 bytes CDB
618 scsi-cmd-seek r@ seek>operation-code c!
619 r> seek>lba l! ( ) ( R: cdb -- )
620 scsi-length-seek to scsi-param-size \ update CDB length
623 \ ****************************************************************************
624 \ CDROM media event stuff
625 \ ****************************************************************************
628 /w FIELD media-event-data-len
629 /c FIELD media-event-nea-class
630 /c FIELD media-event-supp-class
631 /l FIELD media-event-data
632 CONSTANT scsi-length-media-event
634 : scsi-build-get-media-event ( cdb -- )
645 \ ***************************************************************************
646 \ SCSI-Utility: .sense-code
647 \ ***************************************************************************
648 \ this utility prints a string associated to the sense code
649 \ see specs: SPC-3/r23 clause 4.5.6
650 \ ***************************************************************************
651 : .sense-text ( scode -- )
654 1 OF s" RECOVERED ERR" ENDOF
655 2 OF s" NOT READY" ENDOF
656 3 OF s" MEDIUM ERROR" ENDOF
657 4 OF s" HARDWARE ERR" ENDOF
658 5 OF s" ILLEGAL REQUEST" ENDOF
659 6 OF s" UNIT ATTENTION" ENDOF
660 7 OF s" DATA PROTECT" ENDOF
661 8 OF s" BLANK CHECK" ENDOF
662 9 OF s" VENDOR SPECIFIC" ENDOF
663 a OF s" COPY ABORTED" ENDOF
664 b OF s" ABORTED COMMAND" ENDOF
665 d OF s" VOLUME OVERFLOW" ENDOF
666 e OF s" MISCOMPARE" ENDOF
667 dup OF s" UNKNOWN" ENDOF
672 \ ***************************************************************************
673 \ SCSI-Utility: .status-code
674 \ ***************************************************************************
675 \ this utility prints a string associated to the status code
676 \ see specs: SAM-3/r14 clause 5.3
677 \ ***************************************************************************
678 : .status-text ( stat -- )
681 02 OF s" CHECK CONDITION" ENDOF
682 04 OF s" CONDITION MET" ENDOF
684 18 OF s" RESERVATION CONFLICT" ENDOF
685 28 OF s" TASK SET FULL" ENDOF
686 30 OF s" ACA ACTIVE" ENDOF
687 40 OF s" TASK ABORTED" ENDOF
688 dup OF s" UNKNOWN" ENDOF
693 \ ***************************************************************************
694 \ SCSI-Utility: .capacity-text
695 \ ***************************************************************************
696 \ utility that shows total capacity on screen by use of the return data
697 \ from read-capacity calculation is SI conform (base 10)
698 \ ***************************************************************************
699 \ sub function to print a 3 digit decimal
700 \ number with 2 post decimal positions xxx.yy
701 : .dec3-2 ( prenum postnum -- )
703 base @ >r \ save actual base setting
704 decimal \ show decimal values
706 dup 9 <= IF 30 emit THEN .d \ 3 pre-decimal, right aligned
707 r> base ! \ restore base
710 : .capacity-text ( block-size #blocks -- )
711 scsi-param-debug \ debugging flag set ?
712 IF \ show additional info
715 ." LBAs: " .d \ highest logical block number
716 ." / Block-Size: " .d
717 ." / Total Capacity: "
719 * \ calculate total capacity
720 dup d# 1000000000000 >= \ check terabyte limit
722 d# 1000000000000 /mod
724 d# 10000000000 / \ limit remainder to two digits
725 .dec3-2 ." TB" \ show terabytes as xxx.yy
727 dup d# 1000000000 >= \ check gigabyte limit
732 .dec3-2 ." GB" \ show gigabytes as xxx.yy
736 d# 1000000 /mod \ check mega byte limit
739 .dec3-2 ." MB" \ show megabytes as xxx.yy
741 dup d# 1000 >= \ check kilo byte limit
755 \ ***************************************************************************
756 \ SCSI-Utility: .inquiry-text ( addr -- )
757 \ ***************************************************************************
758 \ utility that shows:
759 \ vendor-ident product-ident and revision
760 \ from an inquiry return data block (addr)
761 \ ***************************************************************************
762 : .inquiry-text ( addr -- )
763 22 emit \ enclose text with "
764 dup inquiry-data>vendor-ident 8 type space
765 dup inquiry-data>product-ident 10 type space
766 inquiry-data>product-revision 4 type
770 \ ***************************************************************************
771 \ SCSI-Utility: scsi-supp-init ( -- )
772 \ ***************************************************************************
773 \ utility that helps to ensure that parameters are set to valid values
774 : scsi-supp-init ( -- )
775 false to scsi-param-debug \ no debug strings
776 h# 0 to scsi-param-size
777 h# 0 to scsi-param-control \ common CDB control byte
778 d# 0 to scsi-param-errors \ local errors (param limits)
781 \ ***************************************************************************
782 \ Constants used by SCSI controller's execute-scsi-command
783 \ ***************************************************************************
784 true CONSTANT scsi-dir-read
785 false CONSTANT scsi-dir-write
788 \ ***************************************************************************
790 \ ***************************************************************************
791 0 VALUE scsi-context \ addr of word list on top
794 \ ****************************************************************************
795 \ open scsi-support by adding a new word list on top of search path
796 \ precondition: scsi-support.fs must have been included
797 \ ****************************************************************************
799 also scsi-words \ append scsi word-list
800 context to scsi-context \ save for close process
801 scsi-supp-init \ preset all scsi-param-xxx values
804 space ." SCSI-SUPPORT OPENED" cr
809 \ ****************************************************************************
810 \ close scsi-session and remove scsi word list (if exists)
811 \ ****************************************************************************
812 \ if 'previous' is used without a preceding 'also' all forth words are lost !
813 \ ****************************************************************************
815 \ FIXME This only works if scsi-words is the last vocabulary on the stack
816 \ Instead we could use get-order to find us on the "wordlist stack",
817 \ remove us and write the wordlist stack back with set-order.
818 \ BUT: Is this worth the effort?
822 space ." Closing SCSI-SUPPORT .. " cr
824 context scsi-context = \ scsi word list still active ?
826 scsi-param-errors 0<> \ any errors occurred ?
828 cr ." ** WARNING: " scsi-param-errors .d
829 ." SCSI Errors occurred ** " cr
831 previous \ remove scsi word list on top
832 0 to scsi-context \ prevent from being misinterpreted
834 cr ." ** WARNING: Trying to close non-open SCSI-SUPPORT (1) ** " cr
843 s" scsi-init" $find drop \ return execution pointer, when included
845 previous \ remove scsi word list from search path
846 definitions \ place next definitions into previous list