Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / scsi / adapters / hacom.fth
CommitLineData
920dae64
AT
1\ ========== Copyright Header Begin ==========================================
2\
3\ Hypervisor Software File: hacom.fth
4\
5\ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6\
7\ - Do no alter or remove copyright notices
8\
9\ - Redistribution and use of this software in source and binary forms, with
10\ or without modification, are permitted provided that the following
11\ conditions are met:
12\
13\ - Redistribution of source code must retain the above copyright notice,
14\ this list of conditions and the following disclaimer.
15\
16\ - Redistribution in binary form must reproduce the above copyright notice,
17\ this list of conditions and the following disclaimer in the
18\ documentation and/or other materials provided with the distribution.
19\
20\ Neither the name of Sun Microsystems, Inc. or the names of contributors
21\ may be used to endorse or promote products derived from this software
22\ without specific prior written permission.
23\
24\ This software is provided "AS IS," without a warranty of any kind.
25\ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
26\ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
27\ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
28\ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
29\ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
30\ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
31\ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
32\ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
33\ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
34\ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
35\ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
36\
37\ You acknowledge that this software is not designed, licensed or
38\ intended for use in the design, construction, operation or maintenance of
39\ any nuclear facility.
40\
41\ ========== Copyright Header End ============================================
42id: @(#)hacom.fth 1.12 04/03/18
43purpose:
44copyright: Copyright 1995-2004 Sun Microsystems, Inc. All rights reserved
45copyright: Use is subject to license terms.
46
47\ Common code for SCSI host adapter drivers.
48
49\ The following code is intended to be independent of the details of the
50\ SCSI hardware implementation. It is loaded after the hardware-dependent
51\ file that defines execute-command, set-address, open-hardware, etc.
52
53headers
54
55-1 instance value inq-buf \ Address of inquiry data buffer
56-1 instance value sense-buf \ holds extended error information
57-1 instance value luns-buf \ Address of report luns data buffer
58
59
600 value #retries ( -- n ) \ number of times to retry SCSI transaction
61
62h# 1.0000 constant debug-sense-codes
63
64: .buf ( strt-adr cnt -- )
65 base @ >r hex
66 bounds do i c@ 3 u.r loop
67 r> base !
68;
69
70\ Classifies the sense condition as either okay (0), retryable (1),
71\ or non-retryable (-1)
72: classify-sense ( -- 0 | 1 | -1 )
73 debug? debug-sense-codes and if
74 ." Sense: " sense-buf 11 .buf ." ..." cr
75 then
76 sense-buf
77
78 \ Make sure we understand the error class code
79 dup c@ h# 7f and h# 70 <> if drop -1 exit then
80
81 \ Check for filemark, end-of-media, or illegal block length
82 dup 2+ c@ h# e0 and if drop -1 exit then
83
84 2 + c@ h# f and ( sense-key )
85
86 \ no_sense(0) and recoverable(1) are okay
87 dup 1 <= if drop 0 exit then ( sense-key )
88
89 \ not-ready(2) may be retryable
90 dup 2 = if
91 \ check (tapes, especially) for MEDIA NOT PRESENT: if the
92 \ media's not there the command is not retryable
93 drop sense-buf h# c + c@ h# 3a = sense-buf h# d + c@ 0=
94 and if -1 else 1 then
95 exit
96 then
97
98 \ media-error(3), attention(6), and target aborted (b) are retryable
99 \ media error really should not be retryable, but Toshiba 3601 CDROMs
100 \ sometimes return "media error" during the spin-up process.
101 dup 3 = over 6 = or swap 0b = or if 1 else -1 then
102;
103
104external
105
106\ The SCSI device node defines an address space for its children. That
107\ address space is of the form "target#,unit#". target# and unit# are
108\ both integers. parse-2int converts a text string (e.g. "3,4") into
109\ a pair of binary integers.
110
111: open ( -- flag )
112 open-count if
113 reopen-hardware dup if open-count 1+ to open-count then
114 exit
115 else
116 open-hardware dup if
117 1 to open-count
118 h# 100 dma-alloc to sense-buf
119 h# 100 dma-alloc to inq-buf
120 h# 2000 dma-alloc to luns-buf
121 then
122 then
123;
124: close ( -- )
125 open-count 1- to open-count
126 open-count if
127 reclose-hardware
128 else
129 close-hardware
130 luns-buf h# 2000 dma-free
131 inq-buf h# 100 dma-free
132 sense-buf h# 100 dma-free
133 then
134;
135
136
137headers
138
139\ REQUEST-SENSE is HA specific, here is typical implementation
140\
141\ create sense-cmd 3 c, 0 c, 0 c, 0 c, ff c, 0 c,
142\ : request-sense ( buf,len -- hwresult | statbyte 0 )
143\ true sense-cmd 6 execute-command
144\ ;
145
146\ Issue REQUEST SENSE, which is not supposed to fail
147: get-sense ( -- )
148 sense-buf ff request-sense 0= if drop then
149;
150
151\ Give the device a little time to recover before retrying the command.
152: delay-retry ( -- ) d# 100 ms ;
153
1540 instance value statbyte \ Local variable used by retry?
155
156\ RETRY? is used by RETRY-COMMAND to determine whether or not to retry the
157\ command, considering the following factors:
158\ - Success or failure of the command at the hardware level (failure at
159\ this level is usually fatal, except in the case of an incoming bus reset)
160\ - The value of the status byte returned by the command
161\ - The condition indicated by the sense bytes
162\ - The number of previous retries
163\
164\ The input arguments are as returned by "scsi-exec"
165\ On output, the top of the stack is true if the command is to be retried,
166\ otherwise the top of the stack is false and the results that should be
167\ returned by retry-command are underneath it; those results indicate the type
168\ of error that occurred.
169
170: retry? ( hw-result | statbyte 0 -- true | [[sensebuf] f-hw] error? false )
171 case
172 0 of to statbyte endof \ No hardware error; continue checking
173 bus-reset of true exit endof \ Retry after incoming bus reset
174 ( hw-result ) true false exit \ Other hardware errors are fatal
175 endcase
176
177 statbyte 0= if false false exit then \ If successful, return "no-error"
178
179 statbyte 2 and if \ "Check Condition", so get extended status
180 get-sense classify-sense case ( -1|0|1 )
181 \ If the sense information says "no sense", return "no-error"
182 0 of false false exit endof
183
184 \ If the error is fatal, return "sense-buf,valid,statbyte"
185 -1 of sense-buf false statbyte false exit endof
186 endcase
187
188 \ Otherwise, the error was retryable. However, if we have
189 \ have already retried the specified number of times, don't
190 \ retry again; instead return sense buffer and status.
191 #retries 0= if sense-buf false statbyte false exit then
192 then
193
194 \ Don't retry if vendor-unique, reserved, intermediate, or
195 \ "condition met/good" bits are set. Return "no-sense,status"
196 statbyte h# f5 and if true statbyte false exit then
197
198 \ Don't retry if we have already retried the specified number
199 \ of times. Return "no-sense,status"
200 #retries 0= if true statbyte false exit then
201
202 \ Otherwise, it was either a busy or a retryable check condition,
203 \ so we retry.
204
205 true
206;
207
208\ RETRY-COMMAND executes a SCSI command. If a check condition is indicated,
209\ performs a "get-sense" command. If the sense bytes indicate a non-fatal
210\ condition (e.g. power-on reset occurred, not ready yet, or recoverable
211\ error), the command is retried until the condition either goes away or
212\ changes to a fatal error.
213\
214\ The command is retried until:
215\ a) The command succeeds, or
216\ b) The select fails, or dma fails, or
217\ c) The sense bytes indicate an error that we can't retry at this level
218\ d) The number of retries is exceeded.
219
220\ #retries is number of times to retry (0: don't retry, -1: retry forever)
221\
222\ sensebuf is the address of the sense buffer; it is present only
223\ if f-hw is 0 and error? is non-zero. The length of the sense buffer
224\ is 8 bytes plus the value in byte 7 of the sense buffer.
225\
226\ f-hw is non-zero if there is a hardware error -- dma fails, select fails,
227\ etc -- or if the status byte was neither 0 (okay) nor 2 (check condition)
228\
229\ error? is non-zero if there is a transaction error. If error? is 0,
230\ f-hw and sensebuf are not returned.
231\
232\ If sensebuf is returned, the contents are valid until the next call to
233\ retry-command. sensebuf becomes inaccessable when this package is closed.
234\
235\ dma-dir is necessary because it is not always possible to infer the DMA
236\ direction from the command.
237
238\ Local variables used by retry-command?
239
2400 instance value dbuf \ Data transfer buffer
2410 instance value dlen \ Expected length of data transfer
2420 instance value direction-in \ Direction for data transfer
243
244-1 instance value cbuf \ Command base address
245 0 instance value clen \ Actual length of this command
246
247external
248
249: retry-command ( dma-buf dma-len dma-dir cmdbuf cmdlen #retries -- ... )
250 ( ... -- [[sensebuf] f-hw] error? )
251 to #retries to clen to cbuf to direction-in to dlen to dbuf
252
253 begin
254 dbuf dlen direction-in cbuf clen execute-command ( hwerr | stat 0 )
255 retry?
256 while
257 #retries 1- to #retries
258 delay-retry
259 repeat
260;
261
262headers
263
264\ Collapses the complete error information returned by retry-command into
265\ a single error/no-error flag.
266
267: error? ( false | true true | sensebuf false true -- error? )
268 dup if swap 0= if nip then then
269;
270
271external
272
273\ Simplified "retry-command" routine for commands with no data transfer phase
274\ and simple error checking requirements.
275
276: no-data-command ( cmdbuf -- error? )
277 >r 0 0 true r> 6 -1 retry-command error?
278;
279
280\ short-data-command executes a command with the following characteristics:
281\ a) The data direction is incoming
282\ b) The data length is less than 256 bytes
283
284\ The host adapter driver is responsible for supplying the DMA data
285\ buffer; if the command succeeds, the buffer address is returned.
286\ The buffer contents become invalid when another SCSI command is
287\ executed, or when the driver is closed.
288
289: short-data-command ( data-len cmdbuf cmdlen -- true | buffer false )
290 >r >r inq-buf swap true r> r> -1 retry-command ( retry-cmd-results )
291 error? dup 0= if inq-buf swap then
292;
293
294headers
295
296\ Here begins the implementation of "show-children", a word that
297\ is intended to be executed interactively, showing the user the
298\ devices that are attached to the SCSI bus.
299
300\ Tool for storing a big-endian 24-bit number at an unaligned address
301
302: 3c! ( n addr -- ) >r lbsplit drop r@ c! r@ 1+ c! r> 2+ c! ;
303
304
305\ Command block template for Inquiry command
306
307create inquiry-cmd h# 12 c, 0 c, 0 c, 0 c, ff c, 0 c,
308
309: inquiry ( -- error? )
310 \ 8 retries should be more than enough; inquiry commands aren't
311 \ supposed to respond with "check condition".
312
313 inq-buf ff true inquiry-cmd 6 8 retry-command error?
314;
315
316: ??line ( lmargin char threshold -- )
317 #out @ <= if cr 2dup bl = if 1- then spaces then
318;
319: formatted-type ( adr len -- )
320 #out @ -rot
321 bounds ?do
322 i c@ dup bl = if d# 70 ??line then
323 d# 78 ??line
324 emit
325 loop
326 drop
327;
328
329\ Reads the indicated byte from the Inquiry data buffer
330
331: inq@ ( offset -- value ) inq-buf + c@ ;
332
333: .scsi1-inquiry ( -- ) inq-buf 5 ca+ 4 inq@ h# fa min formatted-type ;
334: .scsi2-inquiry ( -- ) inq-buf 8 ca+ d# 28 formatted-type ;
335
336headerless
337
338create report-luns-cmd
339 h# 0c c,
340 h# a0 c, 00 c, 00 c, 00 c, 00 c, 00 c,
341 h# 00 c, 00 c, 20 c, 00 c, 00 c, 00 c,
342
343: report-luns ( -- error? )
344 luns-buf h# 2000 -1 report-luns-cmd count 8 retry-command error?
345;
346
347headers
348
349\ The diagnose command is useful for generic SCSI devices.
350\ It executes bothe "test-unit-ready" and "send-diagnostic"
351\ commands, decoding the error status information they return.
352
353create test-unit-rdy-cmd 0 c, 0 c, 0 c, 0 c, 0 c, 0 c,
354create send-diagnostic-cmd h# 1d c, 4 c, 0 c, 0 c, 0 c, 0 c,
355
356: send-diagnostic ( -- error? ) send-diagnostic-cmd no-data-command ;
357
358
359external
360
361: diagnose ( -- flag )
362 0 0 true test-unit-rdy-cmd 6 -1 ( dma$ dir cmd$ #retries )
363 retry-command if ( [ sensebuf ] hardware-error? )
364 ." Test unit ready failed - " ( [ sensebuf ] hardware-error? )
365 if ( )
366 ." hardware error (no such device?)" cr ( )
367 else ( sensebuf )
368 ." extended status = " cr ( sensebuf )
369 8 .buf cr
370 then
371 true
372 else
373 send-diagnostic ( fail? )
374 then
375;
376
377headers