1 /* $OpenBSD: ncr53c9xvar.h,v 1.23 2014/01/18 23:09:04 dlg 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 scsi_link sc_link; /* scsi link struct */ 262 263 struct ncr53c9x_glue *sc_glue; /* glue to MD code */ 264 265 int sc_ntarg; /* number of targets */ 266 int sc_cfflags; /* Copy of config flags */ 267 268 /* register defaults */ 269 u_char sc_cfg1; /* Config 1 */ 270 u_char sc_cfg2; /* Config 2, not ESP100 */ 271 u_char sc_cfg3; /* Config 3, only ESP200 */ 272 u_char sc_cfg3_fscsi; /* Chip specific FSCSI bit */ 273 u_char sc_cfg4; /* Config 4 */ 274 u_char sc_cfg5; /* Config 5 */ 275 u_char sc_ccf; /* Clock Conversion */ 276 u_char sc_timeout; 277 278 /* register copies, see espreadregs() */ 279 u_char sc_espintr; 280 u_char sc_espstat; 281 u_char sc_espstep; 282 u_char sc_espstat2; 283 u_char sc_espfflags; 284 285 /* Lists of command blocks */ 286 TAILQ_HEAD(ecb_list, ncr53c9x_ecb) ready_list; 287 288 struct ncr53c9x_ecb *sc_nexus; /* Current command */ 289 struct ncr53c9x_tinfo sc_tinfo[NCR_NTARG]; 290 291 /* Data about the current nexus (updated for every cmd switch) */ 292 caddr_t sc_dp; /* Current data pointer */ 293 ssize_t sc_dleft; /* Data left to transfer */ 294 295 /* Adapter state */ 296 int sc_phase; /* Copy of what bus phase we are in */ 297 int sc_prevphase; /* Copy of what bus phase we were in */ 298 u_char sc_state; /* State applicable to the adapter */ 299 u_char sc_flags; /* See below */ 300 u_char sc_selid; 301 u_char sc_lastcmd; 302 303 /* Message stuff */ 304 u_short sc_msgify; /* IDENTIFY message associated with this nexus */ 305 u_short sc_msgout; /* What message is on its way out? */ 306 u_short sc_msgpriq; /* One or more messages to send (encoded) */ 307 u_short sc_msgoutq; /* What messages have been sent so far? */ 308 309 u_char *sc_omess; /* MSGOUT buffer */ 310 caddr_t sc_omp; /* Message pointer (for multibyte messages) */ 311 size_t sc_omlen; 312 u_char *sc_imess; /* MSGIN buffer */ 313 caddr_t sc_imp; /* Message pointer (for multibyte messages) */ 314 size_t sc_imlen; 315 316 caddr_t sc_cmdp; /* Command pointer (for DMAed commands) */ 317 size_t sc_cmdlen; /* Size of command in transit */ 318 319 /* Hardware attributes */ 320 int sc_freq; /* SCSI bus frequency in MHz */ 321 int sc_id; /* Our SCSI id */ 322 int sc_rev; /* Chip revision */ 323 int sc_features; /* Chip features */ 324 int sc_minsync; /* Minimum sync period / 4 */ 325 int sc_maxxfer; /* Maximum transfer size */ 326 }; 327 328 /* values for sc_state */ 329 #define NCR_IDLE 1 /* waiting for something to do */ 330 #define NCR_SELECTING 2 /* SCSI command is arbiting */ 331 #define NCR_RESELECTED 3 /* Has been reselected */ 332 #define NCR_IDENTIFIED 4 /* Has gotten IFY but not TAG */ 333 #define NCR_CONNECTED 5 /* Actively using the SCSI bus */ 334 #define NCR_DISCONNECT 6 /* MSG_DISCONNECT received */ 335 #define NCR_CMDCOMPLETE 7 /* MSG_CMDCOMPLETE received */ 336 #define NCR_CLEANING 8 337 #define NCR_SBR 9 /* Expect a SCSI RST because we commanded it */ 338 339 /* values for sc_flags */ 340 #define NCR_DROP_MSGI 0x01 /* Discard all msgs (parity err detected) */ 341 #define NCR_ABORTING 0x02 /* Bailing out */ 342 #define NCR_DOINGDMA 0x04 /* The FIFO data path is active! */ 343 #define NCR_SYNCHNEGO 0x08 /* Synch negotiation in progress. */ 344 #define NCR_ICCS 0x10 /* Expect status phase results */ 345 #define NCR_WAITI 0x20 /* Waiting for non-DMA data to arrive */ 346 #define NCR_ATN 0x40 /* ATN asserted */ 347 #define NCR_EXPECT_ILLCMD 0x80 /* Expect Illegal Command Interrupt */ 348 349 /* values for sc_features */ 350 #define NCR_F_HASCFG3 0x01 /* chip has CFG3 register */ 351 #define NCR_F_FASTSCSI 0x02 /* chip supports Fast mode */ 352 #define NCR_F_DMASELECT 0x04 /* can do dma select */ 353 #define NCR_F_SELATN3 0x08 /* can do selatn3 */ 354 355 /* values for sc_msgout */ 356 #define SEND_DEV_RESET 0x0001 357 #define SEND_PARITY_ERROR 0x0002 358 #define SEND_INIT_DET_ERR 0x0004 359 #define SEND_REJECT 0x0008 360 #define SEND_IDENTIFY 0x0010 361 #define SEND_ABORT 0x0020 362 #define SEND_WDTR 0x0040 363 #define SEND_SDTR 0x0080 364 #define SEND_TAG 0x0100 365 366 /* SCSI Status codes */ 367 #define ST_MASK 0x3e /* bit 0,6,7 is reserved */ 368 369 /* phase bits */ 370 #define IOI 0x01 371 #define CDI 0x02 372 #define MSGI 0x04 373 374 /* Information transfer phases */ 375 #define DATA_OUT_PHASE (0) 376 #define DATA_IN_PHASE (IOI) 377 #define COMMAND_PHASE (CDI) 378 #define STATUS_PHASE (CDI|IOI) 379 #define MESSAGE_OUT_PHASE (MSGI|CDI) 380 #define MESSAGE_IN_PHASE (MSGI|CDI|IOI) 381 382 #define PHASE_MASK (MSGI|CDI|IOI) 383 384 /* Some pseudo phases for getphase()*/ 385 #define BUSFREE_PHASE 0x100 /* Re/Selection no longer valid */ 386 #define INVALID_PHASE 0x101 /* Re/Selection valid, but no REQ yet */ 387 #define PSEUDO_PHASE 0x100 /* "pseudo" bit */ 388 389 /* 390 * Macros to read and write the chip's registers. 391 */ 392 #define NCR_READ_REG(sc, reg) \ 393 (*(sc)->sc_glue->gl_read_reg)((sc), (reg)) 394 #define NCR_WRITE_REG(sc, reg, val) \ 395 (*(sc)->sc_glue->gl_write_reg)((sc), (reg), (val)) 396 397 #ifdef NCR53C9X_DEBUG 398 #define NCRCMD(sc, cmd) do { \ 399 if (ncr53c9x_debug & NCR_SHOWCCMDS) \ 400 printf("<cmd:0x%x %d>", (unsigned)cmd, __LINE__); \ 401 sc->sc_lastcmd = cmd; \ 402 NCR_WRITE_REG(sc, NCR_CMD, cmd); \ 403 } while (0) 404 #else 405 #define NCRCMD(sc, cmd) NCR_WRITE_REG(sc, NCR_CMD, cmd) 406 #endif 407 408 /* 409 * DMA macros for NCR53c9x 410 */ 411 #define NCRDMA_ISINTR(sc) (*(sc)->sc_glue->gl_dma_isintr)((sc)) 412 #define NCRDMA_RESET(sc) (*(sc)->sc_glue->gl_dma_reset)((sc)) 413 #define NCRDMA_INTR(sc) (*(sc)->sc_glue->gl_dma_intr)((sc)) 414 #define NCRDMA_SETUP(sc, addr, len, datain, dmasize) \ 415 (*(sc)->sc_glue->gl_dma_setup)((sc), (addr), (len), (datain), (dmasize)) 416 #define NCRDMA_GO(sc) (*(sc)->sc_glue->gl_dma_go)((sc)) 417 #define NCRDMA_ISACTIVE(sc) (*(sc)->sc_glue->gl_dma_isactive)((sc)) 418 419 /* 420 * Macro to convert the chip register Clock Per Byte value to 421 * Synchronous Transfer Period. 422 */ 423 #define ncr53c9x_cpb2stp(sc, cpb) \ 424 ((250 * (cpb)) / (sc)->sc_freq) 425 426 void ncr53c9x_attach(struct ncr53c9x_softc *); 427 void ncr53c9x_reset(struct ncr53c9x_softc *); 428 int ncr53c9x_intr(void *); 429 void ncr53c9x_init(struct ncr53c9x_softc *, int); 430