1 /* $OpenBSD: ncr53c9xvar.h,v 1.24 2020/07/22 13:16:04 krw Exp $ */
2 /* $NetBSD: ncr53c9xvar.h,v 1.13 1998/05/26 23:17:34 thorpej Exp $ */
3
4 /*-
5 * Copyright (c) 1997 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10 * NASA Ames Research Center.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /*
35 * Copyright (c) 1994 Peter Galbavy. All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
47 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
49 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
50 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
52 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
53 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
54 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
55 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 */
57
58 #include <sys/timeout.h>
59
60 /* Set this to 1 for normal debug, or 2 for per-target tracing. */
61 #if !defined(SMALL_KERNEL)
62 #define NCR53C9X_DEBUG 1
63 #endif
64
65 /* Wide or differential can have 16 targets */
66 #define NCR_NTARG 16
67 #define NCR_NLUN 8
68
69 #define NCR_ABORT_TIMEOUT 2000 /* time to wait for abort */
70 #define NCR_SENSE_TIMEOUT 1000 /* time to wait for sense */
71
72 #define FREQTOCCF(freq) (((freq + 4) / 5))
73
74 /*
75 * NCR 53c9x variants. Note, these values are used as indexes into
76 * a table; don't modify them unless you know what you're doing.
77 */
78 #define NCR_VARIANT_ESP100 0
79 #define NCR_VARIANT_ESP100A 1
80 #define NCR_VARIANT_ESP200 2
81 #define NCR_VARIANT_NCR53C94 3
82 #define NCR_VARIANT_NCR53C96 4
83 #define NCR_VARIANT_ESP406 5
84 #define NCR_VARIANT_FAS408 6
85 #define NCR_VARIANT_FAS216 7
86 #define NCR_VARIANT_AM53C974 8
87 #define NCR_VARIANT_FAS366 9
88 #define NCR_VARIANT_MAX 10
89
90 /*
91 * ECB. Holds additional information for each SCSI command Comments: We
92 * need a separate scsi command block because we may need to overwrite it
93 * with a request sense command. Basicly, we refrain from fiddling with
94 * the scsi_xfer struct (except do the expected updating of return values).
95 * We'll generally update: xs->{flags,resid,error,sense,status} and
96 * occasionally xs->retries.
97 */
98 struct ncr53c9x_ecb {
99 TAILQ_ENTRY(ncr53c9x_ecb) chain;
100 struct scsi_xfer *xs; /* SCSI xfer ctrl block from above */
101 int flags;
102 #define ECB_ALLOC 0x01
103 #define ECB_READY 0x02
104 #define ECB_SENSE 0x04
105 #define ECB_ABORT 0x40
106 #define ECB_RESET 0x80
107 #define ECB_TENTATIVE_DONE 0x100
108 int timeout;
109 struct timeout to;
110
111 struct {
112 u_char msg[3]; /* Selection Id msg */
113 struct scsi_generic cmd; /* SCSI command block */
114 } cmd;
115 char *daddr; /* Saved data pointer */
116 int clen; /* Size of command in cmd.cmd */
117 int dleft; /* Residue */
118 u_char stat; /* SCSI status byte */
119 u_char tag[2]; /* TAG bytes */
120 u_char pad[1];
121
122 #if NCR53C9X_DEBUG > 1
123 char trace[1000];
124 #endif
125 };
126 #if NCR53C9X_DEBUG > 1
127 #define ECB_TRACE(ecb, msg, a, b) do { \
128 const char *f = "[" msg "]"; \
129 int n = strlen((ecb)->trace); \
130 if (n < (sizeof((ecb)->trace)-100)) \
131 snprintf((ecb)->trace + n, sizeof((ecb)->trace) - n, f, a, b); \
132 } while(0)
133 #else
134 #define ECB_TRACE(ecb, msg, a, b)
135 #endif
136
137 /*
138 * Some info about ech (possible) target and LUN on the SCSI bus.
139 *
140 * SCSI I and II devices can have up to 8 LUNs, each with up to 256
141 * outstanding tags. SCSI III devices have 64-bit LUN identifiers
142 * that can be sparsely allocated.
143 *
144 * Since SCSI II devices can have up to 8 LUNs, we use an array
145 * of 8 pointers to ncr53c9x_linfo structures for fast lookup.
146 * Longer LUNs need to traverse the linked list.
147 */
148
149 struct ncr53c9x_linfo {
150 int64_t lun;
151 LIST_ENTRY(ncr53c9x_linfo) link;
152 time_t last_used;
153 unsigned char used; /* # slots in use */
154 unsigned char avail; /* where to start scanning */
155 unsigned char busy;
156 struct ncr53c9x_ecb *untagged;
157 struct ncr53c9x_ecb *queued[256];
158 };
159
160 struct ncr53c9x_tinfo {
161 int cmds; /* # of commands processed */
162 int dconns; /* # of disconnects */
163 int touts; /* # of timeouts */
164 int perrs; /* # of parity errors */
165 int senses; /* # of request sense commands sent */
166 u_char flags;
167 #define T_NEED_TO_RESET 0x01 /* Should send a BUS_DEV_RESET */
168 #define T_NEGOTIATE 0x02 /* (Re)Negotiate synchronous options */
169 #define T_BUSY 0x04 /* Target is busy, i.e. cmd in progress */
170 #define T_SYNCMODE 0x08 /* sync mode has been negotiated */
171 #define T_SYNCHOFF 0x10 /* .. */
172 #define T_RSELECTOFF 0x20 /* .. */
173 #define T_TAG 0x40 /* TAG QUEUEs are on */
174 #define T_WIDE 0x80 /* Negotiate wide options */
175 u_char period; /* Period suggestion */
176 u_char offset; /* Offset suggestion */
177 u_char cfg3; /* per target config 3 */
178 u_char nextag; /* Next available tag */
179 u_char width; /* width suggestion */
180 LIST_HEAD(lun_list, ncr53c9x_linfo) luns;
181 struct ncr53c9x_linfo *lun[NCR_NLUN]; /* For speedy lookups */
182 };
183
184 /* Look up a lun in a tinfo */
185 #define TINFO_LUN(t, l) ((((l) < NCR_NLUN) && (((t)->lun[(l)]) != NULL)) ? \
186 ((t)->lun[(l)]) : ncr53c9x_lunsearch((t), (int64_t)(l)))
187
188 /* Register a linenumber (for debugging) */
189 #define LOGLINE(p)
190
191 #define NCR_SHOWECBS 0x01
192 #define NCR_SHOWINTS 0x02
193 #define NCR_SHOWCMDS 0x04
194 #define NCR_SHOWMISC 0x08
195 #define NCR_SHOWTRAC 0x10
196 #define NCR_SHOWSTART 0x20
197 #define NCR_SHOWPHASE 0x40
198 #define NCR_SHOWDMA 0x80
199 #define NCR_SHOWCCMDS 0x100
200 #define NCR_SHOWMSGS 0x200
201
202 #ifdef NCR53C9X_DEBUG
203 extern int ncr53c9x_debug;
204 #define NCR_ECBS(str) \
205 do {if (ncr53c9x_debug & NCR_SHOWECBS) printf str;} while (0)
206 #define NCR_MISC(str) \
207 do {if (ncr53c9x_debug & NCR_SHOWMISC) printf str;} while (0)
208 #define NCR_INTS(str) \
209 do {if (ncr53c9x_debug & NCR_SHOWINTS) printf str;} while (0)
210 #define NCR_TRACE(str) \
211 do {if (ncr53c9x_debug & NCR_SHOWTRAC) printf str;} while (0)
212 #define NCR_CMDS(str) \
213 do {if (ncr53c9x_debug & NCR_SHOWCMDS) printf str;} while (0)
214 #define NCR_START(str) \
215 do {if (ncr53c9x_debug & NCR_SHOWSTART) printf str;}while (0)
216 #define NCR_PHASE(str) \
217 do {if (ncr53c9x_debug & NCR_SHOWPHASE) printf str;}while (0)
218 #define NCR_DMA(str) \
219 do {if (ncr53c9x_debug & NCR_SHOWDMA) printf str;}while (0)
220 #define NCR_MSGS(str) \
221 do {if (ncr53c9x_debug & NCR_SHOWMSGS) printf str;}while (0)
222 #else
223 #define NCR_ECBS(str)
224 #define NCR_MISC(str)
225 #define NCR_INTS(str)
226 #define NCR_TRACE(str)
227 #define NCR_CMDS(str)
228 #define NCR_START(str)
229 #define NCR_PHASE(str)
230 #define NCR_DMA(str)
231 #define NCR_MSGS(str)
232 #endif
233
234 #define NCR_MAX_MSG_LEN 8
235
236 struct ncr53c9x_softc;
237
238 /*
239 * Function switch used as glue to MD code.
240 */
241 struct ncr53c9x_glue {
242 /* Mandatory entry points. */
243 u_char (*gl_read_reg)(struct ncr53c9x_softc *, int);
244 void (*gl_write_reg)(struct ncr53c9x_softc *, int, u_char);
245 int (*gl_dma_isintr)(struct ncr53c9x_softc *);
246 void (*gl_dma_reset)(struct ncr53c9x_softc *);
247 int (*gl_dma_intr)(struct ncr53c9x_softc *);
248 int (*gl_dma_setup)(struct ncr53c9x_softc *,
249 caddr_t *, size_t *, int, size_t *);
250 void (*gl_dma_go)(struct ncr53c9x_softc *);
251 void (*gl_dma_stop)(struct ncr53c9x_softc *);
252 int (*gl_dma_isactive)(struct ncr53c9x_softc *);
253
254 /* Optional entry points. */
255 void (*gl_clear_latched_intr)(struct ncr53c9x_softc *);
256 };
257
258 struct ncr53c9x_softc {
259 struct device sc_dev; /* us as a device */
260
261 struct ncr53c9x_glue *sc_glue; /* glue to MD code */
262
263 int sc_ntarg; /* number of targets */
264 int sc_cfflags; /* Copy of config flags */
265
266 /* register defaults */
267 u_char sc_cfg1; /* Config 1 */
268 u_char sc_cfg2; /* Config 2, not ESP100 */
269 u_char sc_cfg3; /* Config 3, only ESP200 */
270 u_char sc_cfg3_fscsi; /* Chip specific FSCSI bit */
271 u_char sc_cfg4; /* Config 4 */
272 u_char sc_cfg5; /* Config 5 */
273 u_char sc_ccf; /* Clock Conversion */
274 u_char sc_timeout;
275
276 /* register copies, see espreadregs() */
277 u_char sc_espintr;
278 u_char sc_espstat;
279 u_char sc_espstep;
280 u_char sc_espstat2;
281 u_char sc_espfflags;
282
283 /* Lists of command blocks */
284 TAILQ_HEAD(ecb_list, ncr53c9x_ecb) ready_list;
285
286 struct ncr53c9x_ecb *sc_nexus; /* Current command */
287 struct ncr53c9x_tinfo sc_tinfo[NCR_NTARG];
288
289 /* Data about the current nexus (updated for every cmd switch) */
290 caddr_t sc_dp; /* Current data pointer */
291 ssize_t sc_dleft; /* Data left to transfer */
292
293 /* Adapter state */
294 int sc_phase; /* Copy of what bus phase we are in */
295 int sc_prevphase; /* Copy of what bus phase we were in */
296 u_char sc_state; /* State applicable to the adapter */
297 u_char sc_flags; /* See below */
298 u_char sc_selid;
299 u_char sc_lastcmd;
300
301 /* Message stuff */
302 u_short sc_msgify; /* IDENTIFY message associated with this nexus */
303 u_short sc_msgout; /* What message is on its way out? */
304 u_short sc_msgpriq; /* One or more messages to send (encoded) */
305 u_short sc_msgoutq; /* What messages have been sent so far? */
306
307 u_char *sc_omess; /* MSGOUT buffer */
308 caddr_t sc_omp; /* Message pointer (for multibyte messages) */
309 size_t sc_omlen;
310 u_char *sc_imess; /* MSGIN buffer */
311 caddr_t sc_imp; /* Message pointer (for multibyte messages) */
312 size_t sc_imlen;
313
314 caddr_t sc_cmdp; /* Command pointer (for DMAed commands) */
315 size_t sc_cmdlen; /* Size of command in transit */
316
317 /* Hardware attributes */
318 int sc_freq; /* SCSI bus frequency in MHz */
319 int sc_id; /* Our SCSI id */
320 int sc_rev; /* Chip revision */
321 int sc_features; /* Chip features */
322 int sc_minsync; /* Minimum sync period / 4 */
323 int sc_maxxfer; /* Maximum transfer size */
324 };
325
326 /* values for sc_state */
327 #define NCR_IDLE 1 /* waiting for something to do */
328 #define NCR_SELECTING 2 /* SCSI command is arbiting */
329 #define NCR_RESELECTED 3 /* Has been reselected */
330 #define NCR_IDENTIFIED 4 /* Has gotten IFY but not TAG */
331 #define NCR_CONNECTED 5 /* Actively using the SCSI bus */
332 #define NCR_DISCONNECT 6 /* MSG_DISCONNECT received */
333 #define NCR_CMDCOMPLETE 7 /* MSG_CMDCOMPLETE received */
334 #define NCR_CLEANING 8
335 #define NCR_SBR 9 /* Expect a SCSI RST because we commanded it */
336
337 /* values for sc_flags */
338 #define NCR_DROP_MSGI 0x01 /* Discard all msgs (parity err detected) */
339 #define NCR_ABORTING 0x02 /* Bailing out */
340 #define NCR_DOINGDMA 0x04 /* The FIFO data path is active! */
341 #define NCR_SYNCHNEGO 0x08 /* Synch negotiation in progress. */
342 #define NCR_ICCS 0x10 /* Expect status phase results */
343 #define NCR_WAITI 0x20 /* Waiting for non-DMA data to arrive */
344 #define NCR_ATN 0x40 /* ATN asserted */
345 #define NCR_EXPECT_ILLCMD 0x80 /* Expect Illegal Command Interrupt */
346
347 /* values for sc_features */
348 #define NCR_F_HASCFG3 0x01 /* chip has CFG3 register */
349 #define NCR_F_FASTSCSI 0x02 /* chip supports Fast mode */
350 #define NCR_F_DMASELECT 0x04 /* can do dma select */
351 #define NCR_F_SELATN3 0x08 /* can do selatn3 */
352
353 /* values for sc_msgout */
354 #define SEND_DEV_RESET 0x0001
355 #define SEND_PARITY_ERROR 0x0002
356 #define SEND_INIT_DET_ERR 0x0004
357 #define SEND_REJECT 0x0008
358 #define SEND_IDENTIFY 0x0010
359 #define SEND_ABORT 0x0020
360 #define SEND_WDTR 0x0040
361 #define SEND_SDTR 0x0080
362 #define SEND_TAG 0x0100
363
364 /* SCSI Status codes */
365 #define ST_MASK 0x3e /* bit 0,6,7 is reserved */
366
367 /* phase bits */
368 #define IOI 0x01
369 #define CDI 0x02
370 #define MSGI 0x04
371
372 /* Information transfer phases */
373 #define DATA_OUT_PHASE (0)
374 #define DATA_IN_PHASE (IOI)
375 #define COMMAND_PHASE (CDI)
376 #define STATUS_PHASE (CDI|IOI)
377 #define MESSAGE_OUT_PHASE (MSGI|CDI)
378 #define MESSAGE_IN_PHASE (MSGI|CDI|IOI)
379
380 #define PHASE_MASK (MSGI|CDI|IOI)
381
382 /* Some pseudo phases for getphase()*/
383 #define BUSFREE_PHASE 0x100 /* Re/Selection no longer valid */
384 #define INVALID_PHASE 0x101 /* Re/Selection valid, but no REQ yet */
385 #define PSEUDO_PHASE 0x100 /* "pseudo" bit */
386
387 /*
388 * Macros to read and write the chip's registers.
389 */
390 #define NCR_READ_REG(sc, reg) \
391 (*(sc)->sc_glue->gl_read_reg)((sc), (reg))
392 #define NCR_WRITE_REG(sc, reg, val) \
393 (*(sc)->sc_glue->gl_write_reg)((sc), (reg), (val))
394
395 #ifdef NCR53C9X_DEBUG
396 #define NCRCMD(sc, cmd) do { \
397 if (ncr53c9x_debug & NCR_SHOWCCMDS) \
398 printf("<cmd:0x%x %d>", (unsigned)cmd, __LINE__); \
399 sc->sc_lastcmd = cmd; \
400 NCR_WRITE_REG(sc, NCR_CMD, cmd); \
401 } while (0)
402 #else
403 #define NCRCMD(sc, cmd) NCR_WRITE_REG(sc, NCR_CMD, cmd)
404 #endif
405
406 /*
407 * DMA macros for NCR53c9x
408 */
409 #define NCRDMA_ISINTR(sc) (*(sc)->sc_glue->gl_dma_isintr)((sc))
410 #define NCRDMA_RESET(sc) (*(sc)->sc_glue->gl_dma_reset)((sc))
411 #define NCRDMA_INTR(sc) (*(sc)->sc_glue->gl_dma_intr)((sc))
412 #define NCRDMA_SETUP(sc, addr, len, datain, dmasize) \
413 (*(sc)->sc_glue->gl_dma_setup)((sc), (addr), (len), (datain), (dmasize))
414 #define NCRDMA_GO(sc) (*(sc)->sc_glue->gl_dma_go)((sc))
415 #define NCRDMA_ISACTIVE(sc) (*(sc)->sc_glue->gl_dma_isactive)((sc))
416
417 /*
418 * Macro to convert the chip register Clock Per Byte value to
419 * Synchronous Transfer Period.
420 */
421 #define ncr53c9x_cpb2stp(sc, cpb) \
422 ((250 * (cpb)) / (sc)->sc_freq)
423
424 void ncr53c9x_attach(struct ncr53c9x_softc *);
425 void ncr53c9x_reset(struct ncr53c9x_softc *);
426 int ncr53c9x_intr(void *);
427 void ncr53c9x_init(struct ncr53c9x_softc *, int);
Cache object: 25664f9f8d513bf68f583aeaf81071be
|