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