1c3aac50fSPeter Wemm /* $FreeBSD$ */ 26054c3f6SMatt Jacob /* 36054c3f6SMatt Jacob * Soft Definitions for for Qlogic ISP SCSI adapters. 46054c3f6SMatt Jacob * 5aa57fd6fSMatt Jacob * Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob 66054c3f6SMatt Jacob * All rights reserved. 77e90346eSMatt Jacob * 86054c3f6SMatt Jacob * Redistribution and use in source and binary forms, with or without 96054c3f6SMatt Jacob * modification, are permitted provided that the following conditions 106054c3f6SMatt Jacob * are met: 116054c3f6SMatt Jacob * 1. Redistributions of source code must retain the above copyright 126054c3f6SMatt Jacob * notice immediately at the beginning of the file, without modification, 136054c3f6SMatt Jacob * this list of conditions, and the following disclaimer. 14aa57fd6fSMatt Jacob * 2. The name of the author may not be used to endorse or promote products 156054c3f6SMatt Jacob * derived from this software without specific prior written permission. 166054c3f6SMatt Jacob * 176054c3f6SMatt Jacob * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 186054c3f6SMatt Jacob * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 196054c3f6SMatt Jacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 206054c3f6SMatt Jacob * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 216054c3f6SMatt Jacob * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 226054c3f6SMatt Jacob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 236054c3f6SMatt Jacob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 246054c3f6SMatt Jacob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 256054c3f6SMatt Jacob * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 266054c3f6SMatt Jacob * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 276054c3f6SMatt Jacob * SUCH DAMAGE. 286054c3f6SMatt Jacob * 296054c3f6SMatt Jacob */ 306054c3f6SMatt Jacob 316054c3f6SMatt Jacob #ifndef _ISPVAR_H 326054c3f6SMatt Jacob #define _ISPVAR_H 336054c3f6SMatt Jacob 3457c801f5SMatt Jacob #if defined(__NetBSD__) || defined(__OpenBSD__) 356054c3f6SMatt Jacob #include <dev/ic/ispmbox.h> 3680ae5655SMatt Jacob #ifdef ISP_TARGET_MODE 3780ae5655SMatt Jacob #include <dev/ic/isp_target.h> 386b016bfdSMatt Jacob #include <dev/ic/isp_tpublic.h> 3980ae5655SMatt Jacob #endif 406054c3f6SMatt Jacob #endif 416054c3f6SMatt Jacob #ifdef __FreeBSD__ 426054c3f6SMatt Jacob #include <dev/isp/ispmbox.h> 4380ae5655SMatt Jacob #ifdef ISP_TARGET_MODE 4480ae5655SMatt Jacob #include <dev/isp/isp_target.h> 456b016bfdSMatt Jacob #include <dev/isp/isp_tpublic.h> 4680ae5655SMatt Jacob #endif 476054c3f6SMatt Jacob #endif 486054c3f6SMatt Jacob #ifdef __linux__ 49c3055363SMatt Jacob #include "ispmbox.h" 5080ae5655SMatt Jacob #ifdef ISP_TARGET_MODE 5180ae5655SMatt Jacob #include "isp_target.h" 526b016bfdSMatt Jacob #include "isp_tpublic.h" 5380ae5655SMatt Jacob #endif 546054c3f6SMatt Jacob #endif 556054c3f6SMatt Jacob 5653cff3bbSMatt Jacob #define ISP_CORE_VERSION_MAJOR 2 570499ae00SMatt Jacob #define ISP_CORE_VERSION_MINOR 7 58478f8a96SJustin T. Gibbs 596054c3f6SMatt Jacob /* 60cbf57b47SMatt Jacob * Vector for bus specific code to provide specific services. 616054c3f6SMatt Jacob */ 626054c3f6SMatt Jacob struct ispsoftc; 636054c3f6SMatt Jacob struct ispmdvec { 64126ec864SMatt Jacob int (*dv_rd_isr) 65126ec864SMatt Jacob (struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *); 66e2ec5cf0SMatt Jacob u_int16_t (*dv_rd_reg) (struct ispsoftc *, int); 67e2ec5cf0SMatt Jacob void (*dv_wr_reg) (struct ispsoftc *, int, u_int16_t); 68e2ec5cf0SMatt Jacob int (*dv_mbxdma) (struct ispsoftc *); 69e2ec5cf0SMatt Jacob int (*dv_dmaset) (struct ispsoftc *, 70e2ec5cf0SMatt Jacob XS_T *, ispreq_t *, u_int16_t *, u_int16_t); 716054c3f6SMatt Jacob void (*dv_dmaclr) 72e2ec5cf0SMatt Jacob (struct ispsoftc *, XS_T *, u_int16_t); 73e2ec5cf0SMatt Jacob void (*dv_reset0) (struct ispsoftc *); 74e2ec5cf0SMatt Jacob void (*dv_reset1) (struct ispsoftc *); 75e2ec5cf0SMatt Jacob void (*dv_dregs) (struct ispsoftc *, const char *); 76371777b1SMatt Jacob u_int16_t *dv_ispfw; /* ptr to f/w */ 776054c3f6SMatt Jacob u_int16_t dv_conf1; 786054c3f6SMatt Jacob u_int16_t dv_clock; /* clock frequency */ 796054c3f6SMatt Jacob }; 806054c3f6SMatt Jacob 8153cff3bbSMatt Jacob /* 8253cff3bbSMatt Jacob * Overall parameters 8353cff3bbSMatt Jacob */ 846054c3f6SMatt Jacob #define MAX_TARGETS 16 8557c801f5SMatt Jacob #define MAX_FC_TARG 256 860f747d72SMatt Jacob #define ISP_MAX_TARGETS(isp) (IS_FC(isp)? MAX_FC_TARG : MAX_TARGETS) 875e09512cSMatt Jacob #define ISP_MAX_LUNS(isp) (isp)->isp_maxluns 880f747d72SMatt Jacob 89126ec864SMatt Jacob /* 90126ec864SMatt Jacob * 'Types' 91126ec864SMatt Jacob */ 9266cbe912SMatt Jacob #ifdef ISP_DAC_SUPPORTED 9366cbe912SMatt Jacob typedef u_int64_t isp_dma_addr_t; 9466cbe912SMatt Jacob #else 9566cbe912SMatt Jacob typedef u_int32_t isp_dma_addr_t; 96126ec864SMatt Jacob #endif 9780ae5655SMatt Jacob 9880ae5655SMatt Jacob /* 9953cff3bbSMatt Jacob * Macros to access ISP registers through bus specific layers- 10053cff3bbSMatt Jacob * mostly wrappers to vector through the mdvec structure. 10180ae5655SMatt Jacob */ 102126ec864SMatt Jacob #define ISP_READ_ISR(isp, isrp, semap, mbox0p) \ 103126ec864SMatt Jacob (*(isp)->isp_mdvec->dv_rd_isr)(isp, isrp, semap, mbox0p) 10480ae5655SMatt Jacob 10580ae5655SMatt Jacob #define ISP_READ(isp, reg) \ 10680ae5655SMatt Jacob (*(isp)->isp_mdvec->dv_rd_reg)((isp), (reg)) 10780ae5655SMatt Jacob 10880ae5655SMatt Jacob #define ISP_WRITE(isp, reg, val) \ 10980ae5655SMatt Jacob (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), (val)) 11080ae5655SMatt Jacob 11180ae5655SMatt Jacob #define ISP_MBOXDMASETUP(isp) \ 11280ae5655SMatt Jacob (*(isp)->isp_mdvec->dv_mbxdma)((isp)) 11380ae5655SMatt Jacob 11480ae5655SMatt Jacob #define ISP_DMASETUP(isp, xs, req, iptrp, optr) \ 11580ae5655SMatt Jacob (*(isp)->isp_mdvec->dv_dmaset)((isp), (xs), (req), (iptrp), (optr)) 11680ae5655SMatt Jacob 11780ae5655SMatt Jacob #define ISP_DMAFREE(isp, xs, hndl) \ 11880ae5655SMatt Jacob if ((isp)->isp_mdvec->dv_dmaclr) \ 11980ae5655SMatt Jacob (*(isp)->isp_mdvec->dv_dmaclr)((isp), (xs), (hndl)) 12080ae5655SMatt Jacob 12180ae5655SMatt Jacob #define ISP_RESET0(isp) \ 12280ae5655SMatt Jacob if ((isp)->isp_mdvec->dv_reset0) (*(isp)->isp_mdvec->dv_reset0)((isp)) 12380ae5655SMatt Jacob #define ISP_RESET1(isp) \ 12480ae5655SMatt Jacob if ((isp)->isp_mdvec->dv_reset1) (*(isp)->isp_mdvec->dv_reset1)((isp)) 12553cff3bbSMatt Jacob #define ISP_DUMPREGS(isp, m) \ 12653cff3bbSMatt Jacob if ((isp)->isp_mdvec->dv_dregs) (*(isp)->isp_mdvec->dv_dregs)((isp),(m)) 12780ae5655SMatt Jacob 12880ae5655SMatt Jacob #define ISP_SETBITS(isp, reg, val) \ 12980ae5655SMatt Jacob (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) | (val)) 13080ae5655SMatt Jacob 13180ae5655SMatt Jacob #define ISP_CLRBITS(isp, reg, val) \ 13280ae5655SMatt Jacob (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) & ~(val)) 13380ae5655SMatt Jacob 13453cff3bbSMatt Jacob /* 13553cff3bbSMatt Jacob * The MEMORYBARRIER macro is defined per platform (to provide synchronization 13653cff3bbSMatt Jacob * on Request and Response Queues, Scratch DMA areas, and Registers) 13753cff3bbSMatt Jacob * 13853cff3bbSMatt Jacob * Defined Memory Barrier Synchronization Types 13953cff3bbSMatt Jacob */ 14053cff3bbSMatt Jacob #define SYNC_REQUEST 0 /* request queue synchronization */ 14153cff3bbSMatt Jacob #define SYNC_RESULT 1 /* result queue synchronization */ 14253cff3bbSMatt Jacob #define SYNC_SFORDEV 2 /* scratch, sync for ISP */ 14353cff3bbSMatt Jacob #define SYNC_SFORCPU 3 /* scratch, sync for CPU */ 14453cff3bbSMatt Jacob #define SYNC_REG 4 /* for registers */ 14553cff3bbSMatt Jacob 14653cff3bbSMatt Jacob /* 14753cff3bbSMatt Jacob * Request/Response Queue defines and macros. 14853cff3bbSMatt Jacob * The maximum is defined per platform (and can be based on board type). 14953cff3bbSMatt Jacob */ 15053cff3bbSMatt Jacob /* This is the size of a queue entry (request and response) */ 1516054c3f6SMatt Jacob #define QENTRY_LEN 64 15253cff3bbSMatt Jacob /* Both request and result queue length must be a power of two */ 15353cff3bbSMatt Jacob #define RQUEST_QUEUE_LEN(x) MAXISPREQUEST(x) 1541923f739SMatt Jacob #ifdef ISP_TARGET_MODE 1551923f739SMatt Jacob #define RESULT_QUEUE_LEN(x) MAXISPREQUEST(x) 1561923f739SMatt Jacob #else 15753cff3bbSMatt Jacob #define RESULT_QUEUE_LEN(x) \ 15853cff3bbSMatt Jacob (((MAXISPREQUEST(x) >> 2) < 64)? 64 : MAXISPREQUEST(x) >> 2) 1591923f739SMatt Jacob #endif 1606054c3f6SMatt Jacob #define ISP_QUEUE_ENTRY(q, idx) ((q) + ((idx) * QENTRY_LEN)) 1616054c3f6SMatt Jacob #define ISP_QUEUE_SIZE(n) ((n) * QENTRY_LEN) 162478f8a96SJustin T. Gibbs #define ISP_NXT_QENTRY(idx, qlen) (((idx) + 1) & ((qlen)-1)) 163b6b6ad2fSMatt Jacob #define ISP_QFREE(in, out, qlen) \ 164478f8a96SJustin T. Gibbs ((in == out)? (qlen - 1) : ((in > out)? \ 165478f8a96SJustin T. Gibbs ((qlen - 1) - (in - out)) : (out - in - 1))) 166b6b6ad2fSMatt Jacob #define ISP_QAVAIL(isp) \ 167b6b6ad2fSMatt Jacob ISP_QFREE(isp->isp_reqidx, isp->isp_reqodx, RQUEST_QUEUE_LEN(isp)) 16880ae5655SMatt Jacob 1694fd13c1bSMatt Jacob #define ISP_ADD_REQUEST(isp, nxti) \ 1704fd13c1bSMatt Jacob MEMORYBARRIER(isp, SYNC_REQUEST, isp->isp_reqidx, QENTRY_LEN); \ 1714fd13c1bSMatt Jacob WRITE_REQUEST_QUEUE_IN_POINTER(isp, nxti); \ 1724fd13c1bSMatt Jacob isp->isp_reqidx = nxti 17380ae5655SMatt Jacob 1746054c3f6SMatt Jacob /* 1758259d081SMatt Jacob * SCSI Specific Host Adapter Parameters- per bus, per target 1766054c3f6SMatt Jacob */ 1776054c3f6SMatt Jacob 1786054c3f6SMatt Jacob typedef struct { 1798259d081SMatt Jacob u_int isp_gotdparms : 1, 1808259d081SMatt Jacob isp_req_ack_active_neg : 1, 1816054c3f6SMatt Jacob isp_data_line_active_neg: 1, 1826054c3f6SMatt Jacob isp_cmd_dma_burst_enable: 1, 1836054c3f6SMatt Jacob isp_data_dma_burst_enabl: 1, 184128101f3SMatt Jacob isp_fifo_threshold : 3, 185cbf57b47SMatt Jacob isp_ultramode : 1, 1866054c3f6SMatt Jacob isp_diffmode : 1, 1874394c92fSMatt Jacob isp_lvdmode : 1, 188b6b6ad2fSMatt Jacob isp_fast_mttr : 1, /* fast sram */ 1896054c3f6SMatt Jacob isp_initiator_id : 4, 1906054c3f6SMatt Jacob isp_async_data_setup : 4; 1916054c3f6SMatt Jacob u_int16_t isp_selection_timeout; 1926054c3f6SMatt Jacob u_int16_t isp_max_queue_depth; 1936054c3f6SMatt Jacob u_int8_t isp_tag_aging; 1946054c3f6SMatt Jacob u_int8_t isp_bus_reset_delay; 1956054c3f6SMatt Jacob u_int8_t isp_retry_count; 1966054c3f6SMatt Jacob u_int8_t isp_retry_delay; 1976054c3f6SMatt Jacob struct { 198d9c272f3SMatt Jacob u_int32_t 199d9c272f3SMatt Jacob exc_throttle : 8, 2008259d081SMatt Jacob : 1, 201d9c272f3SMatt Jacob dev_enable : 1, /* ignored */ 202cbf57b47SMatt Jacob dev_update : 1, 203cbf57b47SMatt Jacob dev_refresh : 1, 204d9c272f3SMatt Jacob actv_offset : 4, 205d9c272f3SMatt Jacob goal_offset : 4, 206d9c272f3SMatt Jacob nvrm_offset : 4; 207d9c272f3SMatt Jacob u_int8_t actv_period; /* current sync period */ 208d9c272f3SMatt Jacob u_int8_t goal_period; /* goal sync period */ 209d9c272f3SMatt Jacob u_int8_t nvrm_period; /* nvram sync period */ 210d9c272f3SMatt Jacob u_int16_t actv_flags; /* current device flags */ 211d9c272f3SMatt Jacob u_int16_t goal_flags; /* goal device flags */ 212d9c272f3SMatt Jacob u_int16_t nvrm_flags; /* nvram device flags */ 2136054c3f6SMatt Jacob } isp_devparam[MAX_TARGETS]; 2148259d081SMatt Jacob } sdparam; 2156054c3f6SMatt Jacob 2166054c3f6SMatt Jacob /* 2176054c3f6SMatt Jacob * Device Flags 2186054c3f6SMatt Jacob */ 219478f8a96SJustin T. Gibbs #define DPARM_DISC 0x8000 220478f8a96SJustin T. Gibbs #define DPARM_PARITY 0x4000 221478f8a96SJustin T. Gibbs #define DPARM_WIDE 0x2000 222478f8a96SJustin T. Gibbs #define DPARM_SYNC 0x1000 223478f8a96SJustin T. Gibbs #define DPARM_TQING 0x0800 224478f8a96SJustin T. Gibbs #define DPARM_ARQ 0x0400 225478f8a96SJustin T. Gibbs #define DPARM_QFRZ 0x0200 226478f8a96SJustin T. Gibbs #define DPARM_RENEG 0x0100 227b6b6ad2fSMatt Jacob #define DPARM_NARROW 0x0080 228b6b6ad2fSMatt Jacob #define DPARM_ASYNC 0x0040 229b6b6ad2fSMatt Jacob #define DPARM_PPR 0x0020 23010f20e40SMatt Jacob #define DPARM_DEFAULT (0xFF00 & ~DPARM_QFRZ) 231478f8a96SJustin T. Gibbs #define DPARM_SAFE_DFLT (DPARM_DEFAULT & ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING)) 232478f8a96SJustin T. Gibbs 2336054c3f6SMatt Jacob 2344394c92fSMatt Jacob /* technically, not really correct, as they need to be rated based upon clock */ 235b6b6ad2fSMatt Jacob #define ISP_80M_SYNCPARMS 0x0c09 236b6b6ad2fSMatt Jacob #define ISP_40M_SYNCPARMS 0x0c0a 237b6b6ad2fSMatt Jacob #define ISP_20M_SYNCPARMS 0x0c0c 238b6b6ad2fSMatt Jacob #define ISP_20M_SYNCPARMS_1040 0x080c 2396054c3f6SMatt Jacob #define ISP_10M_SYNCPARMS 0x0c19 2406054c3f6SMatt Jacob #define ISP_08M_SYNCPARMS 0x0c25 2416054c3f6SMatt Jacob #define ISP_05M_SYNCPARMS 0x0c32 2426054c3f6SMatt Jacob #define ISP_04M_SYNCPARMS 0x0c41 2436054c3f6SMatt Jacob 2446054c3f6SMatt Jacob /* 2456054c3f6SMatt Jacob * Fibre Channel Specifics 2466054c3f6SMatt Jacob */ 2477e90346eSMatt Jacob #define FL_PORT_ID 0x7e /* FL_Port Special ID */ 2487e90346eSMatt Jacob #define FC_PORT_ID 0x7f /* Fabric Controller Special ID */ 2497e90346eSMatt Jacob #define FC_SNS_ID 0x80 /* SNS Server Special ID */ 2507e90346eSMatt Jacob 251029f13c6SMatt Jacob /* #define ISP_USE_GA_NXT 1 */ /* Use GA_NXT with switches */ 252029f13c6SMatt Jacob #ifndef GA_NXT_MAX 253029f13c6SMatt Jacob #define GA_NXT_MAX 256 254029f13c6SMatt Jacob #endif 255029f13c6SMatt Jacob 2566054c3f6SMatt Jacob typedef struct { 2577e90346eSMatt Jacob u_int32_t isp_fwoptions : 16, 258c507669aSMatt Jacob isp_gbspeed : 2, 259410b5567SMatt Jacob isp_iid_set : 1, 26077d4e836SMatt Jacob loop_seen_once : 1, 2616a23026cSMatt Jacob isp_loopstate : 4, /* Current Loop State */ 26277d4e836SMatt Jacob isp_fwstate : 3, /* ISP F/W state */ 26377d4e836SMatt Jacob isp_gotdparms : 1, 264d465588aSMatt Jacob isp_topo : 3, 26577d4e836SMatt Jacob isp_onfabric : 1; 266410b5567SMatt Jacob u_int8_t isp_iid; /* 'initiator' id */ 267478f8a96SJustin T. Gibbs u_int8_t isp_loopid; /* hard loop id */ 268478f8a96SJustin T. Gibbs u_int8_t isp_alpa; /* ALPA */ 26977d4e836SMatt Jacob u_int32_t isp_portid; 270410b5567SMatt Jacob volatile u_int16_t isp_lipseq; /* LIP sequence # */ 271f8597b62SMatt Jacob u_int16_t isp_fwattr; /* firmware attributes */ 272478f8a96SJustin T. Gibbs u_int8_t isp_execthrottle; 2736054c3f6SMatt Jacob u_int8_t isp_retry_delay; 274478f8a96SJustin T. Gibbs u_int8_t isp_retry_count; 2757e90346eSMatt Jacob u_int8_t isp_reserved; 276478f8a96SJustin T. Gibbs u_int16_t isp_maxalloc; 277478f8a96SJustin T. Gibbs u_int16_t isp_maxfrmlen; 27877d4e836SMatt Jacob u_int64_t isp_nodewwn; 27977d4e836SMatt Jacob u_int64_t isp_portwwn; 2806054c3f6SMatt Jacob /* 28177d4e836SMatt Jacob * Port Data Base. This is indexed by 'target', which is invariate. 28277d4e836SMatt Jacob * However, elements within can move around due to loop changes, 28377d4e836SMatt Jacob * so the actual loop ID passed to the F/W is in this structure. 28477d4e836SMatt Jacob * The first time the loop is seen up, loopid will match the index 28577d4e836SMatt Jacob * (except for fabric nodes which are above mapped above FC_SNS_ID 28677d4e836SMatt Jacob * and are completely virtual), but subsequent LIPs can cause things 28777d4e836SMatt Jacob * to move around. 28857c801f5SMatt Jacob */ 28977d4e836SMatt Jacob struct lportdb { 290029f13c6SMatt Jacob u_int32_t 291029f13c6SMatt Jacob port_type : 8, 29277d4e836SMatt Jacob loopid : 8, 2930499ae00SMatt Jacob fc4_type : 4, 294029f13c6SMatt Jacob last_fabric_dev : 1, 2950499ae00SMatt Jacob : 2, 2960499ae00SMatt Jacob relogin : 1, 2976a23026cSMatt Jacob force_logout : 1, 2987afb656fSMatt Jacob was_fabric_dev : 1, 2997afb656fSMatt Jacob fabric_dev : 1, 300686f419dSMatt Jacob loggedin : 1, 30177d4e836SMatt Jacob roles : 2, 30277d4e836SMatt Jacob valid : 1; 30377d4e836SMatt Jacob u_int32_t portid; 30477d4e836SMatt Jacob u_int64_t node_wwn; 30577d4e836SMatt Jacob u_int64_t port_wwn; 306410b5567SMatt Jacob } portdb[MAX_FC_TARG], tport[FC_PORT_ID]; 30757c801f5SMatt Jacob 30857c801f5SMatt Jacob /* 3096054c3f6SMatt Jacob * Scratch DMA mapped in area to fetch Port Database stuff, etc. 3106054c3f6SMatt Jacob */ 31167eb6231SMatt Jacob caddr_t isp_scratch; 31266cbe912SMatt Jacob isp_dma_addr_t isp_scdma; 31301ff579dSMatt Jacob #ifdef ISP_FW_CRASH_DUMP 31401ff579dSMatt Jacob u_int16_t *isp_dump_data; 31501ff579dSMatt Jacob #endif 3166054c3f6SMatt Jacob } fcparam; 3176054c3f6SMatt Jacob 31877d4e836SMatt Jacob #define FW_CONFIG_WAIT 0 31977d4e836SMatt Jacob #define FW_WAIT_AL_PA 1 32077d4e836SMatt Jacob #define FW_WAIT_LOGIN 2 32177d4e836SMatt Jacob #define FW_READY 3 32277d4e836SMatt Jacob #define FW_LOSS_OF_SYNC 4 32377d4e836SMatt Jacob #define FW_ERROR 5 32477d4e836SMatt Jacob #define FW_REINIT 6 32577d4e836SMatt Jacob #define FW_NON_PART 7 3266054c3f6SMatt Jacob 32777d4e836SMatt Jacob #define LOOP_NIL 0 32877d4e836SMatt Jacob #define LOOP_LIP_RCVD 1 32977d4e836SMatt Jacob #define LOOP_PDB_RCVD 2 330410b5567SMatt Jacob #define LOOP_SCANNING_FABRIC 3 331410b5567SMatt Jacob #define LOOP_FSCAN_DONE 4 332410b5567SMatt Jacob #define LOOP_SCANNING_LOOP 5 3336a23026cSMatt Jacob #define LOOP_LSCAN_DONE 6 3346a23026cSMatt Jacob #define LOOP_SYNCING_PDB 7 3356a23026cSMatt Jacob #define LOOP_READY 8 33677d4e836SMatt Jacob 337d465588aSMatt Jacob #define TOPO_NL_PORT 0 338d465588aSMatt Jacob #define TOPO_FL_PORT 1 339d465588aSMatt Jacob #define TOPO_N_PORT 2 340d465588aSMatt Jacob #define TOPO_F_PORT 3 341d465588aSMatt Jacob #define TOPO_PTP_STUB 4 342d465588aSMatt Jacob 3436054c3f6SMatt Jacob /* 3446054c3f6SMatt Jacob * Soft Structure per host adapter 3456054c3f6SMatt Jacob */ 346b6b6ad2fSMatt Jacob typedef struct ispsoftc { 3476054c3f6SMatt Jacob /* 3486054c3f6SMatt Jacob * Platform (OS) specific data 3496054c3f6SMatt Jacob */ 3506054c3f6SMatt Jacob struct isposinfo isp_osinfo; 3516054c3f6SMatt Jacob 3526054c3f6SMatt Jacob /* 35380ae5655SMatt Jacob * Pointer to bus specific functions and data 3546054c3f6SMatt Jacob */ 3556054c3f6SMatt Jacob struct ispmdvec * isp_mdvec; 3566054c3f6SMatt Jacob 3576054c3f6SMatt Jacob /* 35880ae5655SMatt Jacob * (Mostly) nonvolatile state. Board specific parameters 35980ae5655SMatt Jacob * may contain some volatile state (e.g., current loop state). 3606054c3f6SMatt Jacob */ 3616054c3f6SMatt Jacob 36280ae5655SMatt Jacob void * isp_param; /* type specific */ 36380ae5655SMatt Jacob u_int16_t isp_fwrev[3]; /* Loaded F/W revision */ 36480ae5655SMatt Jacob u_int16_t isp_romfw_rev[3]; /* PROM F/W revision */ 36580ae5655SMatt Jacob u_int16_t isp_maxcmds; /* max possible I/O cmds */ 36680ae5655SMatt Jacob u_int8_t isp_type; /* HBA Chip Type */ 36780ae5655SMatt Jacob u_int8_t isp_revision; /* HBA Chip H/W Revision */ 3685e09512cSMatt Jacob u_int32_t isp_maxluns; /* maximum luns supported */ 3696054c3f6SMatt Jacob 3707afb656fSMatt Jacob u_int32_t isp_clock : 8, /* input clock */ 37175c1e828SMatt Jacob : 4, 37275c1e828SMatt Jacob isp_port : 1, /* 23XX only */ 3734fd13c1bSMatt Jacob isp_failed : 1, /* board failed */ 3744fd13c1bSMatt Jacob isp_open : 1, /* opened (ioctl) */ 3757afb656fSMatt Jacob isp_touched : 1, /* board ever seen? */ 376b6b6ad2fSMatt Jacob isp_bustype : 1, /* SBus or PCI */ 377b6b6ad2fSMatt Jacob isp_loaded_fw : 1, /* loaded firmware */ 3784fd13c1bSMatt Jacob isp_role : 2, /* roles supported */ 3797afb656fSMatt Jacob isp_dblev : 12; /* debug log mask */ 3807afb656fSMatt Jacob 3817afb656fSMatt Jacob u_int32_t isp_confopts; /* config options */ 3827afb656fSMatt Jacob 383126ec864SMatt Jacob u_int16_t isp_rqstinrp; /* register for REQINP */ 384126ec864SMatt Jacob u_int16_t isp_rqstoutrp; /* register for REQOUTP */ 385126ec864SMatt Jacob u_int16_t isp_respinrp; /* register for RESINP */ 386126ec864SMatt Jacob u_int16_t isp_respoutrp; /* register for RESOUTP */ 387126ec864SMatt Jacob 38867afe757SMatt Jacob /* 38967afe757SMatt Jacob * Instrumentation 39067afe757SMatt Jacob */ 39167afe757SMatt Jacob u_int64_t isp_intcnt; /* total int count */ 39267afe757SMatt Jacob u_int64_t isp_intbogus; /* spurious int count */ 3932903b272SMatt Jacob u_int64_t isp_intmboxc; /* mbox completions */ 3942903b272SMatt Jacob u_int64_t isp_intoasync; /* other async */ 3952903b272SMatt Jacob u_int64_t isp_rsltccmplt; /* CMDs on result q */ 3962903b272SMatt Jacob u_int64_t isp_fphccmplt; /* CMDs via fastpost */ 3972903b272SMatt Jacob u_int16_t isp_rscchiwater; 3982903b272SMatt Jacob u_int16_t isp_fpcchiwater; 3996054c3f6SMatt Jacob 4006054c3f6SMatt Jacob /* 401478f8a96SJustin T. Gibbs * Volatile state 4026054c3f6SMatt Jacob */ 403478f8a96SJustin T. Gibbs 404e2adf86eSMatt Jacob volatile u_int32_t 4054fd13c1bSMatt Jacob isp_obits : 8, /* mailbox command output */ 4064fd13c1bSMatt Jacob isp_mboxbsy : 1, /* mailbox command active */ 407478f8a96SJustin T. Gibbs isp_state : 3, 4088259d081SMatt Jacob isp_sendmarker : 2, /* send a marker entry */ 4098259d081SMatt Jacob isp_update : 2, /* update parameters */ 4107e90346eSMatt Jacob isp_nactive : 16; /* how many commands active */ 4117e90346eSMatt Jacob volatile u_int16_t isp_reqodx; /* index of last ISP pickup */ 4127e90346eSMatt Jacob volatile u_int16_t isp_reqidx; /* index of next request */ 4137e90346eSMatt Jacob volatile u_int16_t isp_residx; /* index of next result */ 414371777b1SMatt Jacob volatile u_int16_t isp_resodx; /* index of next result */ 415371777b1SMatt Jacob volatile u_int16_t isp_rspbsy; 4167e90346eSMatt Jacob volatile u_int16_t isp_lasthdls; /* last handle seed */ 417e2adf86eSMatt Jacob volatile u_int16_t isp_mboxtmp[MAX_MAILBOX]; 4187afb656fSMatt Jacob volatile u_int16_t isp_lastmbxcmd; /* last mbox command sent */ 41975c1e828SMatt Jacob volatile u_int16_t isp_mbxwrk0; 42075c1e828SMatt Jacob volatile u_int16_t isp_mbxwrk1; 42175c1e828SMatt Jacob volatile u_int16_t isp_mbxwrk2; 42275c1e828SMatt Jacob void * isp_mbxworkp; 423478f8a96SJustin T. Gibbs 424478f8a96SJustin T. Gibbs /* 42580ae5655SMatt Jacob * Active commands are stored here, indexed by handle functions. 426478f8a96SJustin T. Gibbs */ 42753cff3bbSMatt Jacob XS_T **isp_xflist; 4286054c3f6SMatt Jacob 4296054c3f6SMatt Jacob /* 4304b39f27dSMatt Jacob * request/result queue pointers and DMA handles for them. 4316054c3f6SMatt Jacob */ 43267eb6231SMatt Jacob caddr_t isp_rquest; 43367eb6231SMatt Jacob caddr_t isp_result; 43466cbe912SMatt Jacob isp_dma_addr_t isp_rquest_dma; 43566cbe912SMatt Jacob isp_dma_addr_t isp_result_dma; 436b6b6ad2fSMatt Jacob } ispsoftc_t; 4376054c3f6SMatt Jacob 4380f747d72SMatt Jacob #define SDPARAM(isp) ((sdparam *) (isp)->isp_param) 4390f747d72SMatt Jacob #define FCPARAM(isp) ((fcparam *) (isp)->isp_param) 4400f747d72SMatt Jacob 4416054c3f6SMatt Jacob /* 44253cff3bbSMatt Jacob * ISP Driver Run States 4436054c3f6SMatt Jacob */ 4446054c3f6SMatt Jacob #define ISP_NILSTATE 0 4456054c3f6SMatt Jacob #define ISP_RESETSTATE 1 4466054c3f6SMatt Jacob #define ISP_INITSTATE 2 4476054c3f6SMatt Jacob #define ISP_RUNSTATE 3 4486054c3f6SMatt Jacob 4496054c3f6SMatt Jacob /* 4506054c3f6SMatt Jacob * ISP Configuration Options 4516054c3f6SMatt Jacob */ 4526054c3f6SMatt Jacob #define ISP_CFG_NORELOAD 0x80 /* don't download f/w */ 45310f20e40SMatt Jacob #define ISP_CFG_NONVRAM 0x40 /* ignore NVRAM */ 454c507669aSMatt Jacob #define ISP_CFG_TWOGB 0x20 /* force 2GB connection (23XX only) */ 455c507669aSMatt Jacob #define ISP_CFG_ONEGB 0x10 /* force 1GB connection (23XX only) */ 45680ae5655SMatt Jacob #define ISP_CFG_FULL_DUPLEX 0x01 /* Full Duplex (Fibre Channel only) */ 45767afe757SMatt Jacob #define ISP_CFG_PORT_PREF 0x0C /* Mask for Port Prefs (2200 only) */ 45867afe757SMatt Jacob #define ISP_CFG_LPORT 0x00 /* prefer {N/F}L-Port connection */ 45967afe757SMatt Jacob #define ISP_CFG_NPORT 0x04 /* prefer {N/F}-Port connection */ 46067afe757SMatt Jacob #define ISP_CFG_NPORT_ONLY 0x08 /* insist on {N/F}-Port connection */ 46167afe757SMatt Jacob #define ISP_CFG_LPORT_ONLY 0x0C /* insist on {N/F}L-Port connection */ 46201ff579dSMatt Jacob #define ISP_CFG_OWNWWPN 0x100 /* override NVRAM wwpn */ 46301ff579dSMatt Jacob #define ISP_CFG_OWNWWNN 0x200 /* override NVRAM wwnn */ 4640499ae00SMatt Jacob #define ISP_CFG_OWNFSZ 0x400 /* override NVRAM frame size */ 4650499ae00SMatt Jacob #define ISP_CFG_OWNLOOPID 0x800 /* override NVRAM loopid */ 4660499ae00SMatt Jacob #define ISP_CFG_OWNEXCTHROTTLE 0x1000 /* override NVRAM execution throttle */ 4676054c3f6SMatt Jacob 46853cff3bbSMatt Jacob /* 4697afb656fSMatt Jacob * Prior to calling isp_reset for the first time, the outer layer 4707afb656fSMatt Jacob * should set isp_role to one of NONE, INITIATOR, TARGET, BOTH. 4717afb656fSMatt Jacob * 4727afb656fSMatt Jacob * If you set ISP_ROLE_NONE, the cards will be reset, new firmware loaded, 4737afb656fSMatt Jacob * NVRAM read, and defaults set, but any further initialization (e.g. 4747afb656fSMatt Jacob * INITIALIZE CONTROL BLOCK commands for 2X00 cards) won't be done. 4757afb656fSMatt Jacob * 4767afb656fSMatt Jacob * If INITIATOR MODE isn't set, attempts to run commands will be stopped 4777afb656fSMatt Jacob * at isp_start and completed with the moral equivalent of SELECTION TIMEOUT. 4787afb656fSMatt Jacob * 4797afb656fSMatt Jacob * If TARGET MODE is set, it doesn't mean that the rest of target mode support 4807afb656fSMatt Jacob * needs to be enabled, or will even work. What happens with the 2X00 cards 4817afb656fSMatt Jacob * here is that if you have enabled it with TARGET MODE as part of the ICB 4827afb656fSMatt Jacob * options, but you haven't given the f/w any ram resources for ATIOs or 4837afb656fSMatt Jacob * Immediate Notifies, the f/w just handles what it can and you never see 4847afb656fSMatt Jacob * anything. Basically, it sends a single byte of data (the first byte, 4857afb656fSMatt Jacob * which you can set as part of the INITIALIZE CONTROL BLOCK command) for 4867afb656fSMatt Jacob * INQUIRY, and sends back QUEUE FULL status for any other command. 4877afb656fSMatt Jacob * 4887afb656fSMatt Jacob */ 4897afb656fSMatt Jacob #define ISP_ROLE_NONE 0x0 490e0d3cfb7SMatt Jacob #define ISP_ROLE_TARGET 0x1 491e0d3cfb7SMatt Jacob #define ISP_ROLE_INITIATOR 0x2 4927afb656fSMatt Jacob #define ISP_ROLE_BOTH (ISP_ROLE_TARGET|ISP_ROLE_INITIATOR) 4937afb656fSMatt Jacob #define ISP_ROLE_EITHER ISP_ROLE_BOTH 4947afb656fSMatt Jacob #ifndef ISP_DEFAULT_ROLES 4957afb656fSMatt Jacob #define ISP_DEFAULT_ROLES ISP_ROLE_INITIATOR 4967afb656fSMatt Jacob #endif 4977afb656fSMatt Jacob 4987afb656fSMatt Jacob 4997afb656fSMatt Jacob /* 50053cff3bbSMatt Jacob * Firmware related defines 50153cff3bbSMatt Jacob */ 50253cff3bbSMatt Jacob #define ISP_CODE_ORG 0x1000 /* default f/w code start */ 503126ec864SMatt Jacob #define ISP_CODE_ORG_2300 0x0800 /* ..except for 2300s */ 50412b36e2dSMatt Jacob #define ISP_FW_REV(maj, min, mic) ((maj << 24) | (min << 16) | mic) 505f8597b62SMatt Jacob #define ISP_FW_MAJOR(code) ((code >> 24) & 0xff) 506f8597b62SMatt Jacob #define ISP_FW_MINOR(code) ((code >> 16) & 0xff) 507f8597b62SMatt Jacob #define ISP_FW_MICRO(code) ((code >> 8) & 0xff) 50812b36e2dSMatt Jacob #define ISP_FW_REVX(xp) ((xp[0]<<24) | (xp[1] << 16) | xp[2]) 509f8597b62SMatt Jacob #define ISP_FW_MAJORX(xp) (xp[0]) 510f8597b62SMatt Jacob #define ISP_FW_MINORX(xp) (xp[1]) 511f8597b62SMatt Jacob #define ISP_FW_MICROX(xp) (xp[2]) 512e347e2c9SMatt Jacob #define ISP_FW_NEWER_THAN(i, major, minor, micro) \ 513e347e2c9SMatt Jacob (ISP_FW_REVX((i)->isp_fwrev) > ISP_FW_REV(major, minor, micro)) 51412b36e2dSMatt Jacob 5156054c3f6SMatt Jacob /* 516478f8a96SJustin T. Gibbs * Bus (implementation) types 517478f8a96SJustin T. Gibbs */ 518478f8a96SJustin T. Gibbs #define ISP_BT_PCI 0 /* PCI Implementations */ 519478f8a96SJustin T. Gibbs #define ISP_BT_SBUS 1 /* SBus Implementations */ 520478f8a96SJustin T. Gibbs 521478f8a96SJustin T. Gibbs /* 5224fd13c1bSMatt Jacob * If we have not otherwise defined SBus support away make sure 5234fd13c1bSMatt Jacob * it is defined here such that the code is included as default 5244fd13c1bSMatt Jacob */ 5254fd13c1bSMatt Jacob #ifndef ISP_SBUS_SUPPORTED 5264fd13c1bSMatt Jacob #define ISP_SBUS_SUPPORTED 1 5274fd13c1bSMatt Jacob #endif 5284fd13c1bSMatt Jacob 5294fd13c1bSMatt Jacob /* 530478f8a96SJustin T. Gibbs * Chip Types 5316054c3f6SMatt Jacob */ 5326054c3f6SMatt Jacob #define ISP_HA_SCSI 0xf 533478f8a96SJustin T. Gibbs #define ISP_HA_SCSI_UNKNOWN 0x1 534478f8a96SJustin T. Gibbs #define ISP_HA_SCSI_1020 0x2 535478f8a96SJustin T. Gibbs #define ISP_HA_SCSI_1020A 0x3 536478f8a96SJustin T. Gibbs #define ISP_HA_SCSI_1040 0x4 537478f8a96SJustin T. Gibbs #define ISP_HA_SCSI_1040A 0x5 538478f8a96SJustin T. Gibbs #define ISP_HA_SCSI_1040B 0x6 53912b36e2dSMatt Jacob #define ISP_HA_SCSI_1040C 0x7 54022e1dc85SMatt Jacob #define ISP_HA_SCSI_1240 0x8 54122e1dc85SMatt Jacob #define ISP_HA_SCSI_1080 0x9 54222e1dc85SMatt Jacob #define ISP_HA_SCSI_1280 0xa 543f556e83bSMatt Jacob #define ISP_HA_SCSI_10160 0xb 544f556e83bSMatt Jacob #define ISP_HA_SCSI_12160 0xc 5456054c3f6SMatt Jacob #define ISP_HA_FC 0xf0 5466054c3f6SMatt Jacob #define ISP_HA_FC_2100 0x10 54777d4e836SMatt Jacob #define ISP_HA_FC_2200 0x20 5485d571944SMatt Jacob #define ISP_HA_FC_2300 0x30 5492903b272SMatt Jacob #define ISP_HA_FC_2312 0x40 5506054c3f6SMatt Jacob 55157c801f5SMatt Jacob #define IS_SCSI(isp) (isp->isp_type & ISP_HA_SCSI) 55222e1dc85SMatt Jacob #define IS_1240(isp) (isp->isp_type == ISP_HA_SCSI_1240) 55357c801f5SMatt Jacob #define IS_1080(isp) (isp->isp_type == ISP_HA_SCSI_1080) 55422e1dc85SMatt Jacob #define IS_1280(isp) (isp->isp_type == ISP_HA_SCSI_1280) 555f556e83bSMatt Jacob #define IS_10160(isp) (isp->isp_type == ISP_HA_SCSI_10160) 55683fbc566SMatt Jacob #define IS_12160(isp) (isp->isp_type == ISP_HA_SCSI_12160) 55783fbc566SMatt Jacob 55883fbc566SMatt Jacob #define IS_12X0(isp) (IS_1240(isp) || IS_1280(isp)) 559f556e83bSMatt Jacob #define IS_1X160(isp) (IS_10160(isp) || IS_12160(isp)) 56083fbc566SMatt Jacob #define IS_DUALBUS(isp) (IS_12X0(isp) || IS_12160(isp)) 561f556e83bSMatt Jacob #define IS_ULTRA2(isp) (IS_1080(isp) || IS_1280(isp) || IS_1X160(isp)) 562f556e83bSMatt Jacob #define IS_ULTRA3(isp) (IS_1X160(isp)) 56383fbc566SMatt Jacob 5645d571944SMatt Jacob #define IS_FC(isp) ((isp)->isp_type & ISP_HA_FC) 5655d571944SMatt Jacob #define IS_2100(isp) ((isp)->isp_type == ISP_HA_FC_2100) 5665d571944SMatt Jacob #define IS_2200(isp) ((isp)->isp_type == ISP_HA_FC_2200) 5672903b272SMatt Jacob #define IS_23XX(isp) ((isp)->isp_type >= ISP_HA_FC_2300) 5682903b272SMatt Jacob #define IS_2300(isp) ((isp)->isp_type == ISP_HA_FC_2300) 5692903b272SMatt Jacob #define IS_2312(isp) ((isp)->isp_type == ISP_HA_FC_2312) 57083fbc566SMatt Jacob 57153cff3bbSMatt Jacob /* 57253cff3bbSMatt Jacob * DMA cookie macros 57353cff3bbSMatt Jacob */ 57466cbe912SMatt Jacob #ifdef ISP_DAC_SUPPORTRED 57566cbe912SMatt Jacob #define DMA_WD3(x) (((x) >> 48) & 0xffff) 57666cbe912SMatt Jacob #define DMA_WD2(x) (((x) >> 32) & 0xffff) 57766cbe912SMatt Jacob #else 578126ec864SMatt Jacob #define DMA_WD3(x) 0 579126ec864SMatt Jacob #define DMA_WD2(x) 0 58066cbe912SMatt Jacob #endif 581126ec864SMatt Jacob #define DMA_WD1(x) (((x) >> 16) & 0xffff) 582126ec864SMatt Jacob #define DMA_WD0(x) (((x) & 0xffff)) 58357c801f5SMatt Jacob 5846054c3f6SMatt Jacob /* 58553cff3bbSMatt Jacob * Core System Function Prototypes 5866054c3f6SMatt Jacob */ 5876054c3f6SMatt Jacob 5886054c3f6SMatt Jacob /* 589478f8a96SJustin T. Gibbs * Reset Hardware. Totally. Assumes that you'll follow this with 590478f8a96SJustin T. Gibbs * a call to isp_init. 5916054c3f6SMatt Jacob */ 592e2ec5cf0SMatt Jacob void isp_reset(struct ispsoftc *); 5936054c3f6SMatt Jacob 5946054c3f6SMatt Jacob /* 5956054c3f6SMatt Jacob * Initialize Hardware to known state 5966054c3f6SMatt Jacob */ 597e2ec5cf0SMatt Jacob void isp_init(struct ispsoftc *); 5986054c3f6SMatt Jacob 5996054c3f6SMatt Jacob /* 600478f8a96SJustin T. Gibbs * Reset the ISP and call completion for any orphaned commands. 601478f8a96SJustin T. Gibbs */ 602e2ec5cf0SMatt Jacob void isp_reinit(struct ispsoftc *); 603478f8a96SJustin T. Gibbs 60401ff579dSMatt Jacob #ifdef ISP_FW_CRASH_DUMP 60501ff579dSMatt Jacob /* 60601ff579dSMatt Jacob * Dump firmware entry point. 60701ff579dSMatt Jacob */ 60801ff579dSMatt Jacob void isp_fw_dump(struct ispsoftc *isp); 60901ff579dSMatt Jacob #endif 61001ff579dSMatt Jacob 611478f8a96SJustin T. Gibbs /* 612126ec864SMatt Jacob * Internal Interrupt Service Routine 613126ec864SMatt Jacob * 614126ec864SMatt Jacob * The outer layers do the spade work to get the appropriate status register, 615126ec864SMatt Jacob * semaphore register and first mailbox register (if appropriate). This also 616126ec864SMatt Jacob * means that most spurious/bogus interrupts not for us can be filtered first. 6176054c3f6SMatt Jacob */ 618126ec864SMatt Jacob void isp_intr(struct ispsoftc *, u_int16_t, u_int16_t, u_int16_t); 619126ec864SMatt Jacob 6206054c3f6SMatt Jacob 6216054c3f6SMatt Jacob /* 62253cff3bbSMatt Jacob * Command Entry Point- Platform Dependent layers call into this 6236054c3f6SMatt Jacob */ 624e2ec5cf0SMatt Jacob int isp_start(XS_T *); 62553cff3bbSMatt Jacob /* these values are what isp_start returns */ 62653cff3bbSMatt Jacob #define CMD_COMPLETE 101 /* command completed */ 62753cff3bbSMatt Jacob #define CMD_EAGAIN 102 /* busy- maybe retry later */ 62853cff3bbSMatt Jacob #define CMD_QUEUED 103 /* command has been queued for execution */ 62953cff3bbSMatt Jacob #define CMD_RQLATER 104 /* requeue this command later */ 63053cff3bbSMatt Jacob 63153cff3bbSMatt Jacob /* 63253cff3bbSMatt Jacob * Command Completion Point- Core layers call out from this with completed cmds 63353cff3bbSMatt Jacob */ 634e2ec5cf0SMatt Jacob void isp_done(XS_T *); 635478f8a96SJustin T. Gibbs 636478f8a96SJustin T. Gibbs /* 637cbf57b47SMatt Jacob * Platform Dependent to External to Internal Control Function 638478f8a96SJustin T. Gibbs * 639410b5567SMatt Jacob * Assumes locks are held on entry. You should note that with many of 640410b5567SMatt Jacob * these commands and locks may be released while this is occurring. 641478f8a96SJustin T. Gibbs * 642410b5567SMatt Jacob * A few notes about some of these functions: 643410b5567SMatt Jacob * 644410b5567SMatt Jacob * ISPCTL_FCLINK_TEST tests to make sure we have good fibre channel link. 645410b5567SMatt Jacob * The argument is a pointer to an integer which is the time, in microseconds, 646410b5567SMatt Jacob * we should wait to see whether we have good link. This test, if successful, 647410b5567SMatt Jacob * lets us know our connection topology and our Loop ID/AL_PA and so on. 648410b5567SMatt Jacob * You can't get anywhere without this. 649410b5567SMatt Jacob * 650410b5567SMatt Jacob * ISPCTL_SCAN_FABRIC queries the name server (if we're on a fabric) for 651410b5567SMatt Jacob * all entities using the FC Generic Services subcommand GET ALL NEXT. 652410b5567SMatt Jacob * For each found entity, an ISPASYNC_FABRICDEV event is generated (see 653410b5567SMatt Jacob * below). 654410b5567SMatt Jacob * 655410b5567SMatt Jacob * ISPCTL_SCAN_LOOP does a local loop scan. This is only done if the connection 656410b5567SMatt Jacob * topology is NL or FL port (private or public loop). Since the Qlogic f/w 657410b5567SMatt Jacob * 'automatically' manages local loop connections, this function essentially 658410b5567SMatt Jacob * notes the arrival, departure, and possible shuffling around of local loop 659410b5567SMatt Jacob * entities. Thus for each arrival and departure this generates an isp_async 660410b5567SMatt Jacob * event of ISPASYNC_PROMENADE (see below). 661410b5567SMatt Jacob * 662410b5567SMatt Jacob * ISPCTL_PDB_SYNC is somewhat misnamed. It actually is the final step, in 663410b5567SMatt Jacob * order, of ISPCTL_FCLINK_TEST, ISPCTL_SCAN_FABRIC, and ISPCTL_SCAN_LOOP. 664410b5567SMatt Jacob * The main purpose of ISPCTL_PDB_SYNC is to complete management of logging 665410b5567SMatt Jacob * and logging out of fabric devices (if one is on a fabric) and then marking 666410b5567SMatt Jacob * the 'loop state' as being ready to now be used for sending commands to 667410b5567SMatt Jacob * devices. Originally fabric name server and local loop scanning were 668561e7bb9SMatt Jacob * part of this function. It's now been separated to allow for finer control. 669478f8a96SJustin T. Gibbs */ 670478f8a96SJustin T. Gibbs typedef enum { 67177d4e836SMatt Jacob ISPCTL_RESET_BUS, /* Reset Bus */ 67277d4e836SMatt Jacob ISPCTL_RESET_DEV, /* Reset Device */ 67377d4e836SMatt Jacob ISPCTL_ABORT_CMD, /* Abort Command */ 674410b5567SMatt Jacob ISPCTL_UPDATE_PARAMS, /* Update Operating Parameters (SCSI) */ 67541593b25SMatt Jacob ISPCTL_FCLINK_TEST, /* Test FC Link Status */ 676410b5567SMatt Jacob ISPCTL_SCAN_FABRIC, /* (Re)scan Fabric Name Server */ 677410b5567SMatt Jacob ISPCTL_SCAN_LOOP, /* (Re)scan Local Loop */ 67841593b25SMatt Jacob ISPCTL_PDB_SYNC, /* Synchronize Port Database */ 679410b5567SMatt Jacob ISPCTL_SEND_LIP, /* Send a LIP */ 680410b5567SMatt Jacob ISPCTL_GET_POSMAP, /* Get FC-AL position map */ 6814102f2f6SMatt Jacob ISPCTL_RUN_MBOXCMD, /* run a mailbox command */ 682e0d3cfb7SMatt Jacob ISPCTL_TOGGLE_TMODE, /* toggle target mode */ 683e0d3cfb7SMatt Jacob ISPCTL_GET_PDB /* get a single port database entry */ 684478f8a96SJustin T. Gibbs } ispctl_t; 685e2ec5cf0SMatt Jacob int isp_control(struct ispsoftc *, ispctl_t, void *); 686478f8a96SJustin T. Gibbs 687cbf57b47SMatt Jacob 688cbf57b47SMatt Jacob /* 689cbf57b47SMatt Jacob * Platform Dependent to Internal to External Control Function 690cbf57b47SMatt Jacob * (each platform must provide such a function) 691cbf57b47SMatt Jacob * 692410b5567SMatt Jacob * Assumes locks are held. 693410b5567SMatt Jacob * 694410b5567SMatt Jacob * A few notes about some of these functions: 695410b5567SMatt Jacob * 696410b5567SMatt Jacob * ISPASYNC_CHANGE_NOTIFY notifies the outer layer that a change has 697410b5567SMatt Jacob * occurred that invalidates the list of fabric devices known and/or 698410b5567SMatt Jacob * the list of known loop devices. The argument passed is a pointer 699410b5567SMatt Jacob * whose values are defined below (local loop change, name server 700410b5567SMatt Jacob * change, other). 'Other' may simply be a LIP, or a change in 701410b5567SMatt Jacob * connection topology. 702410b5567SMatt Jacob * 703410b5567SMatt Jacob * ISPASYNC_FABRIC_DEV announces the next element in a list of 704410b5567SMatt Jacob * fabric device names we're getting out of the name server. The 705410b5567SMatt Jacob * argument points to a GET ALL NEXT response structure. The list 706410b5567SMatt Jacob * is known to terminate with an entry that refers to ourselves. 707410b5567SMatt Jacob * One of the main purposes of this function is to allow outer 708410b5567SMatt Jacob * layers, which are OS dependent, to set policy as to which fabric 709410b5567SMatt Jacob * devices might actually be logged into (and made visible) later 710410b5567SMatt Jacob * at ISPCTL_PDB_SYNC time. Since there's a finite number of fabric 711410b5567SMatt Jacob * devices that we can log into (256 less 3 'reserved' for F-port 712410b5567SMatt Jacob * topologies), and fabrics can grow up to 8 million or so entries 713410b5567SMatt Jacob * (24 bits of Port Address, less a wad of reserved spaces), clearly 714410b5567SMatt Jacob * we had better let the OS determine login policy. 715410b5567SMatt Jacob * 716410b5567SMatt Jacob * ISPASYNC_PROMENADE has an argument that is a pointer to an integer which 71766cbe912SMatt Jacob * is an index into the portdb in the softc ('target'). Whether that entry's 718410b5567SMatt Jacob * valid tag is set or not says whether something has arrived or departed. 719410b5567SMatt Jacob * The name refers to a favorite pastime of many city dwellers- watching 720410b5567SMatt Jacob * people come and go, talking of Michaelangelo, and so on.. 7214102f2f6SMatt Jacob * 7224102f2f6SMatt Jacob * ISPASYNC_UNHANDLED_RESPONSE gives outer layers a chance to parse a 7234102f2f6SMatt Jacob * response queue entry not otherwise handled. The outer layer should 7244fd13c1bSMatt Jacob * return non-zero if it handled it. The 'arg' points to an unmassaged 7254fd13c1bSMatt Jacob * response queue entry. 726cbf57b47SMatt Jacob */ 727cbf57b47SMatt Jacob 728cbf57b47SMatt Jacob typedef enum { 729410b5567SMatt Jacob ISPASYNC_NEW_TGT_PARAMS, /* New Target Parameters Negotiated */ 73077d4e836SMatt Jacob ISPASYNC_BUS_RESET, /* Bus Was Reset */ 73177d4e836SMatt Jacob ISPASYNC_LOOP_DOWN, /* FC Loop Down */ 73277d4e836SMatt Jacob ISPASYNC_LOOP_UP, /* FC Loop Up */ 7335d571944SMatt Jacob ISPASYNC_LIP, /* LIP Received */ 7345d571944SMatt Jacob ISPASYNC_LOOP_RESET, /* Loop Reset Received */ 735410b5567SMatt Jacob ISPASYNC_CHANGE_NOTIFY, /* FC Change Notification */ 736410b5567SMatt Jacob ISPASYNC_FABRIC_DEV, /* FC Fabric Device Arrival */ 737410b5567SMatt Jacob ISPASYNC_PROMENADE, /* FC Objects coming && going */ 73841593b25SMatt Jacob ISPASYNC_TARGET_MESSAGE, /* target message */ 73941593b25SMatt Jacob ISPASYNC_TARGET_EVENT, /* target asynchronous event */ 740410b5567SMatt Jacob ISPASYNC_TARGET_ACTION, /* other target command action */ 7414102f2f6SMatt Jacob ISPASYNC_CONF_CHANGE, /* Platform Configuration Change */ 742b91862efSMatt Jacob ISPASYNC_UNHANDLED_RESPONSE, /* Unhandled Response Entry */ 7430499ae00SMatt Jacob ISPASYNC_FW_CRASH, /* Firmware has crashed */ 744e347e2c9SMatt Jacob ISPASYNC_FW_DUMPED, /* Firmware crashdump taken */ 7450499ae00SMatt Jacob ISPASYNC_FW_RESTARTED /* Firmware has been restarted */ 746cbf57b47SMatt Jacob } ispasync_t; 747e2ec5cf0SMatt Jacob int isp_async(struct ispsoftc *, ispasync_t, void *); 748cbf57b47SMatt Jacob 749410b5567SMatt Jacob #define ISPASYNC_CHANGE_PDB ((void *) 0) 750410b5567SMatt Jacob #define ISPASYNC_CHANGE_SNS ((void *) 1) 751410b5567SMatt Jacob #define ISPASYNC_CHANGE_OTHER ((void *) 2) 752410b5567SMatt Jacob 753478f8a96SJustin T. Gibbs /* 75453cff3bbSMatt Jacob * Platform Dependent Error and Debug Printout 755478f8a96SJustin T. Gibbs */ 756e9423e21SMatt Jacob #ifdef __GNUC__ 757e2ec5cf0SMatt Jacob void isp_prt(struct ispsoftc *, int level, const char *, ...) 758e9423e21SMatt Jacob __attribute__((__format__(__printf__,3,4))); 759e9423e21SMatt Jacob #else 760e2ec5cf0SMatt Jacob void isp_prt(struct ispsoftc *, int level, const char *, ...); 761e9423e21SMatt Jacob #endif 762e9423e21SMatt Jacob 76353cff3bbSMatt Jacob #define ISP_LOGALL 0x0 /* log always */ 76453cff3bbSMatt Jacob #define ISP_LOGCONFIG 0x1 /* log configuration messages */ 76553cff3bbSMatt Jacob #define ISP_LOGINFO 0x2 /* log informational messages */ 76653cff3bbSMatt Jacob #define ISP_LOGWARN 0x4 /* log warning messages */ 76753cff3bbSMatt Jacob #define ISP_LOGERR 0x8 /* log error messages */ 76853cff3bbSMatt Jacob #define ISP_LOGDEBUG0 0x10 /* log simple debug messages */ 76953cff3bbSMatt Jacob #define ISP_LOGDEBUG1 0x20 /* log intermediate debug messages */ 77053cff3bbSMatt Jacob #define ISP_LOGDEBUG2 0x40 /* log most debug messages */ 771b91862efSMatt Jacob #define ISP_LOGDEBUG3 0x80 /* log high frequency debug messages */ 772b91862efSMatt Jacob #define ISP_LOGDEBUG4 0x100 /* log high frequency debug messages */ 77353cff3bbSMatt Jacob #define ISP_LOGTDEBUG0 0x200 /* log simple debug messages (target mode) */ 77453cff3bbSMatt Jacob #define ISP_LOGTDEBUG1 0x400 /* log intermediate debug messages (target) */ 77553cff3bbSMatt Jacob #define ISP_LOGTDEBUG2 0x800 /* log all debug messages (target) */ 776478f8a96SJustin T. Gibbs 77753cff3bbSMatt Jacob /* 77853cff3bbSMatt Jacob * Each Platform provides it's own isposinfo substructure of the ispsoftc 77953cff3bbSMatt Jacob * defined above. 78053cff3bbSMatt Jacob * 78153cff3bbSMatt Jacob * Each platform must also provide the following macros/defines: 78253cff3bbSMatt Jacob * 78353cff3bbSMatt Jacob * 78453cff3bbSMatt Jacob * INLINE - platform specific define for 'inline' functions 78553cff3bbSMatt Jacob * 78666cbe912SMatt Jacob * ISP_DAC_SUPPORTED - Is DAC (Dual Address Cycle) is supported? 78766cbe912SMatt Jacob * Basically means whether or not DMA for PCI 78866cbe912SMatt Jacob * PCI cards (Ultra2 or better or FC) works 78966cbe912SMatt Jacob * above 4GB. 790126ec864SMatt Jacob * 79153cff3bbSMatt Jacob * ISP2100_SCRLEN - length for the Fibre Channel scratch DMA area 79253cff3bbSMatt Jacob * 79353cff3bbSMatt Jacob * MEMZERO(dst, src) platform zeroing function 79453cff3bbSMatt Jacob * MEMCPY(dst, src, count) platform copying function 79553cff3bbSMatt Jacob * SNPRINTF(buf, bufsize, fmt, ...) snprintf 79653cff3bbSMatt Jacob * USEC_DELAY(usecs) microsecond spindelay function 79767afe757SMatt Jacob * USEC_SLEEP(isp, usecs) microsecond sleep function 79853cff3bbSMatt Jacob * 79953cff3bbSMatt Jacob * NANOTIME_T nanosecond time type 80053cff3bbSMatt Jacob * 80153cff3bbSMatt Jacob * GET_NANOTIME(NANOTIME_T *) get current nanotime. 80253cff3bbSMatt Jacob * 80353cff3bbSMatt Jacob * GET_NANOSEC(NANOTIME_T *) get u_int64_t from NANOTIME_T 80453cff3bbSMatt Jacob * 80553cff3bbSMatt Jacob * NANOTIME_SUB(NANOTIME_T *, NANOTIME_T *) 80653cff3bbSMatt Jacob * subtract two NANOTIME_T values 80753cff3bbSMatt Jacob * 80853cff3bbSMatt Jacob * 80953cff3bbSMatt Jacob * MAXISPREQUEST(struct ispsoftc *) maximum request queue size 81053cff3bbSMatt Jacob * for this particular board type 81153cff3bbSMatt Jacob * 81253cff3bbSMatt Jacob * MEMORYBARRIER(struct ispsoftc *, barrier_type, offset, size) 81353cff3bbSMatt Jacob * 81453cff3bbSMatt Jacob * Function/Macro the provides memory synchronization on 81553cff3bbSMatt Jacob * various objects so that the ISP's and the system's view 81653cff3bbSMatt Jacob * of the same object is consistent. 81753cff3bbSMatt Jacob * 81853cff3bbSMatt Jacob * MBOX_ACQUIRE(struct ispsoftc *) acquire lock on mailbox regs 81953cff3bbSMatt Jacob * MBOX_WAIT_COMPLETE(struct ispsoftc *) wait for mailbox cmd to be done 82053cff3bbSMatt Jacob * MBOX_NOTIFY_COMPLETE(struct ispsoftc *) notification of mbox cmd donee 82153cff3bbSMatt Jacob * MBOX_RELEASE(struct ispsoftc *) release lock on mailbox regs 82253cff3bbSMatt Jacob * 82375c1e828SMatt Jacob * FC_SCRATCH_ACQUIRE(struct ispsoftc *) acquire lock on FC scratch area 82475c1e828SMatt Jacob * FC_SCRATCH_RELEASE(struct ispsoftc *) acquire lock on FC scratch area 82553cff3bbSMatt Jacob * 82653cff3bbSMatt Jacob * SCSI_GOOD SCSI 'Good' Status 82753cff3bbSMatt Jacob * SCSI_CHECK SCSI 'Check Condition' Status 82853cff3bbSMatt Jacob * SCSI_BUSY SCSI 'Busy' Status 82953cff3bbSMatt Jacob * SCSI_QFULL SCSI 'Queue Full' Status 83053cff3bbSMatt Jacob * 83153cff3bbSMatt Jacob * XS_T Platform SCSI transaction type (i.e., command for HBA) 83253cff3bbSMatt Jacob * XS_ISP(xs) gets an instance out of an XS_T 83353cff3bbSMatt Jacob * XS_CHANNEL(xs) gets the channel (bus # for DUALBUS cards) "" 83453cff3bbSMatt Jacob * XS_TGT(xs) gets the target "" 83553cff3bbSMatt Jacob * XS_LUN(xs) gets the lun "" 83653cff3bbSMatt Jacob * XS_CDBP(xs) gets a pointer to the scsi CDB "" 83753cff3bbSMatt Jacob * XS_CDBLEN(xs) gets the CDB's length "" 83853cff3bbSMatt Jacob * XS_XFRLEN(xs) gets the associated data transfer length "" 83953cff3bbSMatt Jacob * XS_TIME(xs) gets the time (in milliseconds) for this command 84053cff3bbSMatt Jacob * XS_RESID(xs) gets the current residual count 84153cff3bbSMatt Jacob * XS_STSP(xs) gets a pointer to the SCSI status byte "" 84253cff3bbSMatt Jacob * XS_SNSP(xs) gets a pointer to the associate sense data 84353cff3bbSMatt Jacob * XS_SNSLEN(xs) gets the length of sense data storage 84453cff3bbSMatt Jacob * XS_SNSKEY(xs) dereferences XS_SNSP to get the current stored Sense Key 84553cff3bbSMatt Jacob * XS_TAG_P(xs) predicate of whether this command should be tagged 84653cff3bbSMatt Jacob * XS_TAG_TYPE(xs) which type of tag to use 84753cff3bbSMatt Jacob * XS_SETERR(xs) set error state 84853cff3bbSMatt Jacob * 84953cff3bbSMatt Jacob * HBA_NOERROR command has no erros 85053cff3bbSMatt Jacob * HBA_BOTCH hba botched something 85153cff3bbSMatt Jacob * HBA_CMDTIMEOUT command timed out 85253cff3bbSMatt Jacob * HBA_SELTIMEOUT selection timed out (also port logouts for FC) 85353cff3bbSMatt Jacob * HBA_TGTBSY target returned a BUSY status 85453cff3bbSMatt Jacob * HBA_BUSRESET bus reset destroyed command 85553cff3bbSMatt Jacob * HBA_ABORTED command was aborted (by request) 85653cff3bbSMatt Jacob * HBA_DATAOVR a data overrun was detected 85753cff3bbSMatt Jacob * HBA_ARQFAIL Automatic Request Sense failed 85853cff3bbSMatt Jacob * 85953cff3bbSMatt Jacob * XS_ERR(xs) return current error state 86053cff3bbSMatt Jacob * XS_NOERR(xs) there is no error currently set 86153cff3bbSMatt Jacob * XS_INITERR(xs) initialize error state 86253cff3bbSMatt Jacob * 86353cff3bbSMatt Jacob * XS_SAVE_SENSE(xs, sp) save sense data 86453cff3bbSMatt Jacob * 86553cff3bbSMatt Jacob * XS_SET_STATE_STAT(isp, sp, xs) platform dependent interpreter of 86653cff3bbSMatt Jacob * response queue entry status bits 86753cff3bbSMatt Jacob * 86853cff3bbSMatt Jacob * 86953cff3bbSMatt Jacob * DEFAULT_IID(struct ispsoftc *) Default SCSI initiator ID 87053cff3bbSMatt Jacob * DEFAULT_LOOPID(struct ispsoftc *) Default FC Loop ID 8719cf43b97SMatt Jacob * DEFAULT_NODEWWN(struct ispsoftc *) Default Node WWN 8729cf43b97SMatt Jacob * DEFAULT_PORTWWN(struct ispsoftc *) Default Port WWN 8730499ae00SMatt Jacob * DEFAULT_FRAMESIZE(struct ispsoftc *) Default Frame Size 8740499ae00SMatt Jacob * DEFAULT_EXEC_THROTTLE(struct ispsoftc *) Default Execution Throttle 8759cf43b97SMatt Jacob * These establish reasonable defaults for each platform. 8769cf43b97SMatt Jacob * These must be available independent of card NVRAM and are 8779cf43b97SMatt Jacob * to be used should NVRAM not be readable. 87853cff3bbSMatt Jacob * 8799cf43b97SMatt Jacob * ISP_NODEWWN(struct ispsoftc *) FC Node WWN to use 8809cf43b97SMatt Jacob * ISP_PORTWWN(struct ispsoftc *) FC Port WWN to use 88153cff3bbSMatt Jacob * 8829cf43b97SMatt Jacob * These are to be used after NVRAM is read. The tags 8839cf43b97SMatt Jacob * in fcparam.isp_{node,port}wwn reflect the values 8849cf43b97SMatt Jacob * read from NVRAM (possibly corrected for card botches). 8859cf43b97SMatt Jacob * Each platform can take that information and override 8869cf43b97SMatt Jacob * it or ignore and return the Node and Port WWNs to be 8879cf43b97SMatt Jacob * used when sending the Qlogic f/w the Initialization Control 8889cf43b97SMatt Jacob * Block. 88953cff3bbSMatt Jacob * 89053cff3bbSMatt Jacob * (XXX these do endian specific transformations- in transition XXX) 8914fd13c1bSMatt Jacob * 8924fd13c1bSMatt Jacob * ISP_IOXPUT_8(struct ispsoftc *, u_int8_t srcval, u_int8_t *dstptr) 8934fd13c1bSMatt Jacob * ISP_IOXPUT_16(struct ispsoftc *, u_int16_t srcval, u_int16_t *dstptr) 8944fd13c1bSMatt Jacob * ISP_IOXPUT_32(struct ispsoftc *, u_int32_t srcval, u_int32_t *dstptr) 8954fd13c1bSMatt Jacob * 8964fd13c1bSMatt Jacob * ISP_IOXGET_8(struct ispsoftc *, u_int8_t *srcptr, u_int8_t dstrval) 8974fd13c1bSMatt Jacob * ISP_IOXGET_16(struct ispsoftc *, u_int16_t *srcptr, u_int16_t dstrval) 8984fd13c1bSMatt Jacob * ISP_IOXGET_32(struct ispsoftc *, u_int32_t *srcptr, u_int32_t dstrval) 8994fd13c1bSMatt Jacob * 9004fd13c1bSMatt Jacob * ISP_SWIZZLE_NVRAM_WORD(struct ispsoftc *, u_int16_t *) 90153cff3bbSMatt Jacob */ 9025d571944SMatt Jacob 9036054c3f6SMatt Jacob #endif /* _ISPVAR_H */ 904