1 /* $NetBSD: ispvar.h,v 1.76 2023/09/21 09:31:50 msaitoh Exp $ */
2 /*
3  * Copyright (C) 1999 National Aeronautics & Space Administration
4  * All rights reserved.
5  *
6  * Additional Copyright (C) 2000-2007 by Matthew Jacob
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 /*
32  * Additional Copyright (c) 1997-2006 by Matthew Jacob
33  * All rights reserved.
34  *
35  * Redistribution and use in source and binary forms, with or without
36  * modification, are permitted provided that the following conditions
37  * are met:
38  *
39  *  1. Redistributions of source code must retain the above copyright
40  *     notice, this list of conditions, and the following disclaimer,
41  *     without modification, immediately at the beginning of the file.
42  *  2. The name of the author may not be used to endorse or promote products
43  *     derived from this software without specific prior written permission.
44  *
45  *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
46  *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48  *  ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
49  *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50  *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51  *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55  *  SUCH DAMAGE.
56  */
57 /*
58  * Soft Definitions for Qlogic ISP SCSI adapters.
59  */
60 
61 #ifndef   _ISPVAR_H
62 #define   _ISPVAR_H
63 
64 #if defined(__NetBSD__) || defined(__OpenBSD__)
65 #include <dev/ic/isp_stds.h>
66 #include <dev/ic/ispmbox.h>
67 #endif
68 #ifdef    __FreeBSD__
69 #include <dev/isp/isp_stds.h>
70 #include <dev/isp/ispmbox.h>
71 #endif
72 #ifdef    __linux__
73 #include "isp_stds.h"
74 #include "ispmbox.h"
75 #endif
76 #ifdef    __svr4__
77 #include "isp_stds.h"
78 #include "ispmbox.h"
79 #endif
80 
81 #define   ISP_CORE_VERSION_MAJOR        7
82 #define   ISP_CORE_VERSION_MINOR        0
83 
84 /*
85  * Vector for bus specific code to provide specific services.
86  */
87 typedef struct ispsoftc ispsoftc_t;
88 struct ispmdvec {
89           int                 (*dv_rd_isr) (ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *);
90           uint32_t  (*dv_rd_reg) (ispsoftc_t *, int);
91           void                (*dv_wr_reg) (ispsoftc_t *, int, uint32_t);
92           int                 (*dv_mbxdma) (ispsoftc_t *);
93           int                 (*dv_dmaset) (ispsoftc_t *, XS_T *, void *);
94           void                (*dv_dmaclr) (ispsoftc_t *, XS_T *, uint32_t);
95           void                (*dv_reset0) (ispsoftc_t *);
96           void                (*dv_reset1) (ispsoftc_t *);
97           void                (*dv_dregs) (ispsoftc_t *, const char *);
98           const void *        dv_ispfw; /* ptr to f/w */
99           uint16_t  dv_conf1;
100           uint16_t  dv_clock; /* clock frequency */
101 };
102 
103 /*
104  * Overall parameters
105  */
106 #define   MAX_TARGETS                   16
107 #ifndef   MAX_FC_TARG
108 #define   MAX_FC_TARG                   512
109 #endif
110 #define   ISP_MAX_TARGETS(isp)          (IS_FC(isp)? MAX_FC_TARG : MAX_TARGETS)
111 #define   ISP_MAX_LUNS(isp)   (isp)->isp_maxluns
112 
113 /*
114  * Macros to access ISP registers through bus specific layers-
115  * mostly wrappers to vector through the mdvec structure.
116  */
117 #define   ISP_READ_ISR(isp, isrp, semap, mbox0p)  \
118           (*(isp)->isp_mdvec->dv_rd_isr)(isp, isrp, semap, mbox0p)
119 
120 #define   ISP_READ(isp, reg)  \
121           (*(isp)->isp_mdvec->dv_rd_reg)((isp), (reg))
122 
123 #define   ISP_WRITE(isp, reg, val)      \
124           (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), (val))
125 
126 #define   ISP_MBOXDMASETUP(isp)         \
127           (*(isp)->isp_mdvec->dv_mbxdma)((isp))
128 
129 #define   ISP_DMASETUP(isp, xs, req)    \
130           (*(isp)->isp_mdvec->dv_dmaset)((isp), (xs), (req))
131 
132 #define   ISP_DMAFREE(isp, xs, hndl)              \
133           if ((isp)->isp_mdvec->dv_dmaclr)        \
134               (*(isp)->isp_mdvec->dv_dmaclr)((isp), (xs), (hndl))
135 
136 #define   ISP_RESET0(isp)     \
137           if ((isp)->isp_mdvec->dv_reset0) (*(isp)->isp_mdvec->dv_reset0)((isp))
138 #define   ISP_RESET1(isp)     \
139           if ((isp)->isp_mdvec->dv_reset1) (*(isp)->isp_mdvec->dv_reset1)((isp))
140 #define   ISP_DUMPREGS(isp, m)          \
141           if ((isp)->isp_mdvec->dv_dregs) (*(isp)->isp_mdvec->dv_dregs)((isp),(m))
142 
143 #define   ISP_SETBITS(isp, reg, val)    \
144  (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) | (val))
145 
146 #define   ISP_CLRBITS(isp, reg, val)    \
147  (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) & ~(val))
148 
149 /*
150  * The MEMORYBARRIER macro is defined per platform (to provide synchronization
151  * on Request and Response Queues, Scratch DMA areas, and Registers)
152  *
153  * Defined Memory Barrier Synchronization Types
154  */
155 #define   SYNC_REQUEST        0         /* request queue synchronization */
156 #define   SYNC_RESULT         1         /* result queue synchronization */
157 #define   SYNC_SFORDEV        2         /* scratch, sync for ISP */
158 #define   SYNC_SFORCPU        3         /* scratch, sync for CPU */
159 #define   SYNC_REG  4         /* for registers */
160 #define   SYNC_ATIOQ          5         /* atio result queue (24xx) */
161 
162 /*
163  * Request/Response Queue defines and macros.
164  * The maximum is defined per platform (and can be based on board type).
165  */
166 /* This is the size of a queue entry (request and response) */
167 #define   QENTRY_LEN                              64
168 /* Both request and result queue length must be a power of two */
169 #define   RQUEST_QUEUE_LEN(x)           MAXISPREQUEST(x)
170 #ifdef    ISP_TARGET_MODE
171 #define   RESULT_QUEUE_LEN(x)           MAXISPREQUEST(x)
172 #else
173 #define   RESULT_QUEUE_LEN(x)           \
174           (((MAXISPREQUEST(x) >> 2) < 64)? 64 : MAXISPREQUEST(x) >> 2)
175 #endif
176 #define   ISP_QUEUE_ENTRY(q, idx)                 (((uint8_t *)q) + ((idx) * QENTRY_LEN))
177 #define   ISP_QUEUE_SIZE(n)             ((n) * QENTRY_LEN)
178 #define   ISP_NXT_QENTRY(idx, qlen)     (((idx) + 1) & ((qlen)-1))
179 #define   ISP_QFREE(in, out, qlen)      \
180           ((in == out)? (qlen - 1) : ((in > out)? \
181           ((qlen - 1) - (in - out)) : (out - in - 1)))
182 #define   ISP_QAVAIL(isp)     \
183           ISP_QFREE(isp->isp_reqidx, isp->isp_reqodx, RQUEST_QUEUE_LEN(isp))
184 
185 #define   ISP_ADD_REQUEST(isp, nxti)                                                      \
186           MEMORYBARRIER(isp, SYNC_REQUEST, isp->isp_reqidx, QENTRY_LEN, -1);    \
187           ISP_WRITE(isp, isp->isp_rqstinrp, nxti);                                        \
188           isp->isp_reqidx = nxti
189 
190 #define   ISP_SYNC_REQUEST(isp)                                                                               \
191           MEMORYBARRIER(isp, SYNC_REQUEST, isp->isp_reqidx, QENTRY_LEN, -1);              \
192           isp->isp_reqidx = ISP_NXT_QENTRY(isp->isp_reqidx, RQUEST_QUEUE_LEN(isp));       \
193           ISP_WRITE(isp, isp->isp_rqstinrp, isp->isp_reqidx)
194 
195 /*
196  * SCSI Specific Host Adapter Parameters- per bus, per target
197  */
198 typedef struct {
199           uint32_t                                : 8,
200                               update                        : 1,
201                               sendmarker                    : 1,
202                               role                          : 2,
203                               isp_req_ack_active_neg        : 1,
204                               isp_data_line_active_neg: 1,
205                               isp_cmd_dma_burst_enable: 1,
206                               isp_data_dma_burst_enabl: 1,
207                               isp_fifo_threshold  : 3,
208                               isp_ptisp           : 1,
209                               isp_ultramode                 : 1,
210                               isp_diffmode                  : 1,
211                               isp_lvdmode                   : 1,
212                               isp_fast_mttr                 : 1,      /* fast sram */
213                               isp_initiator_id    : 4,
214                               isp_async_data_setup          : 4;
215           uint16_t  isp_selection_timeout;
216           uint16_t  isp_max_queue_depth;
217           uint8_t             isp_tag_aging;
218           uint8_t             isp_bus_reset_delay;
219           uint8_t             isp_retry_count;
220           uint8_t             isp_retry_delay;
221           struct {
222                     uint32_t
223                               exc_throttle        :         8,
224                                                   :         1,
225                               dev_enable          :         1,        /* ignored */
226                               dev_update          :         1,
227                               dev_refresh         :         1,
228                               actv_offset         :         4,
229                               goal_offset         :         4,
230                               nvrm_offset         :         4;
231                     uint8_t             actv_period;        /* current sync period */
232                     uint8_t             goal_period;        /* goal sync period */
233                     uint8_t             nvrm_period;        /* nvram sync period */
234                     uint16_t  actv_flags;         /* current device flags */
235                     uint16_t  goal_flags;         /* goal device flags */
236                     uint16_t  nvrm_flags;         /* nvram device flags */
237           } isp_devparam[MAX_TARGETS];
238 } sdparam;
239 
240 /*
241  * Device Flags
242  */
243 #define   DPARM_DISC          0x8000
244 #define   DPARM_PARITY        0x4000
245 #define   DPARM_WIDE          0x2000
246 #define   DPARM_SYNC          0x1000
247 #define   DPARM_TQING         0x0800
248 #define   DPARM_ARQ 0x0400
249 #define   DPARM_QFRZ          0x0200
250 #define   DPARM_RENEG         0x0100
251 #define   DPARM_NARROW        0x0080
252 #define   DPARM_ASYNC         0x0040
253 #define   DPARM_PPR 0x0020
254 #define   DPARM_DEFAULT       (0xFF00 & ~DPARM_QFRZ)
255 #define   DPARM_SAFE_DFLT     (DPARM_DEFAULT & ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING))
256 
257 /* technically, not really correct, as they need to be rated based upon clock */
258 #define   ISP_80M_SYNCPARMS   0x0c09
259 #define   ISP_40M_SYNCPARMS   0x0c0a
260 #define   ISP_20M_SYNCPARMS   0x0c0c
261 #define   ISP_20M_SYNCPARMS_1040        0x080c
262 #define   ISP_10M_SYNCPARMS   0x0c19
263 #define   ISP_08M_SYNCPARMS   0x0c25
264 #define   ISP_05M_SYNCPARMS   0x0c32
265 #define   ISP_04M_SYNCPARMS   0x0c41
266 
267 /*
268  * Fibre Channel Specifics
269  */
270 /* These are for non-2K Login Firmware cards */
271 #define   FL_ID                         0x7e      /* FL_Port Special ID */
272 #define   SNS_ID                        0x80      /* SNS Server Special ID */
273 #define   NPH_MAX                       0xfe
274 
275 /* Use this handle for the base for multi-id firmware SNS logins */
276 #define   NPH_SNS_HDLBASE               0x400
277 
278 /* These are for 2K Login Firmware cards */
279 #define   NPH_RESERVED                  0x7F0     /* begin of reserved N-port handles */
280 #define   NPH_MGT_ID                    0x7FA     /* Management Server Special ID */
281 #define   NPH_SNS_ID                    0x7FC     /* SNS Server Special ID */
282 #define   NPH_FABRIC_CTLR               0x7FD     /* Fabric Controller (0xFFFFFD) */
283 #define   NPH_FL_ID           0x7FE     /* F Port Special ID (0xFFFFFE) */
284 #define   NPH_IP_BCST                   0x7ff     /* IP Broadcast Special ID (0xFFFFFF) */
285 #define   NPH_MAX_2K                    0x800
286 
287 /*
288  * "Unassigned" handle to be used internally
289  */
290 #define   NIL_HANDLE                    0xffff
291 
292 /*
293  * Limit for devices on an arbitrated loop.
294  */
295 #define   LOCAL_LOOP_LIM                126
296 
297 /*
298  * Limit for (2K login) N-port handle amounts
299  */
300 #define   MAX_NPORT_HANDLE    2048
301 
302 /*
303  * Special Constants
304  */
305 #define   INI_NONE                      ((uint64_t) 0)
306 #define   ISP_NOCHAN                    0xff
307 
308 /*
309  * Special Port IDs
310  */
311 #define   MANAGEMENT_PORT_ID  0xFFFFFA
312 #define   SNS_PORT_ID                   0xFFFFFC
313 #define   FABRIC_PORT_ID                0xFFFFFE
314 #define   PORT_ANY            0xFFFFFF
315 #define   PORT_NONE           0
316 #define   DOMAIN_CONTROLLER_BASE        0xFFFC00
317 #define   DOMAIN_CONTROLLER_END         0xFFFCFF
318 
319 /*
320  * Command Handles
321  *
322  * Most QLogic initiator or target have 32 bit handles associated with them.
323  * We want to have a quick way to index back and forth between a local SCSI
324  * command context and what the firmware is passing back to us. We also
325  * want to avoid working on stale information. This structure handles both
326  * at the expense of some local memory.
327  *
328  * The handle is architected thusly:
329  *
330  *        0 means "free handle"
331  *        bits  0..12 index commands
332  *        bits 13..15 bits index usage
333  *        bits 16..31 contain a rolling sequence
334  *
335  *
336  */
337 typedef struct {
338           void *              cmd;      /* associated command context */
339           uint32_t  handle;   /* handle associated with this command */
340 } isp_hdl_t;
341 #define   ISP_HANDLE_FREE               0x00000000
342 #define   ISP_HANDLE_CMD_MASK 0x00001fff
343 #define   ISP_HANDLE_USAGE_MASK         0x0000e000
344 #define   ISP_HANDLE_USAGE_SHIFT        13
345 #define   ISP_H2HT(hdl)       ((hdl & ISP_HANDLE_USAGE_MASK) >> ISP_HANDLE_USAGE_SHIFT)
346 #         define    ISP_HANDLE_NONE               0
347 #         define    ISP_HANDLE_INITIATOR          1
348 #         define    ISP_HANDLE_TARGET   2
349 #define   ISP_HANDLE_SEQ_MASK 0xffff0000
350 #define   ISP_HANDLE_SEQ_SHIFT          16
351 #define   ISP_H2SEQ(hdl)      ((hdl & ISP_HANDLE_SEQ_MASK) >> ISP_HANDLE_SEQ_SHIFT)
352 #define   ISP_VALID_INI_HANDLE(c, hdl)  \
353           (ISP_H2HT(hdl) == ISP_HANDLE_INITIATOR && (hdl & ISP_HANDLE_CMD_MASK) < (c)->isp_maxcmds && \
354            ISP_H2SEQ(hdl) == ISP_H2SEQ((c)->isp_xflist[hdl & ISP_HANDLE_CMD_MASK].handle))
355 #ifdef    ISP_TARGET_MODE
356 #define   ISP_VALID_TGT_HANDLE(c, hdl)  \
357           (ISP_H2HT(hdl) == ISP_HANDLE_TARGET && (hdl & ISP_HANDLE_CMD_MASK) < (c)->isp_maxcmds && \
358            ISP_H2SEQ(hdl) == ISP_H2SEQ((c)->isp_tgtlist[hdl & ISP_HANDLE_CMD_MASK].handle))
359 #define   ISP_VALID_HANDLE(c, hdl)      \
360           (ISP_VALID_INI_HANDLE((c), hdl) || ISP_VALID_TGT_HANDLE((c), hdl))
361 #else
362 #define   ISP_VALID_HANDLE    ISP_VALID_INI_HANDLE
363 #endif
364 #define   ISP_BAD_HANDLE_INDEX          0xffffffff
365 
366 
367 /*
368  * FC Port Database entry.
369  *
370  * It has a handle that the f/w uses to address commands to a device.
371  * This handle's value may be assigned by the firmware (e.g., for local loop
372  * devices) or by the driver (e.g., for fabric devices).
373  *
374  * It has a state. If the state if VALID, that means that we've logged into
375  * the device. We also *may* have a initiator map index entry. This is a value
376  * from 0..MAX_FC_TARG that is used to index into the isp_dev_map array. If
377  * the value therein is non-zero, then that value minus one is used to index
378  * into the Port Database to find the handle for forming commands. There is
379  * back-index minus one value within to Port Database entry that tells us
380  * which entry in isp_dev_map points to us (to avoid searching).
381  *
382  * Local loop devices the firmware automatically performs PLOGI on for us
383  * (which is why that handle is imposed upon us). Fabric devices we assign
384  * a handle to and perform the PLOGI on.
385  *
386  * When a PORT DATABASE CHANGED asynchronous event occurs, we mark all VALID
387  * entries as PROBATIONAL. This allows us, if policy says to, just keep track
388  * of devices whose handles change but are otherwise the same device (and
389  * thus keep 'target' constant).
390  *
391  * In any case, we search all possible local loop handles. For each one that
392  * has a port database entity returned, we search for any PROBATIONAL entry
393  * that matches it and update as appropriate. Otherwise, as a new entry, we
394  * find room for it in the Port Database. We *try* and use the handle as the
395  * index to put it into the Database, but that's just an optimization. We mark
396  * the entry VALID and make sure that the target index is updated and correct.
397  *
398  * When we get done searching the local loop, we then search similarly for
399  * a list of devices we've gotten from the fabric name controller (if we're
400  * on a fabric). VALID marking is also done similarly.
401  *
402  * When all of this is done, we can march through the database and clean up
403  * any entry that is still PROBATIONAL (these represent devices which have
404  * departed). Then we're done and can resume normal operations.
405  *
406  * Negative invariants that we try and test for are:
407  *
408  *  + There can never be two non-NIL entries with the same { Port, Node } WWN
409  *    duples.
410  *
411  *  + There can never be two non-NIL entries with the same handle.
412  *
413  *  + There can never be two non-NIL entries which have the same dev_map_idx
414  *    value.
415  */
416 typedef struct {
417           /*
418            * This is the handle that the firmware needs in order for us to
419            * send commands to the device. For pre-24XX cards, this would be
420            * the 'loopid'.
421            */
422           uint16_t  handle;
423 
424           /*
425            * The dev_map_idx, if nonzero, is the system virtual target ID (+1)
426            * as a cross-reference with the isp_dev_map.
427            *
428            * A device is 'autologin' if the firmware automatically logs into
429            * it (re-logins as needed). Basically, local private loop devices.
430            *
431            * The state is the current state of this entry.
432            *
433            * Role is Initiator, Target, Both
434            *
435            * Portid is obvious, as are node && port WWNs. The new_role and
436            * new_portid is for when we are pending a change.
437            *
438            * The 'target_mode' tag means that this entry arrived via a
439            * target mode command and is immune from normal flushing rules.
440            * You should also never see anything with an initiator role
441            * with this set.
442            */
443           uint16_t  dev_map_idx         : 12,
444                               autologin : 1,      /* F/W does PLOGI/PLOGO */
445                               state               : 3;
446           uint32_t  reserved  : 5,
447                               target_mode         : 1,
448                               roles               : 2,
449                               portid              : 24;
450           uint32_t
451                               dirty               : 1,      /* commands have been run */
452                               new_reserved        : 5,
453                               new_roles : 2,
454                               new_portid          : 24;
455           uint64_t  node_wwn;
456           uint64_t  port_wwn;
457           uint32_t  gone_timer;
458 } fcportdb_t;
459 
460 #define   FC_PORTDB_STATE_NIL           0
461 #define   FC_PORTDB_STATE_PROBATIONAL   1
462 #define   FC_PORTDB_STATE_DEAD                    2
463 #define   FC_PORTDB_STATE_CHANGED                 3
464 #define   FC_PORTDB_STATE_NEW           4
465 #define   FC_PORTDB_STATE_PENDING_VALID 5
466 #define   FC_PORTDB_STATE_ZOMBIE                  6
467 #define   FC_PORTDB_STATE_VALID                   7
468 
469 /*
470  * FC card specific information
471  *
472  * This structure is replicated across multiple channels for multi-id
473  * capapble chipsets, with some entities different on a per-channel basis.
474  */
475 
476 typedef struct {
477           uint32_t
478                                         link_active         : 1,
479                                         npiv_fabric         : 1,
480                                         inorder             : 1,
481                                         sendmarker          : 1,
482                                         role                : 2,
483                                         isp_gbspeed         : 4,
484                                         isp_loopstate       : 4,      /* Current Loop State */
485                                         isp_fwstate         : 4,      /* ISP F/W state */
486                                         isp_topo  : 3,      /* Connection Type */
487                                         loop_seen_once      : 1;
488 
489           uint32_t                                : 8,
490                                         isp_portid          : 24;     /* S_ID */
491 
492 
493           uint16_t            isp_fwoptions;
494           uint16_t            isp_xfwoptions;
495           uint16_t            isp_zfwoptions;
496           uint16_t            isp_loopid;                   /* hard loop id */
497           uint16_t            isp_sns_hdl;                  /* N-port handle for SNS */
498           uint16_t            isp_lasthdl;                  /* only valid for channel 0 */
499           uint16_t            isp_maxalloc;
500           uint8_t                       isp_retry_delay;
501           uint8_t                       isp_retry_count;
502 
503           /*
504            * Current active WWNN/WWPN
505            */
506           uint64_t            isp_wwnn;
507           uint64_t            isp_wwpn;
508 
509           /*
510            * NVRAM WWNN/WWPN
511            */
512           uint64_t            isp_wwnn_nvram;
513           uint64_t            isp_wwpn_nvram;
514 
515           /*
516            * Our Port Data Base
517            */
518           fcportdb_t                    portdb[MAX_FC_TARG];
519 
520           /*
521            * This maps system virtual 'target' id to a portdb entry.
522            *
523            * The mapping function is to take any non-zero entry and
524            * subtract one to get the portdb index. This means that
525            * entries which are zero are unmapped (i.e., don't exist).
526            */
527           uint16_t            isp_dev_map[MAX_FC_TARG];
528 
529 #ifdef    ISP_TARGET_MODE
530           /*
531            * This maps N-Port Handle to portdb entry so we
532            * don't have to search for every incoming command.
533            *
534            * The mapping function is to take any non-zero entry and
535            * subtract one to get the portdb index. This means that
536            * entries which are zero are unmapped (i.e., don't exist).
537            */
538           uint16_t            isp_tgt_map[MAX_NPORT_HANDLE];
539 #endif
540 
541           /*
542            * Scratch DMA mapped in area to fetch Port Database stuff, etc.
543            */
544           void *                        isp_scratch;
545           XS_DMA_ADDR_T                 isp_scdma;
546 } fcparam;
547 
548 #define   FW_CONFIG_WAIT                0
549 #define   FW_WAIT_AL_PA                 1
550 #define   FW_WAIT_LOGIN                 2
551 #define   FW_READY            3
552 #define   FW_LOSS_OF_SYNC               4
553 #define   FW_ERROR            5
554 #define   FW_REINIT           6
555 #define   FW_NON_PART                   7
556 
557 #define   LOOP_NIL            0
558 #define   LOOP_LIP_RCVD                 1
559 #define   LOOP_PDB_RCVD                 2
560 #define   LOOP_SCANNING_LOOP  3
561 #define   LOOP_LSCAN_DONE               4
562 #define   LOOP_SCANNING_FABRIC          5
563 #define   LOOP_FSCAN_DONE               6
564 #define   LOOP_SYNCING_PDB    7
565 #define   LOOP_READY                    8
566 
567 #define   TOPO_NL_PORT                  0
568 #define   TOPO_FL_PORT                  1
569 #define   TOPO_N_PORT                   2
570 #define   TOPO_F_PORT                   3
571 #define   TOPO_PTP_STUB                 4
572 
573 /*
574  * Soft Structure per host adapter
575  */
576 struct ispsoftc {
577           /*
578            * Platform (OS) specific data
579            */
580           struct isposinfo    isp_osinfo;
581 
582           /*
583            * Pointer to bus specific functions and data
584            */
585           struct ispmdvec *   isp_mdvec;
586 
587           /*
588            * (Mostly) nonvolatile state. Board specific parameters
589            * may contain some volatile state (e.g., current loop state).
590            */
591 
592           void *                        isp_param;          /* type specific */
593           uint16_t            isp_fwrev[3];       /* Loaded F/W revision */
594           uint16_t            isp_maxcmds;        /* max possible I/O cmds */
595           uint8_t                       isp_type; /* HBA Chip Type */
596           uint8_t                       isp_revision;       /* HBA Chip H/W Revision */
597           uint32_t            isp_maxluns;        /* maximum luns supported */
598 
599           uint32_t            isp_clock : 8,      /* input clock */
600                                                             : 4,
601                                         isp_port  : 1,      /* 23XX/24XX only */
602                                         isp_open  : 1,      /* opened (ioctl) */
603                                         isp_bustype         : 1,      /* SBus or PCI */
604                                         isp_loaded_fw       : 1,      /* loaded firmware */
605                                         isp_dblev : 16;     /* debug log mask */
606 
607           uint16_t            isp_fwattr;         /* firmware attributes */
608           uint16_t            isp_nchan;          /* number of channels */
609 
610           uint32_t            isp_confopts;       /* config options */
611 
612           uint32_t            isp_rqstinrp;       /* register for REQINP */
613           uint32_t            isp_rqstoutrp;      /* register for REQOUTP */
614           uint32_t            isp_respinrp;       /* register for RESINP */
615           uint32_t            isp_respoutrp;      /* register for RESOUTP */
616 
617           /*
618            * Instrumentation
619            */
620           uint64_t            isp_intcnt;                   /* total int count */
621           uint64_t            isp_intbogus;                 /* spurious int count */
622           uint64_t            isp_intmboxc;                 /* mbox completions */
623           uint64_t            isp_intoasync;                /* other async */
624           uint64_t            isp_rsltccmplt;               /* CMDs on result q */
625           uint64_t            isp_fphccmplt;                /* CMDs via fastpost */
626           uint16_t            isp_rscchiwater;
627           uint16_t            isp_fpcchiwater;
628           NANOTIME_T                    isp_init_time;                /* time were last initialized */
629 
630           /*
631            * Volatile state
632            */
633 
634           volatile uint32_t   :         8,
635                                         :         2,
636                     isp_dead  :         1,
637                                         :         1,
638                     isp_mboxbsy         :         1,        /* mailbox command active */
639                     isp_state :         3,
640                     isp_nactive         :         16;       /* how many commands active */
641           volatile mbreg_t    isp_curmbx;         /* currently active mailbox command */
642           volatile uint32_t   isp_reqodx;         /* index of last ISP pickup */
643           volatile uint32_t   isp_reqidx;         /* index of next request */
644           volatile uint32_t   isp_residx;         /* index of next result */
645           volatile uint32_t   isp_resodx;         /* index of next result */
646           volatile uint32_t   isp_obits;          /* mailbox command output */
647           volatile uint32_t   isp_serno;          /* rolling serial number */
648           volatile uint16_t   isp_mboxtmp[MAILBOX_STORAGE];
649           volatile uint16_t   isp_lastmbxcmd;     /* last mbox command sent */
650           volatile uint16_t   isp_mbxwrk0;
651           volatile uint16_t   isp_mbxwrk1;
652           volatile uint16_t   isp_mbxwrk2;
653           volatile uint16_t   isp_mbxwrk8;
654           volatile uint16_t   isp_seqno;          /* running sequence number */
655           void *                        isp_mbxworkp;
656 
657           /*
658            * Active commands are stored here, indexed by handle functions.
659            */
660           isp_hdl_t           *isp_xflist;
661           isp_hdl_t           *isp_xffree;
662 
663 #ifdef    ISP_TARGET_MODE
664           /*
665            * Active target commands are stored here, indexed by handle functions.
666            */
667           isp_hdl_t           *isp_tgtlist;
668           isp_hdl_t           *isp_tgtfree;
669 #endif
670 
671           /*
672            * request/result queue pointers and DMA handles for them.
673            */
674           void *                        isp_rquest;
675           void *                        isp_result;
676           XS_DMA_ADDR_T                 isp_rquest_dma;
677           XS_DMA_ADDR_T                 isp_result_dma;
678 #ifdef    ISP_TARGET_MODE
679           /* for 24XX only */
680           void *                        isp_atioq;
681           XS_DMA_ADDR_T                 isp_atioq_dma;
682 #endif
683 };
684 
685 #define   SDPARAM(isp, chan)  (&((sdparam *)(isp)->isp_param)[(chan)])
686 #define   FCPARAM(isp, chan)  (&((fcparam *)(isp)->isp_param)[(chan)])
687 
688 #define   ISP_SET_SENDMARKER(isp, chan, val)      \
689     if (IS_FC(isp)) {                                       \
690           FCPARAM(isp, chan)->sendmarker = val;   \
691     } else {                                                \
692           SDPARAM(isp, chan)->sendmarker = val;   \
693     }
694 
695 #define   ISP_TST_SENDMARKER(isp, chan)           \
696     (IS_FC(isp)?                                  \
697           FCPARAM(isp, chan)->sendmarker != 0 :   \
698           SDPARAM(isp, chan)->sendmarker != 0)
699 
700 /*
701  * ISP Driver Run States
702  */
703 #define   ISP_NILSTATE        0
704 #define   ISP_CRASHED         1
705 #define   ISP_RESETSTATE      2
706 #define   ISP_INITSTATE       3
707 #define   ISP_RUNSTATE        4
708 
709 /*
710  * ISP Configuration Options
711  */
712 #define   ISP_CFG_NORELOAD    0x80      /* don't download f/w */
713 #define   ISP_CFG_NONVRAM               0x40      /* ignore NVRAM */
714 #define   ISP_CFG_TWOGB                 0x20      /* force 2GB connection (23XX only) */
715 #define   ISP_CFG_ONEGB                 0x10      /* force 1GB connection (23XX only) */
716 #define   ISP_CFG_FULL_DUPLEX 0x01      /* Full Duplex (Fibre Channel only) */
717 #define   ISP_CFG_PORT_PREF   0x0C      /* Mask for Port Prefs (2200 only) */
718 #define   ISP_CFG_LPORT                 0x00      /* prefer {N/F}L-Port connection */
719 #define   ISP_CFG_NPORT                 0x04      /* prefer {N/F}-Port connection */
720 #define   ISP_CFG_NPORT_ONLY  0x08      /* insist on {N/F}-Port connection */
721 #define   ISP_CFG_LPORT_ONLY  0x0C      /* insist on {N/F}L-Port connection */
722 #define   ISP_CFG_OWNFSZ                0x400     /* override NVRAM frame size */
723 #define   ISP_CFG_OWNLOOPID   0x800     /* override NVRAM loopid */
724 #define   ISP_CFG_OWNEXCTHROTTLE        0x1000    /* override NVRAM execution throttle */
725 #define   ISP_CFG_FOURGB                0x2000    /* force 4GB connection (24XX only) */
726 
727 /*
728  * For each channel, the outer layers should know what role that channel
729  * will take: ISP_ROLE_NONE, ISP_ROLE_INITIATOR, ISP_ROLE_TARGET,
730  * ISP_ROLE_BOTH.
731  *
732  * If you set ISP_ROLE_NONE, the cards will be reset, new firmware loaded,
733  * NVRAM read, and defaults set, but any further initialization (e.g.
734  * INITIALIZE CONTROL BLOCK commands for 2X00 cards) won't be done.
735  *
736  * If INITIATOR MODE isn't set, attempts to run commands will be stopped
737  * at isp_start and completed with the equivalent of SELECTION TIMEOUT.
738  *
739  * If TARGET MODE is set, it doesn't mean that the rest of target mode support
740  * needs to be enabled, or will even work. What happens with the 2X00 cards
741  * here is that if you have enabled it with TARGET MODE as part of the ICB
742  * options, but you haven't given the f/w any ram resources for ATIOs or
743  * Immediate Notifies, the f/w just handles what it can and you never see
744  * anything. Basically, it sends a single byte of data (the first byte,
745  * which you can set as part of the INITIALIZE CONTROL BLOCK command) for
746  * INQUIRY, and sends back QUEUE FULL status for any other command.
747  *
748  */
749 #define   ISP_ROLE_NONE                 0x0
750 #define   ISP_ROLE_TARGET               0x1
751 #define   ISP_ROLE_INITIATOR  0x2
752 #define   ISP_ROLE_BOTH                 (ISP_ROLE_TARGET|ISP_ROLE_INITIATOR)
753 #define   ISP_ROLE_EITHER               ISP_ROLE_BOTH
754 #ifndef   ISP_DEFAULT_ROLES
755 #define   ISP_DEFAULT_ROLES   ISP_ROLE_INITIATOR
756 #endif
757 
758 
759 /*
760  * Firmware related defines
761  */
762 #define   ISP_CODE_ORG                            0x1000    /* default f/w code start */
763 #define   ISP_CODE_ORG_2300             0x0800    /* ..except for 2300s */
764 #define   ISP_CODE_ORG_2400             0x100000 /* ..and 2400s */
765 #define   ISP_FW_REV(maj, min, mic)     ((maj << 24) | (min << 16) | mic)
766 #define   ISP_FW_MAJOR(code)            ((code >> 24) & 0xff)
767 #define   ISP_FW_MINOR(code)            ((code >> 16) & 0xff)
768 #define   ISP_FW_MICRO(code)            ((code >>  8) & 0xff)
769 #define   ISP_FW_REVX(xp)                         ((xp[0]<<24) | (xp[1] << 16) | xp[2])
770 #define   ISP_FW_MAJORX(xp)             (xp[0])
771 #define   ISP_FW_MINORX(xp)             (xp[1])
772 #define   ISP_FW_MICROX(xp)             (xp[2])
773 #define   ISP_FW_NEWER_THAN(i, major, minor, micro)                   \
774  (ISP_FW_REVX((i)->isp_fwrev) > ISP_FW_REV(major, minor, micro))
775 #define   ISP_FW_OLDER_THAN(i, major, minor, micro)                   \
776  (ISP_FW_REVX((i)->isp_fwrev) < ISP_FW_REV(major, minor, micro))
777 
778 /*
779  * Bus (implementation) types
780  */
781 #define   ISP_BT_PCI                    0         /* PCI Implementations */
782 #define   ISP_BT_SBUS                   1         /* SBus Implementations */
783 
784 /*
785  * If we have not otherwise defined SBus support away make sure
786  * it is defined here such that the code is included as default
787  */
788 #ifndef   ISP_SBUS_SUPPORTED
789 #define   ISP_SBUS_SUPPORTED  1
790 #endif
791 
792 /*
793  * Chip Types
794  */
795 #define   ISP_HA_SCSI                   0xf
796 #define   ISP_HA_SCSI_UNKNOWN 0x1
797 #define   ISP_HA_SCSI_1020    0x2
798 #define   ISP_HA_SCSI_1020A   0x3
799 #define   ISP_HA_SCSI_1040    0x4
800 #define   ISP_HA_SCSI_1040A   0x5
801 #define   ISP_HA_SCSI_1040B   0x6
802 #define   ISP_HA_SCSI_1040C   0x7
803 #define   ISP_HA_SCSI_1240    0x8
804 #define   ISP_HA_SCSI_1080    0x9
805 #define   ISP_HA_SCSI_1280    0xa
806 #define   ISP_HA_SCSI_10160   0xb
807 #define   ISP_HA_SCSI_12160   0xc
808 #define   ISP_HA_FC           0xf0
809 #define   ISP_HA_FC_2100                0x10
810 #define   ISP_HA_FC_2200                0x20
811 #define   ISP_HA_FC_2300                0x30
812 #define   ISP_HA_FC_2312                0x40
813 #define   ISP_HA_FC_2322                0x50
814 #define   ISP_HA_FC_2400                0x60
815 #define   ISP_HA_FC_2500                0x70
816 
817 #define   IS_SCSI(isp)        (isp->isp_type & ISP_HA_SCSI)
818 #define   IS_1020(isp)        (isp->isp_type < ISP_HA_SCSI_1240)
819 #define   IS_1240(isp)        (isp->isp_type == ISP_HA_SCSI_1240)
820 #define   IS_1080(isp)        (isp->isp_type == ISP_HA_SCSI_1080)
821 #define   IS_1280(isp)        (isp->isp_type == ISP_HA_SCSI_1280)
822 #define   IS_10160(isp)       (isp->isp_type == ISP_HA_SCSI_10160)
823 #define   IS_12160(isp)       (isp->isp_type == ISP_HA_SCSI_12160)
824 
825 #define   IS_12X0(isp)        (IS_1240(isp) || IS_1280(isp))
826 #define   IS_1X160(isp)       (IS_10160(isp) || IS_12160(isp))
827 #define   IS_DUALBUS(isp)     (IS_12X0(isp) || IS_12160(isp))
828 #define   IS_ULTRA2(isp)      (IS_1080(isp) || IS_1280(isp) || IS_1X160(isp))
829 #define   IS_ULTRA3(isp)      (IS_1X160(isp))
830 
831 #define   IS_FC(isp)          ((isp)->isp_type & ISP_HA_FC)
832 #define   IS_2100(isp)        ((isp)->isp_type == ISP_HA_FC_2100)
833 #define   IS_2200(isp)        ((isp)->isp_type == ISP_HA_FC_2200)
834 #define   IS_23XX(isp)        ((isp)->isp_type >= ISP_HA_FC_2300 && \
835                                         (isp)->isp_type < ISP_HA_FC_2400)
836 #define   IS_2300(isp)        ((isp)->isp_type == ISP_HA_FC_2300)
837 #define   IS_2312(isp)        ((isp)->isp_type == ISP_HA_FC_2312)
838 #define   IS_2322(isp)        ((isp)->isp_type == ISP_HA_FC_2322)
839 #define   IS_24XX(isp)        ((isp)->isp_type >= ISP_HA_FC_2400)
840 #define   IS_25XX(isp)        ((isp)->isp_type >= ISP_HA_FC_2500)
841 
842 /*
843  * DMA related macros
844  */
845 #define   DMA_WD3(x)          (((uint16_t)(((uint64_t)x) >> 48)) & 0xffff)
846 #define   DMA_WD2(x)          (((uint16_t)(((uint64_t)x) >> 32)) & 0xffff)
847 #define   DMA_WD1(x)          ((uint16_t)((x) >> 16) & 0xffff)
848 #define   DMA_WD0(x)          ((uint16_t)((x) & 0xffff))
849 
850 #define   DMA_LO32(x)         ((uint32_t) (x))
851 #define   DMA_HI32(x)         ((uint32_t)(((uint64_t)x) >> 32))
852 
853 /*
854  * Core System Function Prototypes
855  */
856 
857 /*
858  * Reset Hardware. Totally. Assumes that you'll follow this with a call to isp_init.
859  */
860 void isp_reset(ispsoftc_t *, int);
861 
862 /*
863  * Initialize Hardware to known state
864  */
865 void isp_init(ispsoftc_t *);
866 
867 /*
868  * Reset the ISP and call completion for any orphaned commands.
869  */
870 void isp_reinit(ispsoftc_t *, int);
871 
872 /*
873  * Internal Interrupt Service Routine
874  *
875  * The outer layers do the spade work to get the appropriate status register,
876  * semaphore register and first mailbox register (if appropriate). This also
877  * means that most spurious/bogus interrupts not for us can be filtered first.
878  */
879 void isp_intr(ispsoftc_t *, uint32_t, uint16_t, uint16_t);
880 
881 
882 /*
883  * Command Entry Point- Platform Dependent layers call into this
884  */
885 int isp_start(XS_T *);
886 
887 /* these values are what isp_start returns */
888 #define   CMD_COMPLETE        101       /* command completed */
889 #define   CMD_EAGAIN          102       /* busy- maybe retry later */
890 #define   CMD_QUEUED          103       /* command has been queued for execution */
891 #define   CMD_RQLATER         104       /* requeue this command later */
892 
893 /*
894  * Command Completion Point- Core layers call out from this with completed cmds
895  */
896 void isp_done(XS_T *);
897 
898 /*
899  * Platform Dependent to External to Internal Control Function
900  *
901  * Assumes locks are held on entry. You should note that with many of
902  * these commands locks may be released while this function is called.
903  *
904  * ... ISPCTL_RESET_BUS, int channel);
905  *        Reset BUS on this channel
906  * ... ISPCTL_RESET_DEV, int channel, int target);
907  *        Reset Device on this channel at this target.
908  * ... ISPCTL_ABORT_CMD, XS_T *xs);
909  *        Abort active transaction described by xs.
910  * ... IPCTL_UPDATE_PARAMS);
911  *        Update any operating parameters (speed, etc.)
912  * ... ISPCTL_FCLINK_TEST, int channel);
913  *        Test FC link status on this channel
914  * ... ISPCTL_SCAN_FABRIC, int channel);
915  *        Scan fabric on this channel
916  * ... ISPCTL_SCAN_LOOP, int channel);
917  *        Scan local loop on this channel
918  * ... ISPCTL_PDB_SYNC, int channel);
919  *        Synchronize port database on this channel
920  * ... ISPCTL_SEND_LIP, int channel);
921  *        Send a LIP on this channel
922  * ... ISPCTL_GET_NAMES, int channel, int np, uint64_t *wwnn, uint64_t *wwpn)
923  *        Get a WWNN/WWPN for this N-port handle on this channel
924  * ... ISPCTL_RUN_MBOXCMD, mbreg_t *mbp)
925  *        Run this mailbox command
926  * ... ISPCTL_GET_PDB, int channel, int nphandle, isp_pdb_t *pdb)
927  *        Get PDB on this channel for this N-port handle
928  * ... ISPCTL_PLOGX, isp_plcmd_t *)
929  *        Performa a port login/logout
930  *
931  * ISPCTL_PDB_SYNC is somewhat misnamed. It actually is the final step, in
932  * order, of ISPCTL_FCLINK_TEST, ISPCTL_SCAN_FABRIC, and ISPCTL_SCAN_LOOP.
933  * The main purpose of ISPCTL_PDB_SYNC is to complete management of logging
934  * and logging out of fabric devices (if one is on a fabric) and then marking
935  * the 'loop state' as being ready to now be used for sending commands to
936  * devices. Originally fabric name server and local loop scanning were
937  * part of this function. It's now been separated to allow for finer control.
938  */
939 typedef enum {
940           ISPCTL_RESET_BUS,
941           ISPCTL_RESET_DEV,
942           ISPCTL_ABORT_CMD,
943           ISPCTL_UPDATE_PARAMS,
944           ISPCTL_FCLINK_TEST,
945           ISPCTL_SCAN_FABRIC,
946           ISPCTL_SCAN_LOOP,
947           ISPCTL_PDB_SYNC,
948           ISPCTL_SEND_LIP,
949           ISPCTL_GET_NAMES,
950           ISPCTL_RUN_MBOXCMD,
951           ISPCTL_GET_PDB,
952           ISPCTL_PLOGX
953 } ispctl_t;
954 int isp_control(ispsoftc_t *, ispctl_t, ...);
955 
956 /*
957  * Platform Dependent to Internal to External Control Function
958  */
959 
960 typedef enum {
961           ISPASYNC_NEW_TGT_PARAMS,      /* SPI New Target Parameters */
962           ISPASYNC_BUS_RESET,           /* All Bus Was Reset */
963           ISPASYNC_LOOP_DOWN,           /* FC Loop Down */
964           ISPASYNC_LOOP_UP,             /* FC Loop Up */
965           ISPASYNC_LIP,                           /* FC LIP Received */
966           ISPASYNC_LOOP_RESET,                    /* FC Loop Reset Received */
967           ISPASYNC_CHANGE_NOTIFY,                 /* FC Change Notification */
968           ISPASYNC_DEV_ARRIVED,                   /* FC Device Arrived */
969           ISPASYNC_DEV_CHANGED,                   /* FC Device Changed */
970           ISPASYNC_DEV_STAYED,                    /* FC Device Stayed */
971           ISPASYNC_DEV_GONE,            /* FC Device Departure */
972           ISPASYNC_TARGET_NOTIFY,                 /* All target async notification */
973           ISPASYNC_TARGET_ACTION,                 /* All target action requested */
974           ISPASYNC_FW_CRASH,            /* All Firmware has crashed */
975           ISPASYNC_FW_RESTARTED                   /* All Firmware has been restarted */
976 } ispasync_t;
977 void isp_async(ispsoftc_t *, ispasync_t, ...);
978 
979 #define   ISPASYNC_CHANGE_PDB 0
980 #define   ISPASYNC_CHANGE_SNS 1
981 #define   ISPASYNC_CHANGE_OTHER         2
982 
983 /*
984  * Platform Dependent Error and Debug Printout
985  *
986  * Two required functions for each platform must be provided:
987  *
988  *    void isp_prt(ispsoftc_t *, int level, const char *, ...)
989  *    void isp_xs_prt(ispsoftc_t *, XS_T *, int level, const char *, ...)
990  *
991  * but due to compiler differences on different platforms this won't be
992  * formally defined here. Instead, they go in each platform definition file.
993  */
994 
995 #define   ISP_LOGALL          0x0       /* log always */
996 #define   ISP_LOGCONFIG       0x1       /* log configuration messages */
997 #define   ISP_LOGINFO         0x2       /* log informational messages */
998 #define   ISP_LOGWARN         0x4       /* log warning messages */
999 #define   ISP_LOGERR          0x8       /* log error messages */
1000 #define   ISP_LOGDEBUG0       0x10      /* log simple debug messages */
1001 #define   ISP_LOGDEBUG1       0x20      /* log intermediate debug messages */
1002 #define   ISP_LOGDEBUG2       0x40      /* log most debug messages */
1003 #define   ISP_LOGDEBUG3       0x80      /* log high frequency debug messages */
1004 #define   ISP_LOGSANCFG       0x100     /* log SAN configuration */
1005 #define   ISP_LOG_CWARN       0x200     /* log SCSI command "warnings" (e.g., check conditions) */
1006 #define   ISP_LOGTINFO        0x1000    /* log informational messages (target mode) */
1007 #define   ISP_LOGTDEBUG0      0x2000    /* log simple debug messages (target mode) */
1008 #define   ISP_LOGTDEBUG1      0x4000    /* log intermediate debug messages (target) */
1009 #define   ISP_LOGTDEBUG2      0x8000    /* log all debug messages (target) */
1010 
1011 /*
1012  * Each Platform provides its own isposinfo substructure of the ispsoftc
1013  * defined above.
1014  *
1015  * Each platform must also provide the following macros/defines:
1016  *
1017  *
1018  *        ISP_FC_SCRLEN                                     FC scratch area DMA length
1019  *
1020  *        ISP_MEMZERO(dst, src)                             platform zeroing function
1021  *        ISP_MEMCPY(dst, src, count)             platform copying function
1022  *        ISP_SNPRINTF(buf, bufsize, fmt, ...)    snprintf
1023  *        ISP_DELAY(usecs)                        microsecond spindelay function
1024  *        ISP_SLEEP(isp, usecs)                             microsecond sleep function
1025  *
1026  *        ISP_INLINE                                        ___inline or not- depending on how
1027  *                                                          good your debugger is
1028  *        ISP_MIN                                           shorthand for ((a) < (b))? (a) : (b)
1029  *
1030  *        NANOTIME_T                                        nanosecond time type
1031  *
1032  *        GET_NANOTIME(NANOTIME_T *)              get current nanotime.
1033  *
1034  *        GET_NANOSEC(NANOTIME_T *)               get uint64_t from NANOTIME_T
1035  *
1036  *        NANOTIME_SUB(NANOTIME_T *, NANOTIME_T *)
1037  *                                                          subtract two NANOTIME_T values
1038  *
1039  *        MAXISPREQUEST(ispsoftc_t *)             maximum request queue size
1040  *                                                          for this particular board type
1041  *
1042  *        MEMORYBARRIER(ispsoftc_t *, barrier_type, offset, size, chan)
1043  *
1044  *                  Function/Macro the provides memory synchronization on
1045  *                  various objects so that the ISP's and the system's view
1046  *                  of the same object is consistent.
1047  *
1048  *        MBOX_ACQUIRE(ispsoftc_t *)              acquire lock on mailbox regs
1049  *        MBOX_WAIT_COMPLETE(ispsoftc_t *, mbreg_t *) wait for cmd to be done
1050  *        MBOX_NOTIFY_COMPLETE(ispsoftc_t *)      notification of mbox cmd donee
1051  *        MBOX_RELEASE(ispsoftc_t *)              release lock on mailbox regs
1052  *
1053  *        FC_SCRATCH_ACQUIRE(ispsoftc_t *, chan)  acquire lock on FC scratch area
1054  *                                                          return -1 if you cannot
1055  *        FC_SCRATCH_RELEASE(ispsoftc_t *, chan)  acquire lock on FC scratch area
1056  *
1057  *        SCSI_GOOD SCSI 'Good' Status
1058  *        SCSI_CHECK          SCSI 'Check Condition' Status
1059  *        SCSI_BUSY SCSI 'Busy' Status
1060  *        SCSI_QFULL          SCSI 'Queue Full' Status
1061  *
1062  *        XS_T                          Platform SCSI transaction type (i.e., command for HBA)
1063  *        XS_DMA_ADDR_T                 Platform PCI DMA Address Type
1064  *        XS_GET_DMA_SEG(..)  Get 32 bit dma segment list value
1065  *        XS_GET_DMA64_SEG(..)          Get 64 bit dma segment list value
1066  *        XS_ISP(xs)                    gets an instance out of an XS_T
1067  *        XS_CHANNEL(xs)                gets the channel (bus # for DUALBUS cards) ""
1068  *        XS_TGT(xs)                    gets the target ""
1069  *        XS_LUN(xs)                    gets the lun ""
1070  *        XS_CDBP(xs)                   gets a pointer to the scsi CDB ""
1071  *        XS_CDBLEN(xs)                 gets the CDB's length ""
1072  *        XS_XFRLEN(xs)                 gets the associated data transfer length ""
1073  *        XS_TIME(xs)                   gets the time (in milliseconds) for this command
1074  *        XS_GET_RESID(xs)    gets the current residual count
1075  *        XS_GET_RESID(xs, resid)       sets the current residual count
1076  *        XS_STSP(xs)                   gets a pointer to the SCSI status byte ""
1077  *        XS_SNSP(xs)                   gets a pointer to the associate sense data
1078  *        XS_SNSLEN(xs)                 gets the length of sense data storage
1079  *        XS_SNSKEY(xs)                 dereferences XS_SNSP to get the current stored Sense Key
1080  *        XS_SNSASC(xs)                 dereferences XS_SNSP to get the current stored Additional Sense Code
1081  *        XS_SNSASCQ(xs)                dereferences XS_SNSP to get the current stored Additional Sense Code Qualifier
1082  *        XS_TAG_P(xs)                  predicate of whether this command should be tagged
1083  *        XS_TAG_TYPE(xs)               which type of tag to use
1084  *        XS_SETERR(xs)                 set error state
1085  *
1086  *                  HBA_NOERROR         command has no erros
1087  *                  HBA_BOTCH hba botched something
1088  *                  HBA_CMDTIMEOUT      command timed out
1089  *                  HBA_SELTIMEOUT      selection timed out (also port logouts for FC)
1090  *                  HBA_TGTBSY          target returned a BUSY status
1091  *                  HBA_BUSRESET        bus reset destroyed command
1092  *                  HBA_ABORTED         command was aborted (by request)
1093  *                  HBA_DATAOVR         a data overrun was detected
1094  *                  HBA_ARQFAIL         Automatic Request Sense failed
1095  *
1096  *        XS_ERR(xs)          return current error state
1097  *        XS_NOERR(xs)        there is no error currently set
1098  *        XS_INITERR(xs)      initialize error state
1099  *
1100  *        XS_SAVE_SENSE(xs, sp, len)    save sense data
1101  *
1102  *        XS_SENSE_VALID(xs)            indicates whether sense is valid
1103  *
1104  *        DEFAULT_FRAMESIZE(ispsoftc_t *)                   Default Frame Size
1105  *        DEFAULT_EXEC_THROTTLE(ispsoftc_t *)     Default Execution Throttle
1106  *
1107  *        GET_DEFAULT_ROLE(ispsoftc_t *, int)     Get Default Role for a channel
1108  *        SET_DEFAULT_ROLE(ispsoftc_t *, int, int) Set Default Role for a channel
1109  *        DEFAULT_IID(ispsoftc_t *, int)                    Default SCSI initiator ID
1110  *        DEFAULT_LOOPID(ispsoftc_t *, int)       Default FC Loop ID
1111  *
1112  *                  These establish reasonable defaults for each platform.
1113  *                  These must be available independent of card NVRAM and are
1114  *                  to be used should NVRAM not be readable.
1115  *
1116  *        DEFAULT_NODEWWN(ispsoftc_t *, chan)     Default FC Node WWN to use
1117  *        DEFAULT_PORTWWN(ispsoftc_t *, chan)     Default FC Port WWN to use
1118  *
1119  *                  These defines are hooks to allow the setting of node and
1120  *                  port WWNs when NVRAM cannot be read or is to be overridden.
1121  *
1122  *        ACTIVE_NODEWWN(ispsoftc_t *, chan)      FC Node WWN to use
1123  *        ACTIVE_PORTWWN(ispsoftc_t *, chan)      FC Port WWN to use
1124  *
1125  *                  After NVRAM is read, these will be invoked to get the
1126  *                  node and port WWNs that will actually be used for this
1127  *                  channel.
1128  *
1129  *
1130  *        ISP_IOXPUT_8(ispsoftc_t *, uint8_t srcval, uint8_t *dstptr)
1131  *        ISP_IOXPUT_16(ispsoftc_t *, uint16_t srcval, uint16_t *dstptr)
1132  *        ISP_IOXPUT_32(ispsoftc_t *, uint32_t srcval, uint32_t *dstptr)
1133  *
1134  *        ISP_IOXGET_8(ispsoftc_t *, uint8_t *srcptr, uint8_t dstrval)
1135  *        ISP_IOXGET_16(ispsoftc_t *, uint16_t *srcptr, uint16_t dstrval)
1136  *        ISP_IOXGET_32(ispsoftc_t *, uint32_t *srcptr, uint32_t dstrval)
1137  *
1138  *        ISP_SWIZZLE_NVRAM_WORD(ispsoftc_t *, uint16_t *)
1139  *        ISP_SWIZZLE_NVRAM_LONG(ispsoftc_t *, uint32_t *)
1140  *        ISP_SWAP16(ispsoftc_t *, uint16_t srcval)
1141  *        ISP_SWAP32(ispsoftc_t *, uint32_t srcval)
1142  */
1143 
1144 #ifdef    ISP_TARGET_MODE
1145 /*
1146  * The functions below are for the publicly available
1147  * target mode functions that are internal to the Qlogic driver.
1148  */
1149 
1150 /*
1151  * This function handles new response queue entry appropriate for target mode.
1152  */
1153 int isp_target_notify(ispsoftc_t *, void *, uint32_t *);
1154 
1155 /*
1156  * This function externalizes the ability to acknowledge an Immediate Notify request.
1157  */
1158 int isp_notify_ack(ispsoftc_t *, void *);
1159 
1160 /*
1161  * This function externalized acknowledging (success/fail) an ABTS frame
1162  */
1163 int isp_acknak_abts(ispsoftc_t *, void *, int);
1164 
1165 /*
1166  * Enable/Disable/Modify a logical unit.
1167  * (softc, cmd, bus, tgt, lun, cmd_cnt, inotify_cnt)
1168  */
1169 #define   DFLT_CMND_CNT       0xfe      /* unmonitored */
1170 #define   DFLT_INOT_CNT       0xfe      /* unmonitored */
1171 int isp_lun_cmd(ispsoftc_t *, int, int, int, int, int);
1172 
1173 /*
1174  * General request queue 'put' routine for target mode entries.
1175  */
1176 int isp_target_put_entry(ispsoftc_t *isp, void *);
1177 
1178 /*
1179  * General routine to put back an ATIO entry-
1180  * used for replenishing f/w resource counts.
1181  * The argument is a pointer to a source ATIO
1182  * or ATIO2.
1183  */
1184 int isp_target_put_atio(ispsoftc_t *, void *);
1185 
1186 /*
1187  * General routine to send a final CTIO for a command- used mostly for
1188  * local responses.
1189  */
1190 int isp_endcmd(ispsoftc_t *, ...);
1191 #define   ECMD_SVALID         0x100
1192 #define   ECMD_TERMINATE      0x200
1193 
1194 /*
1195  * Handle an asynchronous event
1196  *
1197  * Return nonzero if the interrupt that generated this event has been dismissed.
1198  */
1199 int isp_target_async(ispsoftc_t *, int, int);
1200 #endif
1201 #endif    /* _ISPVAR_H */
1202