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