1 /* $FreeBSD$ */ 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 /* 179 * Soft Structure per host adapter 180 */ 181 struct ispsoftc { 182 /* 183 * Platform (OS) specific data 184 */ 185 struct isposinfo isp_osinfo; 186 187 /* 188 * Pointer to bus specific data 189 */ 190 struct ispmdvec * isp_mdvec; 191 192 /* 193 * State, debugging, etc.. 194 */ 195 196 u_int : 8, 197 isp_confopts : 8, 198 : 2, 199 isp_dblev : 3, 200 isp_gotdparms : 1, 201 isp_dogactive : 1, 202 isp_bustype : 1, /* BUS Implementation */ 203 isp_type : 8; /* HBA Type and Revision */ 204 205 u_int16_t isp_fwrev; /* Running F/W revision */ 206 u_int16_t isp_romfw_rev; /* 'ROM' F/W revision */ 207 void * isp_param; 208 209 /* 210 * Volatile state 211 */ 212 213 volatile u_int 214 : 19, 215 isp_state : 3, 216 isp_sendmarker : 1, /* send a marker entry */ 217 isp_update : 1, /* update paramters */ 218 isp_nactive : 9; /* how many commands active */ 219 220 /* 221 * Result and Request Queue indices. 222 */ 223 volatile u_int8_t isp_reqodx; /* index of last ISP pickup */ 224 volatile u_int8_t isp_reqidx; /* index of next request */ 225 volatile u_int8_t isp_residx; /* index of next result */ 226 volatile u_int8_t isp_seqno; /* rolling sequence # */ 227 228 /* 229 * Sheer laziness, but it gets us around the problem 230 * where we don't have a clean way of remembering 231 * which transaction is bound to which ISP queue entry. 232 * 233 * There are other more clever ways to do this, but, 234 * jeez, so I blow a couple of KB per host adapter... 235 * and it *is* faster. 236 */ 237 volatile ISP_SCSI_XFER_T *isp_xflist[RQUEST_QUEUE_LEN]; 238 239 /* 240 * request/result queues and dma handles for them. 241 */ 242 volatile caddr_t isp_rquest; 243 volatile caddr_t isp_result; 244 u_int32_t isp_rquest_dma; 245 u_int32_t isp_result_dma; 246 }; 247 248 /* 249 * ISP States 250 */ 251 #define ISP_NILSTATE 0 252 #define ISP_RESETSTATE 1 253 #define ISP_INITSTATE 2 254 #define ISP_RUNSTATE 3 255 256 /* 257 * ISP Configuration Options 258 */ 259 #define ISP_CFG_NORELOAD 0x80 /* don't download f/w */ 260 261 #define ISP_FW_REV(maj, min) ((maj) << 10| (min)) 262 263 /* 264 * Bus (implementation) types 265 */ 266 #define ISP_BT_PCI 0 /* PCI Implementations */ 267 #define ISP_BT_SBUS 1 /* SBus Implementations */ 268 269 /* 270 * Chip Types 271 */ 272 #define ISP_HA_SCSI 0xf 273 #define ISP_HA_SCSI_UNKNOWN 0x1 274 #define ISP_HA_SCSI_1020 0x2 275 #define ISP_HA_SCSI_1020A 0x3 276 #define ISP_HA_SCSI_1040 0x4 277 #define ISP_HA_SCSI_1040A 0x5 278 #define ISP_HA_SCSI_1040B 0x6 279 #define ISP_HA_FC 0xf0 280 #define ISP_HA_FC_2100 0x10 281 282 /* 283 * Macros to read, write ISP registers through MD code 284 */ 285 286 #define ISP_READ(isp, reg) \ 287 (*(isp)->isp_mdvec->dv_rd_reg)((isp), (reg)) 288 289 #define ISP_WRITE(isp, reg, val) \ 290 (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), (val)) 291 292 #define ISP_MBOXDMASETUP(isp) \ 293 (*(isp)->isp_mdvec->dv_mbxdma)((isp)) 294 295 #define ISP_DMASETUP(isp, xs, req, iptrp, optr) \ 296 (*(isp)->isp_mdvec->dv_dmaset)((isp), (xs), (req), (iptrp), (optr)) 297 298 #define ISP_DMAFREE(isp, xs, seqno) \ 299 if ((isp)->isp_mdvec->dv_dmaclr) \ 300 (*(isp)->isp_mdvec->dv_dmaclr)((isp), (xs), (seqno)) 301 302 #define ISP_RESET0(isp) \ 303 if ((isp)->isp_mdvec->dv_reset0) (*(isp)->isp_mdvec->dv_reset0)((isp)) 304 #define ISP_RESET1(isp) \ 305 if ((isp)->isp_mdvec->dv_reset1) (*(isp)->isp_mdvec->dv_reset1)((isp)) 306 #define ISP_DUMPREGS(isp) \ 307 if ((isp)->isp_mdvec->dv_dregs) (*(isp)->isp_mdvec->dv_dregs)((isp)) 308 309 #define ISP_SETBITS(isp, reg, val) \ 310 (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) | (val)) 311 312 #define ISP_CLRBITS(isp, reg, val) \ 313 (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) & ~(val)) 314 315 /* 316 * Function Prototypes 317 */ 318 319 /* 320 * Reset Hardware. Totally. Assumes that you'll follow this with 321 * a call to isp_init. 322 */ 323 void isp_reset __P((struct ispsoftc *)); 324 325 /* 326 * Initialize Hardware to known state 327 */ 328 void isp_init __P((struct ispsoftc *)); 329 330 /* 331 * Free any associated resources prior to decommissioning. 332 */ 333 void isp_uninit __P((struct ispsoftc *)); 334 335 /* 336 * Reset the ISP and call completion for any orphaned commands. 337 */ 338 void isp_restart __P((struct ispsoftc *)); 339 340 /* 341 * Interrupt Service Routine 342 */ 343 int isp_intr __P((void *)); 344 345 /* 346 * Watchdog Routine 347 */ 348 void isp_watch __P((void *)); 349 350 /* 351 * Command Entry Point 352 */ 353 int32_t ispscsicmd __P((ISP_SCSI_XFER_T *)); 354 355 /* 356 * Platform Dependent to Internal Control Point 357 * 358 * For: Aborting a running command - arg is an ISP_SCSI_XFER_T * 359 * Resetting a Device - arg is target to reset 360 * Resetting a BUS - arg is ignored 361 * Updating parameters - arg is ignored 362 * 363 * Second argument is an index into xflist array. 364 * Assumes all locks must be held already. 365 */ 366 typedef enum { 367 ISPCTL_RESET_BUS, 368 ISPCTL_RESET_DEV, 369 ISPCTL_ABORT_CMD, 370 ISPCTL_UPDATE_PARAMS, 371 } ispctl_t; 372 int isp_control __P((struct ispsoftc *, ispctl_t, void *)); 373 374 /* 375 * lost command routine (XXXX IN TRANSITION XXXX) 376 */ 377 void isp_lostcmd __P((struct ispsoftc *, ISP_SCSI_XFER_T *)); 378 379 380 #endif /* _ISPVAR_H */ 381