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 (10)
421
\ Type: Block Command (SBC-3 clause 5.8)
422
\ ***************************************************************************
423
\ Forth Word: scsi-build-read-10 ( block# #blocks cdb -- )
424
\ ***************************************************************************
426
28 CONSTANT scsi-cmd-read-10
430
/c FIELD read-10>operation-code
431
/c FIELD read-10>protect
432
/l FIELD read-10>block-address \ logical block address (32bits)
433
/c FIELD read-10>group
434
/w FIELD read-10>length \ transfer length (16-bits)
435
/c FIELD read-10>control
436
CONSTANT scsi-length-read-10
438
: scsi-build-read-10 ( block# #blocks cdb -- )
439
>r ( block# #blocks ) ( R: -- cdb )
440
r@ scsi-length-read-10 erase \ 10 bytes CDB
441
scsi-cmd-read-10 r@ read-10>operation-code c! ( block# #blocks )
442
r@ read-10>length w! ( block# )
443
r@ read-10>block-address l! ( )
444
scsi-param-control r> read-10>control c! ( R: cdb -- )
445
scsi-length-read-10 to scsi-param-size \ update CDB length
448
\ ***************************************************************************
449
\ SCSI-Command: READ (12)
450
\ Type: Block Command (SBC-3 clause 5.9)
451
\ ***************************************************************************
452
\ Forth Word: scsi-build-read-12 ( block# #blocks cdb -- )
453
\ ***************************************************************************
455
a8 CONSTANT scsi-cmd-read-12
459
/c FIELD read-12>operation-code \ code: a8
460
/c FIELD read-12>protect \ RDPROTECT, DPO, FUA, FUA_NV
461
/l FIELD read-12>block-address \ lba
462
/l FIELD read-12>length \ transfer length (32bits)
463
/c FIELD read-12>group \ group number
464
/c FIELD read-12>control
465
CONSTANT scsi-length-read-12
467
: scsi-build-read-12 ( block# #blocks cdb -- )
468
>r ( block# #blocks ) ( R: -- cdb )
469
r@ scsi-length-read-12 erase \ 12 bytes CDB
470
scsi-cmd-read-12 r@ read-12>operation-code c! ( block# #blocks )
471
r@ read-12>length l! ( block# )
472
r@ read-12>block-address l! ( )
473
scsi-param-control r> read-12>control c! ( R: cdb -- )
474
scsi-length-read-12 to scsi-param-size \ update CDB length
477
\ ***************************************************************************
478
\ SCSI-Command: READ (16)
479
\ Type: Block Command
480
\ ***************************************************************************
481
\ Forth Word: scsi-build-read-16 ( block# #blocks cdb -- )
482
\ ***************************************************************************
484
88 CONSTANT scsi-cmd-read-16
488
/c FIELD read-16>operation-code \ code: 88
489
/c FIELD read-16>protect \ RDPROTECT, DPO, FUA, FUA_NV
490
/x FIELD read-16>block-address \ lba
491
/l FIELD read-16>length \ transfer length (32bits)
492
/c FIELD read-16>group \ group number
493
/c FIELD read-16>control
494
CONSTANT scsi-length-read-16
496
: scsi-build-read-16 ( block# #blocks cdb -- )
497
>r ( block# #blocks ) ( R: -- cdb )
498
r@ scsi-length-read-16 erase \ 16 bytes CDB
499
scsi-cmd-read-16 r@ read-16>operation-code c! ( block# #blocks )
500
r@ read-16>length l! ( block# )
501
r@ read-16>block-address x! ( )
502
scsi-param-control r> read-16>control c! ( R: cdb -- )
503
scsi-length-read-16 to scsi-param-size \ update CDB length
506
\ ***************************************************************************
507
\ SCSI-Command: READ with autodetection of required command
508
\ read(10) or read(12) depending on parameter size
509
\ (read(6) removed because obsolete in some cases (USB))
510
\ Type: Block Command
511
\ ***************************************************************************
512
\ Forth Word: scsi-build-read? ( block# #blocks cdb -- )
514
\ +----------------+---------------------------|
515
\ | block# (lba) | #block (transfer-length) |
516
\ +-----------+----------------+---------------------------|
517
\ | read-6 | 16-Bits | 8 Bits |
518
\ | read-10 | 32-Bits | 16 Bits |
519
\ | read-12 | 32-Bits | 32 Bits |
520
\ ***************************************************************************
521
: scsi-build-read? ( block# #blocks cdb -- length )
522
over ( block# #blocks cdb #blocks )
523
fffe > \ tx-length (#blocks) exceeds 16-bit limit ?
525
scsi-build-read-12 ( block# #blocks cdb -- )
526
scsi-length-read-12 ( length )
527
ELSE ( block# #blocks cdb )
528
scsi-build-read-10 ( block# #blocks cdb -- )
529
scsi-length-read-10 ( length )
533
\ ***************************************************************************
534
\ SCSI-Command: WRITE (10)
535
\ Type: Block Command
536
\ ***************************************************************************
537
\ Forth Word: scsi-build-write-10 ( block# #blocks cdb -- )
538
\ ***************************************************************************
540
2A CONSTANT scsi-cmd-write-10
544
/c FIELD write-10>operation-code
545
/c FIELD write-10>protect
546
/l FIELD write-10>block-address \ logical block address (32bits)
547
/c FIELD write-10>group
548
/w FIELD write-10>length \ transfer length (16-bits)
549
/c FIELD write-10>control
550
CONSTANT scsi-length-write-10
552
: scsi-build-write-10 ( block# #blocks cdb -- )
553
>r ( block# #blocks ) ( R: -- cdb )
554
r@ scsi-length-write-10 erase \ 10 bytes CDB
555
scsi-cmd-write-10 r@ write-10>operation-code c! ( block# #blocks )
556
r@ write-10>length w! ( block# )
557
r@ write-10>block-address l! ( )
558
scsi-param-control r> write-10>control c! ( R: cdb -- )
559
scsi-length-write-10 to scsi-param-size \ update CDB length
562
\ ***************************************************************************
563
\ SCSI-Command: WRITE (16)
564
\ Type: Block Command
565
\ ***************************************************************************
566
\ Forth Word: scsi-build-write-16 ( block# #blocks cdb -- )
567
\ ***************************************************************************
569
8A CONSTANT scsi-cmd-write-16
573
/c FIELD write-16>operation-code
574
/c FIELD write-16>protect \ RDPROTECT, DPO, FUA, FUA_NV
575
/x FIELD write-16>block-address \ LBA
576
/l FIELD write-16>length \ Transfer length (32-bits)
577
/c FIELD write-16>group \ Group number
578
/c FIELD write-16>control
579
CONSTANT scsi-length-write-16
581
: scsi-build-write-16 ( block# #blocks cdb -- )
582
>r ( block# #blocks ) ( R: -- cdb )
583
r@ scsi-length-write-16 erase \ 16 bytes CDB
584
scsi-cmd-write-16 r@ write-16>operation-code c! ( block# #blocks )
585
r@ write-16>length l! ( block# )
586
r@ write-16>block-address x! ( )
587
scsi-param-control r> write-16>control c! ( R: cdb -- )
588
scsi-length-write-16 to scsi-param-size \ update CDB length
591
\ ***************************************************************************
592
\ SCSI-Command: START STOP UNIT
593
\ Type: Block Command (SBC-3 clause 5.19)
594
\ ***************************************************************************
595
\ Forth Word: scsi-build-start-stop-unit ( state# cdb -- )
596
\ ***************************************************************************
598
1b CONSTANT scsi-cmd-start-stop-unit
602
/c FIELD start-stop-unit>operation-code
603
/c FIELD start-stop-unit>immed
604
/w FIELD start-stop-unit>reserved
605
/c FIELD start-stop-unit>pow-condition
606
/c FIELD start-stop-unit>control
607
CONSTANT scsi-length-start-stop-unit
609
\ START/STOP constants
610
\ (see spec: SBC-3 clause 5.19)
611
f1 CONSTANT scsi-const-active-power \ param used for start-stop-unit
612
f2 CONSTANT scsi-const-idle-power \ param used for start-stop-unit
613
f3 CONSTANT scsi-const-standby-power \ param used for start-stop-unit
614
3 CONSTANT scsi-const-load \ param used for start-stop-unit
615
2 CONSTANT scsi-const-eject \ param used for start-stop-unit
616
1 CONSTANT scsi-const-start
617
0 CONSTANT scsi-const-stop
619
: scsi-build-start-stop-unit ( state# cdb -- )
620
>r ( state# ) ( R: -- cdb )
621
r@ scsi-length-start-stop-unit erase \ 6 bytes CDB
622
scsi-cmd-start-stop-unit r@ start-stop-unit>operation-code c!
625
4 lshift \ shift to upper nibble
627
r@ start-stop-unit>pow-condition c! ( )
628
scsi-param-control r> start-stop-unit>control c! ( R: cdb -- )
629
scsi-length-start-stop-unit to scsi-param-size \ update CDB length
632
\ ***************************************************************************
633
\ SCSI-Command: SEEK(10)
634
\ Type: Block Command (obsolete)
635
\ ***************************************************************************
636
\ Forth Word: scsi-build-seek ( state# cdb -- )
637
\ Obsolete function (last listed in spec SBC / Nov. 1997)
638
\ implemented only for the sake of completeness
639
\ ***************************************************************************
641
2b CONSTANT scsi-cmd-seek
645
/c FIELD seek>operation-code
646
/c FIELD seek>reserved1
648
3 FIELD seek>reserved2
649
/c FIELD seek>control
650
CONSTANT scsi-length-seek
652
: scsi-build-seek ( lba cdb -- )
653
>r ( lba ) ( R: -- cdb )
654
r@ scsi-length-seek erase \ 10 bytes CDB
655
scsi-cmd-seek r@ seek>operation-code c!
656
r> seek>lba l! ( ) ( R: cdb -- )
657
scsi-length-seek to scsi-param-size \ update CDB length
660
\ ****************************************************************************
661
\ CDROM media event stuff
662
\ ****************************************************************************
665
/w FIELD media-event-data-len
666
/c FIELD media-event-nea-class
667
/c FIELD media-event-supp-class
668
/l FIELD media-event-data
669
CONSTANT scsi-length-media-event
671
: scsi-build-get-media-event ( cdb -- )
682
\ ***************************************************************************
683
\ SCSI-Utility: .sense-code
684
\ ***************************************************************************
685
\ this utility prints a string associated to the sense code
686
\ see specs: SPC-3/r23 clause 4.5.6
687
\ ***************************************************************************
688
: .sense-text ( scode -- )
691
1 OF s" RECOVERED ERR" ENDOF
692
2 OF s" NOT READY" ENDOF
693
3 OF s" MEDIUM ERROR" ENDOF
694
4 OF s" HARDWARE ERR" ENDOF
695
5 OF s" ILLEGAL REQUEST" ENDOF
696
6 OF s" UNIT ATTENTION" ENDOF
697
7 OF s" DATA PROTECT" ENDOF
698
8 OF s" BLANK CHECK" ENDOF
699
9 OF s" VENDOR SPECIFIC" ENDOF
700
a OF s" COPY ABORTED" ENDOF
701
b OF s" ABORTED COMMAND" ENDOF
702
d OF s" VOLUME OVERFLOW" ENDOF
703
e OF s" MISCOMPARE" ENDOF
704
dup OF s" UNKNOWN" ENDOF
709
\ ***************************************************************************
710
\ SCSI-Utility: .status-code
711
\ ***************************************************************************
712
\ this utility prints a string associated to the status code
713
\ see specs: SAM-3/r14 clause 5.3
714
\ ***************************************************************************
715
: .status-text ( stat -- )
718
02 OF s" CHECK CONDITION" ENDOF
719
04 OF s" CONDITION MET" ENDOF
721
18 OF s" RESERVATION CONFLICT" ENDOF
722
28 OF s" TASK SET FULL" ENDOF
723
30 OF s" ACA ACTIVE" ENDOF
724
40 OF s" TASK ABORTED" ENDOF
725
dup OF s" UNKNOWN" ENDOF
730
\ ***************************************************************************
731
\ SCSI-Utility: .capacity-text
732
\ ***************************************************************************
733
\ utility that shows total capacity on screen by use of the return data
734
\ from read-capacity calculation is SI conform (base 10)
735
\ ***************************************************************************
736
\ sub function to print a 3 digit decimal
737
\ number with 2 post decimal positions xxx.yy
738
: .dec3-2 ( prenum postnum -- )
740
base @ >r \ save actual base setting
741
decimal \ show decimal values
743
dup 9 <= IF 30 emit THEN .d \ 3 pre-decimal, right aligned
744
r> base ! \ restore base
747
: .capacity-text ( block-size #blocks -- )
748
scsi-param-debug \ debugging flag set ?
749
IF \ show additional info
752
." LBAs: " .d \ highest logical block number
753
." / Block-Size: " .d
754
." / Total Capacity: "
756
* \ calculate total capacity
757
dup d# 1000000000000 >= \ check terabyte limit
759
d# 1000000000000 /mod
761
d# 10000000000 / \ limit remainder to two digits
762
.dec3-2 ." TB" \ show terabytes as xxx.yy
764
dup d# 1000000000 >= \ check gigabyte limit
769
.dec3-2 ." GB" \ show gigabytes as xxx.yy
773
d# 1000000 /mod \ check mega byte limit
776
.dec3-2 ." MB" \ show megabytes as xxx.yy
778
dup d# 1000 >= \ check kilo byte limit
792
\ ***************************************************************************
793
\ SCSI-Utility: .inquiry-text ( addr -- )
794
\ ***************************************************************************
795
\ utility that shows:
796
\ vendor-ident product-ident and revision
797
\ from an inquiry return data block (addr)
798
\ ***************************************************************************
799
: .inquiry-text ( addr -- )
800
22 emit \ enclose text with "
801
dup inquiry-data>vendor-ident 8 type space
802
dup inquiry-data>product-ident 10 type space
803
inquiry-data>product-revision 4 type
807
\ ***************************************************************************
808
\ SCSI-Utility: scsi-supp-init ( -- )
809
\ ***************************************************************************
810
\ utility that helps to ensure that parameters are set to valid values
811
: scsi-supp-init ( -- )
812
false to scsi-param-debug \ no debug strings
813
h# 0 to scsi-param-size
814
h# 0 to scsi-param-control \ common CDB control byte
815
d# 0 to scsi-param-errors \ local errors (param limits)
818
\ ***************************************************************************
819
\ Constants used by SCSI controller's execute-scsi-command
820
\ ***************************************************************************
821
true CONSTANT scsi-dir-read
822
false CONSTANT scsi-dir-write
825
\ ***************************************************************************
827
\ ***************************************************************************
828
0 VALUE scsi-context \ addr of word list on top
831
\ ****************************************************************************
832
\ open scsi-support by adding a new word list on top of search path
833
\ precondition: scsi-support.fs must have been included
834
\ ****************************************************************************
836
also scsi-words \ append scsi word-list
837
context to scsi-context \ save for close process
838
scsi-supp-init \ preset all scsi-param-xxx values
841
space ." SCSI-SUPPORT OPENED" cr
846
\ ****************************************************************************
847
\ close scsi-session and remove scsi word list (if exists)
848
\ ****************************************************************************
849
\ if 'previous' is used without a preceding 'also' all forth words are lost !
850
\ ****************************************************************************
852
\ FIXME This only works if scsi-words is the last vocabulary on the stack
853
\ Instead we could use get-order to find us on the "wordlist stack",
854
\ remove us and write the wordlist stack back with set-order.
855
\ BUT: Is this worth the effort?
859
space ." Closing SCSI-SUPPORT .. " cr
861
context scsi-context = \ scsi word list still active ?
863
scsi-param-errors 0<> \ any errors occurred ?
865
cr ." ** WARNING: " scsi-param-errors .d
866
." SCSI Errors occurred ** " cr
868
previous \ remove scsi word list on top
869
0 to scsi-context \ prevent from being misinterpreted
871
cr ." ** WARNING: Trying to close non-open SCSI-SUPPORT (1) ** " cr
880
s" scsi-init" $find drop \ return execution pointer, when included
882
previous \ remove scsi word list from search path
883
definitions \ place next definitions into previous list