1 /* $Id: ispvar.h,v 1.17 1998/09/14 23:22:51 mjacob Exp $ */ 2 /* 3 * Soft Definitions for for Qlogic ISP SCSI adapters. 4 * 5 *--------------------------------------- 6 * Copyright (c) 1997, 1998 by Matthew Jacob 7 * NASA/Ames Research Center 8 * All rights reserved. 9 *--------------------------------------- 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice immediately at the beginning of the file, without modification, 15 * this list of conditions, and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 26 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 */ 35 36 #ifndef _ISPVAR_H 37 #define _ISPVAR_H 38 39 #ifdef __NetBSD__ 40 #include <dev/ic/ispmbox.h> 41 #endif 42 #ifdef __FreeBSD__ 43 #include <dev/isp/ispmbox.h> 44 #endif 45 #ifdef __linux__ 46 #include <ispmbox.h> 47 #endif 48 49 #define ISP_CORE_VERSION_MAJOR 1 50 #define ISP_CORE_VERSION_MINOR 3 51 52 /* 53 * Vector for MD code to provide specific services. 54 */ 55 struct ispsoftc; 56 struct ispmdvec { 57 u_int16_t (*dv_rd_reg) __P((struct ispsoftc *, int)); 58 void (*dv_wr_reg) __P((struct ispsoftc *, int, u_int16_t)); 59 int (*dv_mbxdma) __P((struct ispsoftc *)); 60 int (*dv_dmaset) __P((struct ispsoftc *, 61 ISP_SCSI_XFER_T *, ispreq_t *, u_int8_t *, u_int8_t)); 62 void (*dv_dmaclr) 63 __P((struct ispsoftc *, ISP_SCSI_XFER_T *, u_int32_t)); 64 void (*dv_reset0) __P((struct ispsoftc *)); 65 void (*dv_reset1) __P((struct ispsoftc *)); 66 void (*dv_dregs) __P((struct ispsoftc *)); 67 const u_int16_t *dv_ispfw; /* ptr to f/w */ 68 u_int16_t dv_fwlen; /* length of f/w */ 69 u_int16_t dv_codeorg; /* code ORG for f/w */ 70 u_int16_t dv_fwrev; /* f/w revision */ 71 /* 72 * Initial values for conf1 register 73 */ 74 u_int16_t dv_conf1; 75 u_int16_t dv_clock; /* clock frequency */ 76 }; 77 78 #define MAX_TARGETS 16 79 #define MAX_FC_TARG 126 80 81 /* queue length must be a power of two */ 82 #define QENTRY_LEN 64 83 #define RQUEST_QUEUE_LEN MAXISPREQUEST 84 #define RESULT_QUEUE_LEN (MAXISPREQUEST/4) 85 #define ISP_QUEUE_ENTRY(q, idx) ((q) + ((idx) * QENTRY_LEN)) 86 #define ISP_QUEUE_SIZE(n) ((n) * QENTRY_LEN) 87 #define ISP_NXT_QENTRY(idx, qlen) (((idx) + 1) & ((qlen)-1)) 88 #define ISP_QAVAIL(in, out, qlen) \ 89 ((in == out)? (qlen - 1) : ((in > out)? \ 90 ((qlen - 1) - (in - out)) : (out - in - 1))) 91 /* 92 * SCSI (as opposed to FC-PH) Specific Host Adapter Parameters 93 */ 94 95 typedef struct { 96 u_int isp_req_ack_active_neg : 1, 97 isp_data_line_active_neg: 1, 98 isp_cmd_dma_burst_enable: 1, 99 isp_data_dma_burst_enabl: 1, 100 isp_fifo_threshold : 2, 101 isp_diffmode : 1, 102 isp_fast_mttr : 1, 103 isp_initiator_id : 4, 104 isp_async_data_setup : 4; 105 u_int16_t isp_selection_timeout; 106 u_int16_t isp_max_queue_depth; 107 u_int16_t isp_clock; 108 u_int8_t isp_tag_aging; 109 u_int8_t isp_bus_reset_delay; 110 u_int8_t isp_retry_count; 111 u_int8_t isp_retry_delay; 112 struct { 113 u_int dev_update : 1, 114 dev_enable : 1, 115 exc_throttle : 7, 116 sync_offset : 4, 117 sync_period : 8; 118 u_int16_t dev_flags; /* persistent device flags */ 119 u_int16_t cur_dflags; /* current device flags */ 120 } isp_devparam[MAX_TARGETS]; 121 } sdparam; /* scsi device parameters */ 122 123 /* 124 * Device Flags 125 */ 126 #define DPARM_DISC 0x8000 127 #define DPARM_PARITY 0x4000 128 #define DPARM_WIDE 0x2000 129 #define DPARM_SYNC 0x1000 130 #define DPARM_TQING 0x0800 131 #define DPARM_ARQ 0x0400 132 #define DPARM_QFRZ 0x0200 133 #define DPARM_RENEG 0x0100 134 #define DPARM_NARROW 0x0080 /* Possibly only available with >= 7.55 fw */ 135 #define DPARM_ASYNC 0x0040 /* Possibly only available with >= 7.55 fw */ 136 #define DPARM_DEFAULT (0xFFFF & ~DPARM_QFRZ) 137 #define DPARM_SAFE_DFLT (DPARM_DEFAULT & ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING)) 138 139 140 #define ISP_20M_SYNCPARMS 0x080c 141 #define ISP_10M_SYNCPARMS 0x0c19 142 #define ISP_08M_SYNCPARMS 0x0c25 143 #define ISP_05M_SYNCPARMS 0x0c32 144 #define ISP_04M_SYNCPARMS 0x0c41 145 146 /* 147 * Fibre Channel Specifics 148 */ 149 typedef struct { 150 u_int64_t isp_wwn; /* WWN of adapter */ 151 u_int8_t isp_loopid; /* hard loop id */ 152 u_int8_t isp_alpa; /* ALPA */ 153 u_int8_t isp_execthrottle; 154 u_int8_t isp_retry_delay; 155 u_int8_t isp_retry_count; 156 u_int8_t isp_fwstate; /* ISP F/W state */ 157 u_int16_t isp_maxalloc; 158 u_int16_t isp_maxfrmlen; 159 u_int16_t isp_fwoptions; 160 /* 161 * Scratch DMA mapped in area to fetch Port Database stuff, etc. 162 */ 163 volatile caddr_t isp_scratch; 164 u_int32_t isp_scdma; 165 } fcparam; 166 167 #define ISP2100_SCRLEN 0x100 168 169 #define FW_CONFIG_WAIT 0x0000 170 #define FW_WAIT_AL_PA 0x0001 171 #define FW_WAIT_LOGIN 0x0002 172 #define FW_READY 0x0003 173 #define FW_LOSS_OF_SYNC 0x0004 174 #define FW_ERROR 0x0005 175 #define FW_REINIT 0x0006 176 #define FW_NON_PART 0x0007 177 178 static __inline char *fw_statename __P((u_int8_t x)); 179 static __inline char * 180 fw_statename(x) 181 u_int8_t x; 182 { 183 switch(x) { 184 case FW_CONFIG_WAIT: return "Config Wait"; 185 case FW_WAIT_AL_PA: return "Waiting for AL/PA"; 186 case FW_WAIT_LOGIN: return "Wait Login"; 187 case FW_READY: return "Ready"; 188 case FW_LOSS_OF_SYNC: return "Loss Of Sync"; 189 case FW_ERROR: return "Error"; 190 case FW_REINIT: return "Re-Init"; 191 case FW_NON_PART: return "Nonparticipating"; 192 default: return "eh?"; 193 } 194 } 195 196 /* 197 * Soft Structure per host adapter 198 */ 199 struct ispsoftc { 200 /* 201 * Platform (OS) specific data 202 */ 203 struct isposinfo isp_osinfo; 204 205 /* 206 * Pointer to bus specific data 207 */ 208 struct ispmdvec * isp_mdvec; 209 210 /* 211 * State, debugging, etc.. 212 */ 213 214 u_int : 8, 215 isp_confopts : 8, 216 : 2, 217 isp_dblev : 3, 218 isp_gotdparms : 1, 219 isp_dogactive : 1, 220 isp_bustype : 1, /* BUS Implementation */ 221 isp_type : 8; /* HBA Type and Revision */ 222 223 u_int16_t isp_fwrev; /* Running F/W revision */ 224 u_int16_t isp_romfw_rev; /* 'ROM' F/W revision */ 225 void * isp_param; 226 227 /* 228 * Volatile state 229 */ 230 231 volatile u_int 232 : 19, 233 isp_state : 3, 234 isp_sendmarker : 1, /* send a marker entry */ 235 isp_update : 1, /* update paramters */ 236 isp_nactive : 9; /* how many commands active */ 237 238 /* 239 * Result and Request Queue indices. 240 */ 241 volatile u_int8_t isp_reqodx; /* index of last ISP pickup */ 242 volatile u_int8_t isp_reqidx; /* index of next request */ 243 volatile u_int8_t isp_residx; /* index of next result */ 244 volatile u_int8_t isp_seqno; /* rolling sequence # */ 245 246 /* 247 * Sheer laziness, but it gets us around the problem 248 * where we don't have a clean way of remembering 249 * which transaction is bound to which ISP queue entry. 250 * 251 * There are other more clever ways to do this, but, 252 * jeez, so I blow a couple of KB per host adapter... 253 * and it *is* faster. 254 */ 255 volatile ISP_SCSI_XFER_T *isp_xflist[RQUEST_QUEUE_LEN]; 256 257 /* 258 * request/result queues and dma handles for them. 259 */ 260 volatile caddr_t isp_rquest; 261 volatile caddr_t isp_result; 262 u_int32_t isp_rquest_dma; 263 u_int32_t isp_result_dma; 264 }; 265 266 /* 267 * ISP States 268 */ 269 #define ISP_NILSTATE 0 270 #define ISP_RESETSTATE 1 271 #define ISP_INITSTATE 2 272 #define ISP_RUNSTATE 3 273 274 /* 275 * ISP Configuration Options 276 */ 277 #define ISP_CFG_NORELOAD 0x80 /* don't download f/w */ 278 279 #define ISP_FW_REV(maj, min) ((maj) << 10| (min)) 280 281 /* 282 * Bus (implementation) types 283 */ 284 #define ISP_BT_PCI 0 /* PCI Implementations */ 285 #define ISP_BT_SBUS 1 /* SBus Implementations */ 286 287 /* 288 * Chip Types 289 */ 290 #define ISP_HA_SCSI 0xf 291 #define ISP_HA_SCSI_UNKNOWN 0x1 292 #define ISP_HA_SCSI_1020 0x2 293 #define ISP_HA_SCSI_1020A 0x3 294 #define ISP_HA_SCSI_1040 0x4 295 #define ISP_HA_SCSI_1040A 0x5 296 #define ISP_HA_SCSI_1040B 0x6 297 #define ISP_HA_FC 0xf0 298 #define ISP_HA_FC_2100 0x10 299 300 /* 301 * Macros to read, write ISP registers through MD code 302 */ 303 304 #define ISP_READ(isp, reg) \ 305 (*(isp)->isp_mdvec->dv_rd_reg)((isp), (reg)) 306 307 #define ISP_WRITE(isp, reg, val) \ 308 (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), (val)) 309 310 #define ISP_MBOXDMASETUP(isp) \ 311 (*(isp)->isp_mdvec->dv_mbxdma)((isp)) 312 313 #define ISP_DMASETUP(isp, xs, req, iptrp, optr) \ 314 (*(isp)->isp_mdvec->dv_dmaset)((isp), (xs), (req), (iptrp), (optr)) 315 316 #define ISP_DMAFREE(isp, xs, seqno) \ 317 if ((isp)->isp_mdvec->dv_dmaclr) \ 318 (*(isp)->isp_mdvec->dv_dmaclr)((isp), (xs), (seqno)) 319 320 #define ISP_RESET0(isp) \ 321 if ((isp)->isp_mdvec->dv_reset0) (*(isp)->isp_mdvec->dv_reset0)((isp)) 322 #define ISP_RESET1(isp) \ 323 if ((isp)->isp_mdvec->dv_reset1) (*(isp)->isp_mdvec->dv_reset1)((isp)) 324 #define ISP_DUMPREGS(isp) \ 325 if ((isp)->isp_mdvec->dv_dregs) (*(isp)->isp_mdvec->dv_dregs)((isp)) 326 327 #define ISP_SETBITS(isp, reg, val) \ 328 (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) | (val)) 329 330 #define ISP_CLRBITS(isp, reg, val) \ 331 (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) & ~(val)) 332 333 /* 334 * Function Prototypes 335 */ 336 337 /* 338 * Reset Hardware. Totally. Assumes that you'll follow this with 339 * a call to isp_init. 340 */ 341 void isp_reset __P((struct ispsoftc *)); 342 343 /* 344 * Initialize Hardware to known state 345 */ 346 void isp_init __P((struct ispsoftc *)); 347 348 /* 349 * Free any associated resources prior to decommissioning. 350 */ 351 void isp_uninit __P((struct ispsoftc *)); 352 353 /* 354 * Reset the ISP and call completion for any orphaned commands. 355 */ 356 void isp_restart __P((struct ispsoftc *)); 357 358 /* 359 * Interrupt Service Routine 360 */ 361 int isp_intr __P((void *)); 362 363 /* 364 * Watchdog Routine 365 */ 366 void isp_watch __P((void *)); 367 368 /* 369 * Command Entry Point 370 */ 371 int32_t ispscsicmd __P((ISP_SCSI_XFER_T *)); 372 373 /* 374 * Platform Dependent to Internal Control Point 375 * 376 * For: Aborting a running command - arg is an ISP_SCSI_XFER_T * 377 * Resetting a Device - arg is target to reset 378 * Resetting a BUS - arg is ignored 379 * Updating parameters - arg is ignored 380 * 381 * Second argument is an index into xflist array. 382 * Assumes all locks must be held already. 383 */ 384 typedef enum { 385 ISPCTL_RESET_BUS, 386 ISPCTL_RESET_DEV, 387 ISPCTL_ABORT_CMD, 388 ISPCTL_UPDATE_PARAMS, 389 } ispctl_t; 390 int isp_control __P((struct ispsoftc *, ispctl_t, void *)); 391 392 /* 393 * lost command routine (XXXX IN TRANSITION XXXX) 394 */ 395 void isp_lostcmd __P((struct ispsoftc *, ISP_SCSI_XFER_T *)); 396 397 398 #endif /* _ISPVAR_H */ 399