ispvar.h revision 43793
1281526Sandrew/* $Id: ispvar.h,v 1.9 1999/01/30 07:29:00 mjacob Exp $ */ 2281526Sandrew/* release_02_05_99 */ 3281526Sandrew/* 4281526Sandrew * Soft Definitions for for Qlogic ISP SCSI adapters. 5281526Sandrew * 6281526Sandrew *--------------------------------------- 7281526Sandrew * Copyright (c) 1997, 1998 by Matthew Jacob 8281526Sandrew * NASA/Ames Research Center 9281526Sandrew * All rights reserved. 10281526Sandrew *--------------------------------------- 11281526Sandrew * Redistribution and use in source and binary forms, with or without 12281526Sandrew * modification, are permitted provided that the following conditions 13281526Sandrew * are met: 14281526Sandrew * 1. Redistributions of source code must retain the above copyright 15281526Sandrew * notice immediately at the beginning of the file, without modification, 16281526Sandrew * this list of conditions, and the following disclaimer. 17281526Sandrew * 2. Redistributions in binary form must reproduce the above copyright 18281526Sandrew * notice, this list of conditions and the following disclaimer in the 19281526Sandrew * documentation and/or other materials provided with the distribution. 20281526Sandrew * 3. The name of the author may not be used to endorse or promote products 21281526Sandrew * derived from this software without specific prior written permission. 22281526Sandrew * 23281526Sandrew * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24281526Sandrew * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25281526Sandrew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26281526Sandrew * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 27281526Sandrew * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28281526Sandrew * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29281526Sandrew * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30281526Sandrew * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31281526Sandrew * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32281526Sandrew * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33281526Sandrew * SUCH DAMAGE. 34281526Sandrew * 35281526Sandrew */ 36281526Sandrew 37281526Sandrew#ifndef _ISPVAR_H 38281526Sandrew#define _ISPVAR_H 39281526Sandrew 40281526Sandrew#ifdef __NetBSD__ 41281526Sandrew#include <dev/ic/ispmbox.h> 42281526Sandrew#endif 43281526Sandrew#ifdef __FreeBSD__ 44281526Sandrew#include <dev/isp/ispmbox.h> 45281526Sandrew#endif 46281526Sandrew#ifdef __linux__ 47281526Sandrew#include "ispmbox.h" 48281526Sandrew#endif 49281526Sandrew 50281526Sandrew#define ISP_CORE_VERSION_MAJOR 1 51281526Sandrew#define ISP_CORE_VERSION_MINOR 6 52281526Sandrew 53281526Sandrew/* 54281526Sandrew * Vector for bus specific code to provide specific services. 55281526Sandrew */ 56281526Sandrewstruct ispsoftc; 57281526Sandrewstruct ispmdvec { 58281526Sandrew u_int16_t (*dv_rd_reg) __P((struct ispsoftc *, int)); 59281526Sandrew void (*dv_wr_reg) __P((struct ispsoftc *, int, u_int16_t)); 60281526Sandrew int (*dv_mbxdma) __P((struct ispsoftc *)); 61281526Sandrew int (*dv_dmaset) __P((struct ispsoftc *, 62281526Sandrew ISP_SCSI_XFER_T *, ispreq_t *, u_int8_t *, u_int8_t)); 63281526Sandrew void (*dv_dmaclr) 64281526Sandrew __P((struct ispsoftc *, ISP_SCSI_XFER_T *, u_int32_t)); 65281526Sandrew void (*dv_reset0) __P((struct ispsoftc *)); 66281526Sandrew void (*dv_reset1) __P((struct ispsoftc *)); 67281526Sandrew void (*dv_dregs) __P((struct ispsoftc *)); 68281526Sandrew const u_int16_t *dv_ispfw; /* ptr to f/w */ 69281526Sandrew u_int16_t dv_fwlen; /* length of f/w */ 70281526Sandrew u_int16_t dv_codeorg; /* code ORG for f/w */ 71281526Sandrew u_int16_t dv_fwrev; /* f/w revision */ 72281526Sandrew /* 73281526Sandrew * Initial values for conf1 register 74281526Sandrew */ 75281526Sandrew u_int16_t dv_conf1; 76281526Sandrew u_int16_t dv_clock; /* clock frequency */ 77281526Sandrew}; 78281526Sandrew 79281526Sandrew#define MAX_TARGETS 16 80281526Sandrew#define MAX_FC_TARG 126 81281526Sandrew#define DEFAULT_LOOPID 113 82281526Sandrew 83281526Sandrew/* queue length must be a power of two */ 84281526Sandrew#define QENTRY_LEN 64 85281526Sandrew#define RQUEST_QUEUE_LEN MAXISPREQUEST 86281526Sandrew#define RESULT_QUEUE_LEN (MAXISPREQUEST/4) 87281526Sandrew#define ISP_QUEUE_ENTRY(q, idx) ((q) + ((idx) * QENTRY_LEN)) 88281526Sandrew#define ISP_QUEUE_SIZE(n) ((n) * QENTRY_LEN) 89281526Sandrew#define ISP_NXT_QENTRY(idx, qlen) (((idx) + 1) & ((qlen)-1)) 90281526Sandrew#define ISP_QAVAIL(in, out, qlen) \ 91281526Sandrew ((in == out)? (qlen - 1) : ((in > out)? \ 92281526Sandrew ((qlen - 1) - (in - out)) : (out - in - 1))) 93281526Sandrew/* 94281526Sandrew * SCSI Specific Host Adapter Parameters 95281526Sandrew */ 96281526Sandrew 97281526Sandrewtypedef struct { 98281526Sandrew u_int isp_req_ack_active_neg : 1, 99281526Sandrew isp_data_line_active_neg: 1, 100281526Sandrew isp_cmd_dma_burst_enable: 1, 101281526Sandrew isp_data_dma_burst_enabl: 1, 102281526Sandrew isp_fifo_threshold : 3, 103281526Sandrew isp_ultramode : 1, 104281526Sandrew isp_diffmode : 1, 105281526Sandrew isp_fast_mttr : 1, 106281526Sandrew isp_initiator_id : 4, 107281526Sandrew isp_async_data_setup : 4; 108281526Sandrew u_int16_t isp_selection_timeout; 109281526Sandrew u_int16_t isp_max_queue_depth; 110281526Sandrew u_int16_t isp_clock; 111281526Sandrew u_int8_t isp_tag_aging; 112281526Sandrew u_int8_t isp_bus_reset_delay; 113281526Sandrew u_int8_t isp_retry_count; 114281526Sandrew u_int8_t isp_retry_delay; 115281526Sandrew struct { 116281526Sandrew u_int 117281526Sandrew dev_enable : 1, 118281526Sandrew dev_announced : 1, 119281526Sandrew dev_update : 1, 120281526Sandrew dev_refresh : 1, 121281526Sandrew exc_throttle : 7, 122281526Sandrew sync_offset : 4, 123281526Sandrew sync_period : 8; 124281526Sandrew u_int16_t dev_flags; /* persistent device flags */ 125281526Sandrew u_int16_t cur_dflags; /* current device flags */ 126281526Sandrew } isp_devparam[MAX_TARGETS]; 127281526Sandrew} sdparam; /* scsi device parameters */ 128281526Sandrew 129281526Sandrew/* 130281526Sandrew * Device Flags 131281526Sandrew */ 132281526Sandrew#define DPARM_DISC 0x8000 133281526Sandrew#define DPARM_PARITY 0x4000 134281526Sandrew#define DPARM_WIDE 0x2000 135281526Sandrew#define DPARM_SYNC 0x1000 136281526Sandrew#define DPARM_TQING 0x0800 137281526Sandrew#define DPARM_ARQ 0x0400 138281526Sandrew#define DPARM_QFRZ 0x0200 139281526Sandrew#define DPARM_RENEG 0x0100 140281526Sandrew#define DPARM_NARROW 0x0080 /* Possibly only available with >= 7.55 fw */ 141281526Sandrew#define DPARM_ASYNC 0x0040 /* Possibly only available with >= 7.55 fw */ 142281526Sandrew#define DPARM_DEFAULT (0xFF00 & ~DPARM_QFRZ) 143281526Sandrew#define DPARM_SAFE_DFLT (DPARM_DEFAULT & ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING)) 144281526Sandrew 145281526Sandrew 146281526Sandrew#define ISP_20M_SYNCPARMS 0x080c 147281526Sandrew#define ISP_10M_SYNCPARMS 0x0c19 148281526Sandrew#define ISP_08M_SYNCPARMS 0x0c25 149281526Sandrew#define ISP_05M_SYNCPARMS 0x0c32 150281526Sandrew#define ISP_04M_SYNCPARMS 0x0c41 151281526Sandrew 152281526Sandrew/* 153281526Sandrew * Fibre Channel Specifics 154281526Sandrew */ 155281526Sandrewtypedef struct { 156281526Sandrew u_int64_t isp_wwn; /* WWN of adapter */ 157281526Sandrew u_int8_t isp_loopid; /* hard loop id */ 158281526Sandrew u_int8_t isp_alpa; /* ALPA */ 159281526Sandrew u_int8_t isp_execthrottle; 160281526Sandrew u_int8_t isp_retry_delay; 161281526Sandrew u_int8_t isp_retry_count; 162281526Sandrew u_int8_t isp_fwstate; /* ISP F/W state */ 163281526Sandrew u_int16_t isp_maxalloc; 164281526Sandrew u_int16_t isp_maxfrmlen; 165281526Sandrew u_int16_t isp_fwoptions; 166281526Sandrew /* 167281526Sandrew * Scratch DMA mapped in area to fetch Port Database stuff, etc. 168281526Sandrew */ 169281526Sandrew volatile caddr_t isp_scratch; 170281526Sandrew u_int32_t isp_scdma; 171281526Sandrew} fcparam; 172281526Sandrew 173281526Sandrew#define ISP2100_SCRLEN 0x100 174281526Sandrew 175281526Sandrew#define FW_CONFIG_WAIT 0x0000 176281526Sandrew#define FW_WAIT_AL_PA 0x0001 177281526Sandrew#define FW_WAIT_LOGIN 0x0002 178281526Sandrew#define FW_READY 0x0003 179281526Sandrew#define FW_LOSS_OF_SYNC 0x0004 180281526Sandrew#define FW_ERROR 0x0005 181281526Sandrew#define FW_REINIT 0x0006 182281526Sandrew#define FW_NON_PART 0x0007 183281526Sandrew 184281526Sandrew#ifdef ISP_TARGET_MODE 185281526Sandrew/* 186281526Sandrew * Some temporary Target Mode definitions 187281526Sandrew */ 188281526Sandrewtypedef struct tmd_cmd { 189281526Sandrew u_int8_t cd_iid; /* initiator */ 190281526Sandrew u_int8_t cd_tgt; /* target */ 191281526Sandrew u_int8_t cd_lun; /* LUN for this command */ 192281526Sandrew u_int8_t cd_state; 193281526Sandrew u_int8_t cd_cdb[16]; /* command bytes */ 194281526Sandrew u_int8_t cd_sensedata[20]; 195281526Sandrew u_int16_t cd_rxid; 196281526Sandrew u_int32_t cd_datalen; 197281526Sandrew u_int32_t cd_totbytes; 198281526Sandrew void * cd_hba; 199281526Sandrew} tmd_cmd_t; 200281526Sandrew 201281526Sandrew/* 202281526Sandrew * Async Target Mode Event Definitions 203281526Sandrew */ 204281526Sandrew#define TMD_BUS_RESET 0 205281526Sandrew#define TMD_BDR 1 206281526Sandrew 207281526Sandrew/* 208281526Sandrew * Immediate Notify data structure. 209281526Sandrew */ 210281526Sandrew#define NOTIFY_MSGLEN 5 211281526Sandrewtypedef struct { 212281526Sandrew u_int8_t nt_iid; /* initiator */ 213281526Sandrew u_int8_t nt_tgt; /* target */ 214281526Sandrew u_int8_t nt_lun; /* LUN for this command */ 215281526Sandrew u_int8_t nt_msg[NOTIFY_MSGLEN]; /* SCSI message byte(s) */ 216281526Sandrew} tmd_notify_t; 217281526Sandrew 218281526Sandrew#endif 219281526Sandrew 220/* 221 * Soft Structure per host adapter 222 */ 223struct ispsoftc { 224 /* 225 * Platform (OS) specific data 226 */ 227 struct isposinfo isp_osinfo; 228 229 /* 230 * Pointer to bus specific data 231 */ 232 struct ispmdvec * isp_mdvec; 233 234 /* 235 * Mostly nonvolatile state, debugging, etc.. 236 */ 237 238 u_int : 8, 239 isp_confopts : 8, 240 : 2, 241 isp_dblev : 3, 242 isp_gotdparms : 1, 243 isp_dogactive : 1, 244 isp_bustype : 1, /* BUS Implementation */ 245 isp_type : 8; /* HBA Type and Revision */ 246 247 u_int16_t isp_fwrev; /* Running F/W revision */ 248 u_int16_t isp_romfw_rev; /* 'ROM' F/W revision */ 249 void * isp_param; 250 251 /* 252 * Volatile state 253 */ 254 255 volatile u_int 256 : 19, 257 isp_state : 3, 258 isp_sendmarker : 1, /* send a marker entry */ 259 isp_update : 1, /* update paramters */ 260 isp_nactive : 9; /* how many commands active */ 261 262 /* 263 * Result and Request Queue indices. 264 */ 265 volatile u_int8_t isp_reqodx; /* index of last ISP pickup */ 266 volatile u_int8_t isp_reqidx; /* index of next request */ 267 volatile u_int8_t isp_residx; /* index of next result */ 268 volatile u_int8_t isp_seqno; /* rolling sequence # */ 269 270 /* 271 * Sheer laziness, but it gets us around the problem 272 * where we don't have a clean way of remembering 273 * which transaction is bound to which ISP queue entry. 274 * 275 * There are other more clever ways to do this, but, 276 * jeez, so I blow a couple of KB per host adapter... 277 * and it *is* faster. 278 */ 279 ISP_SCSI_XFER_T *isp_xflist[RQUEST_QUEUE_LEN]; 280 281 /* 282 * request/result queues and dma handles for them. 283 */ 284 volatile caddr_t isp_rquest; 285 volatile caddr_t isp_result; 286 u_int32_t isp_rquest_dma; 287 u_int32_t isp_result_dma; 288 289#ifdef ISP_TARGET_MODE 290 /* 291 * Vectors for handling target mode support. 292 * 293 * isp_tmd_newcmd is for feeding a newly arrived command to some 294 * upper layer. 295 * 296 * isp_tmd_event is for notifying some upper layer that an event has 297 * occurred that is not necessarily tied to any target (e.g., a SCSI 298 * Bus Reset). 299 * 300 * isp_tmd_notify is for notifying some upper layer that some 301 * event is now occurring that is either pertinent for a specific 302 * device or for a specific command (e.g., BDR or ABORT TAG). 303 * 304 * It is left undefined (for now) how pools of commands are managed. 305 */ 306 void (*isp_tmd_newcmd) __P((void *, tmd_cmd_t *)); 307 void (*isp_tmd_event) __P((void *, int)); 308 void (*isp_tmd_notify) __P((void *, tmd_notify_t *)); 309#endif 310}; 311 312/* 313 * ISP States 314 */ 315#define ISP_NILSTATE 0 316#define ISP_RESETSTATE 1 317#define ISP_INITSTATE 2 318#define ISP_RUNSTATE 3 319 320/* 321 * ISP Configuration Options 322 */ 323#define ISP_CFG_NORELOAD 0x80 /* don't download f/w */ 324#define ISP_CFG_NONVRAM 0x40 /* ignore NVRAM */ 325 326#define ISP_FW_REV(maj, min) ((maj) << 10| (min)) 327 328/* 329 * Bus (implementation) types 330 */ 331#define ISP_BT_PCI 0 /* PCI Implementations */ 332#define ISP_BT_SBUS 1 /* SBus Implementations */ 333 334/* 335 * Chip Types 336 */ 337#define ISP_HA_SCSI 0xf 338#define ISP_HA_SCSI_UNKNOWN 0x1 339#define ISP_HA_SCSI_1020 0x2 340#define ISP_HA_SCSI_1020A 0x3 341#define ISP_HA_SCSI_1040 0x4 342#define ISP_HA_SCSI_1040A 0x5 343#define ISP_HA_SCSI_1040B 0x6 344#define ISP_HA_FC 0xf0 345#define ISP_HA_FC_2100 0x10 346 347/* 348 * Macros to read, write ISP registers through bus specific code. 349 */ 350 351#define ISP_READ(isp, reg) \ 352 (*(isp)->isp_mdvec->dv_rd_reg)((isp), (reg)) 353 354#define ISP_WRITE(isp, reg, val) \ 355 (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), (val)) 356 357#define ISP_MBOXDMASETUP(isp) \ 358 (*(isp)->isp_mdvec->dv_mbxdma)((isp)) 359 360#define ISP_DMASETUP(isp, xs, req, iptrp, optr) \ 361 (*(isp)->isp_mdvec->dv_dmaset)((isp), (xs), (req), (iptrp), (optr)) 362 363#define ISP_DMAFREE(isp, xs, seqno) \ 364 if ((isp)->isp_mdvec->dv_dmaclr) \ 365 (*(isp)->isp_mdvec->dv_dmaclr)((isp), (xs), (seqno)) 366 367#define ISP_RESET0(isp) \ 368 if ((isp)->isp_mdvec->dv_reset0) (*(isp)->isp_mdvec->dv_reset0)((isp)) 369#define ISP_RESET1(isp) \ 370 if ((isp)->isp_mdvec->dv_reset1) (*(isp)->isp_mdvec->dv_reset1)((isp)) 371#define ISP_DUMPREGS(isp) \ 372 if ((isp)->isp_mdvec->dv_dregs) (*(isp)->isp_mdvec->dv_dregs)((isp)) 373 374#define ISP_SETBITS(isp, reg, val) \ 375 (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) | (val)) 376 377#define ISP_CLRBITS(isp, reg, val) \ 378 (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) & ~(val)) 379 380/* 381 * Function Prototypes 382 */ 383 384/* 385 * Reset Hardware. Totally. Assumes that you'll follow this with 386 * a call to isp_init. 387 */ 388void isp_reset __P((struct ispsoftc *)); 389 390/* 391 * Initialize Hardware to known state 392 */ 393void isp_init __P((struct ispsoftc *)); 394 395/* 396 * Reset the ISP and call completion for any orphaned commands. 397 */ 398void isp_restart __P((struct ispsoftc *)); 399 400/* 401 * Interrupt Service Routine 402 */ 403int isp_intr __P((void *)); 404 405/* 406 * Command Entry Point 407 */ 408int32_t ispscsicmd __P((ISP_SCSI_XFER_T *)); 409 410/* 411 * Platform Dependent to External to Internal Control Function 412 * 413 * For: Aborting a running command - arg is an ISP_SCSI_XFER_T * 414 * Resetting a Device - arg is target to reset 415 * Resetting a BUS - arg is ignored 416 * Updating parameters - arg is ignored 417 * 418 * First argument is this instance's softc pointer. 419 * Second argument is an index into xflist array. 420 * Assumes all locks must be held already. 421 */ 422typedef enum { 423 ISPCTL_RESET_BUS, 424 ISPCTL_RESET_DEV, 425 ISPCTL_ABORT_CMD, 426 ISPCTL_UPDATE_PARAMS, 427} ispctl_t; 428int isp_control __P((struct ispsoftc *, ispctl_t, void *)); 429 430 431/* 432 * Platform Dependent to Internal to External Control Function 433 * (each platform must provide such a function) 434 * 435 * For: Announcing Target Paramter Changes (arg is target) 436 * 437 * Assumes all locks are held. 438 */ 439 440typedef enum { 441 ISPASYNC_NEW_TGT_PARAMS, 442 ISPASYNC_LOOP_DOWN, /* Obvious FC only */ 443 ISPASYNC_LOOP_UP /* Obvious FC only */ 444} ispasync_t; 445int isp_async __P((struct ispsoftc *, ispasync_t, void *)); 446 447/* 448 * lost command routine (XXXX IN TRANSITION XXXX) 449 */ 450void isp_lostcmd __P((struct ispsoftc *, ISP_SCSI_XFER_T *)); 451 452 453#endif /* _ISPVAR_H */ 454