]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - sys/dev/isp/isp.c
Pick up some changes the the MFC missed.
[FreeBSD/stable/8.git] / sys / dev / isp / isp.c
1 /*-
2  *  Copyright (c) 1997-2009 by Matthew Jacob
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions
7  *  are met:
8  *
9  *  1. Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  *  2. Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  *  THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  *  ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  *  SUCH DAMAGE.
26  *
27  */
28
29 /*
30  * Machine and OS Independent (well, as best as possible)
31  * code for the Qlogic ISP SCSI and FC-SCSI adapters.
32  */
33
34 /*
35  * Inspiration and ideas about this driver are from Erik Moe's Linux driver
36  * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
37  * ideas dredged from the Solaris driver.
38  */
39
40 /*
41  * Include header file appropriate for platform we're building on.
42  */
43 #ifdef  __NetBSD__
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD$");
46 #include <dev/ic/isp_netbsd.h>
47 #endif
48 #ifdef  __FreeBSD__
49 #include <sys/cdefs.h>
50 __FBSDID("$FreeBSD$");
51 #include <dev/isp/isp_freebsd.h>
52 #endif
53 #ifdef  __OpenBSD__
54 #include <dev/ic/isp_openbsd.h>
55 #endif
56 #ifdef  __linux__
57 #include "isp_linux.h"
58 #endif
59 #ifdef  __svr4__
60 #include "isp_solaris.h"
61 #endif
62
63 /*
64  * General defines
65  */
66 #define MBOX_DELAY_COUNT        1000000 / 100
67 #define ISP_MARK_PORTDB(a, b, c)                                \
68     isp_prt(isp, ISP_LOGSANCFG,                                 \
69         "Chan %d ISP_MARK_PORTDB@LINE %d", b, __LINE__);        \
70     isp_mark_portdb(a, b, c)
71
72 /*
73  * Local static data
74  */
75 static const char fconf[] = "Chan %d PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)\n database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)";
76 static const char notresp[] = "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
77 static const char xact1[] = "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
78 static const char xact2[] = "HBA attempted queued transaction to target routine %d on target %d bus %d";
79 static const char xact3[] = "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
80 static const char pskip[] = "SCSI phase skipped for target %d.%d.%d";
81 static const char topology[] = "Chan %d WWPN 0x%08x%08x PortID 0x%06x N-Port Handle %d, Connection '%s'";
82 static const char finmsg[] = "%d.%d.%d: FIN dl%d resid %ld STS 0x%x SKEY %c XS_ERR=0x%x";
83 static const char sc4[] = "NVRAM";
84 static const char bun[] = "bad underrun for %d.%d (count %d, resid %d, status %s)";
85 static const char lipd[] = "Chan %d LIP destroyed %d active commands";
86 static const char sacq[] = "unable to acquire scratch area";
87
88 static const uint8_t alpa_map[] = {
89         0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda,
90         0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce,
91         0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5,
92         0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3,
93         0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
94         0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b,
95         0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81,
96         0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73,
97         0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69,
98         0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
99         0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c,
100         0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c,
101         0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
102         0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26,
103         0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
104         0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00
105 };
106
107 /*
108  * Local function prototypes.
109  */
110 static int isp_parse_async(ispsoftc_t *, uint16_t);
111 static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *);
112 static void isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *); static void
113 isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *);
114 static void isp_fastpost_complete(ispsoftc_t *, uint16_t);
115 static int isp_mbox_continue(ispsoftc_t *);
116 static void isp_scsi_init(ispsoftc_t *);
117 static void isp_scsi_channel_init(ispsoftc_t *, int);
118 static void isp_fibre_init(ispsoftc_t *);
119 static void isp_fibre_init_2400(ispsoftc_t *);
120 static void isp_mark_portdb(ispsoftc_t *, int, int);
121 static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int, int);
122 static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t);
123 static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t);
124 static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *, int);
125 static void isp_dump_chip_portdb(ispsoftc_t *, int, int);
126 static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
127 static int isp_fclink_test(ispsoftc_t *, int, int);
128 static int isp_pdb_sync(ispsoftc_t *, int);
129 static int isp_scan_loop(ispsoftc_t *, int);
130 static int isp_gid_ft_sns(ispsoftc_t *, int);
131 static int isp_gid_ft_ct_passthru(ispsoftc_t *, int);
132 static int isp_scan_fabric(ispsoftc_t *, int);
133 static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *);
134 static int isp_register_fc4_type(ispsoftc_t *, int);
135 static int isp_register_fc4_type_24xx(ispsoftc_t *, int);
136 static uint16_t isp_nxt_handle(ispsoftc_t *, int, uint16_t);
137 static void isp_fw_state(ispsoftc_t *, int);
138 static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int);
139 static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
140
141 static void isp_spi_update(ispsoftc_t *, int);
142 static void isp_setdfltsdparm(ispsoftc_t *);
143 static void isp_setdfltfcparm(ispsoftc_t *, int);
144 static int isp_read_nvram(ispsoftc_t *, int);
145 static int isp_read_nvram_2400(ispsoftc_t *, uint8_t *);
146 static void isp_rdnvram_word(ispsoftc_t *, int, uint16_t *);
147 static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *);
148 static void isp_parse_nvram_1020(ispsoftc_t *, uint8_t *);
149 static void isp_parse_nvram_1080(ispsoftc_t *, int, uint8_t *);
150 static void isp_parse_nvram_12160(ispsoftc_t *, int, uint8_t *);
151 static void isp_parse_nvram_2100(ispsoftc_t *, uint8_t *);
152 static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
153
154 /*
155  * Reset Hardware.
156  *
157  * Hit the chip over the head, download new f/w if available and set it running.
158  *
159  * Locking done elsewhere.
160  */
161
162 void
163 isp_reset(ispsoftc_t *isp, int do_load_defaults)
164 {
165         mbreg_t mbs;
166         uint32_t code_org, val;
167         int loops, i, dodnld = 1;
168         const char *btype = "????";
169         static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
170
171         isp->isp_state = ISP_NILSTATE;
172         if (isp->isp_dead) {
173                 isp_shutdown(isp);
174                 ISP_DISABLE_INTS(isp);
175                 return;
176         }
177
178         /*
179          * Basic types (SCSI, FibreChannel and PCI or SBus)
180          * have been set in the MD code. We figure out more
181          * here. Possibly more refined types based upon PCI
182          * identification. Chip revision has been gathered.
183          *
184          * After we've fired this chip up, zero out the conf1 register
185          * for SCSI adapters and do other settings for the 2100.
186          */
187
188         ISP_DISABLE_INTS(isp);
189
190         /*
191          * Pick an initial maxcmds value which will be used
192          * to allocate xflist pointer space. It may be changed
193          * later by the firmware.
194          */
195         if (IS_24XX(isp)) {
196                 isp->isp_maxcmds = 4096;
197         } else if (IS_2322(isp)) {
198                 isp->isp_maxcmds = 2048;
199         } else if (IS_23XX(isp) || IS_2200(isp)) {
200                 isp->isp_maxcmds = 1024;
201         } else {
202                 isp->isp_maxcmds = 512;
203         }
204
205         /*
206          * Set up DMA for the request and response queues.
207          *
208          * We do this now so we can use the request queue
209          * for dma to load firmware from.
210          */
211         if (ISP_MBOXDMASETUP(isp) != 0) {
212                 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
213                 return;
214         }
215
216         /*
217          * Set up default request/response queue in-pointer/out-pointer
218          * register indices.
219          */
220         if (IS_24XX(isp)) {
221                 isp->isp_rqstinrp = BIU2400_REQINP;
222                 isp->isp_rqstoutrp = BIU2400_REQOUTP;
223                 isp->isp_respinrp = BIU2400_RSPINP;
224                 isp->isp_respoutrp = BIU2400_RSPOUTP;
225         } else if (IS_23XX(isp)) {
226                 isp->isp_rqstinrp = BIU_REQINP;
227                 isp->isp_rqstoutrp = BIU_REQOUTP;
228                 isp->isp_respinrp = BIU_RSPINP;
229                 isp->isp_respoutrp = BIU_RSPOUTP;
230         } else {
231                 isp->isp_rqstinrp = INMAILBOX4;
232                 isp->isp_rqstoutrp = OUTMAILBOX4;
233                 isp->isp_respinrp = OUTMAILBOX5;
234                 isp->isp_respoutrp = INMAILBOX5;
235         }
236
237         /*
238          * Put the board into PAUSE mode (so we can read the SXP registers
239          * or write FPM/FBM registers).
240          */
241         if (IS_24XX(isp)) {
242                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT);
243                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
244                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
245         } else {
246                 ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
247         }
248
249         if (IS_FC(isp)) {
250                 switch (isp->isp_type) {
251                 case ISP_HA_FC_2100:
252                         btype = "2100";
253                         break;
254                 case ISP_HA_FC_2200:
255                         btype = "2200";
256                         break;
257                 case ISP_HA_FC_2300:
258                         btype = "2300";
259                         break;
260                 case ISP_HA_FC_2312:
261                         btype = "2312";
262                         break;
263                 case ISP_HA_FC_2322:
264                         btype = "2322";
265                         break;
266                 case ISP_HA_FC_2400:
267                         btype = "2422";
268                         break;
269                 case ISP_HA_FC_2500:
270                         btype = "2532";
271                         break;
272                 default:
273                         break;
274                 }
275
276                 if (!IS_24XX(isp)) {
277                         /*
278                          * While we're paused, reset the FPM module and FBM
279                          * fifos.
280                          */
281                         ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
282                         ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
283                         ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
284                         ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
285                         ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
286                 }
287         } else if (IS_1240(isp)) {
288                 sdparam *sdp;
289
290                 btype = "1240";
291                 isp->isp_clock = 60;
292                 sdp = SDPARAM(isp, 0);
293                 sdp->isp_ultramode = 1;
294                 sdp = SDPARAM(isp, 1);
295                 sdp->isp_ultramode = 1;
296                 /*
297                  * XXX: Should probably do some bus sensing.
298                  */
299         } else if (IS_ULTRA3(isp)) {
300                 sdparam *sdp = isp->isp_param;
301
302                 isp->isp_clock = 100;
303
304                 if (IS_10160(isp))
305                         btype = "10160";
306                 else if (IS_12160(isp))
307                         btype = "12160";
308                 else
309                         btype = "<UNKLVD>";
310                 sdp->isp_lvdmode = 1;
311
312                 if (IS_DUALBUS(isp)) {
313                         sdp++;
314                         sdp->isp_lvdmode = 1;
315                 }
316         } else if (IS_ULTRA2(isp)) {
317                 static const char m[] = "bus %d is in %s Mode";
318                 uint16_t l;
319                 sdparam *sdp = SDPARAM(isp, 0);
320
321                 isp->isp_clock = 100;
322
323                 if (IS_1280(isp))
324                         btype = "1280";
325                 else if (IS_1080(isp))
326                         btype = "1080";
327                 else
328                         btype = "<UNKLVD>";
329
330                 l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
331                 switch (l) {
332                 case ISP1080_LVD_MODE:
333                         sdp->isp_lvdmode = 1;
334                         isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
335                         break;
336                 case ISP1080_HVD_MODE:
337                         sdp->isp_diffmode = 1;
338                         isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
339                         break;
340                 case ISP1080_SE_MODE:
341                         sdp->isp_ultramode = 1;
342                         isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
343                         break;
344                 default:
345                         isp_prt(isp, ISP_LOGERR,
346                             "unknown mode on bus %d (0x%x)", 0, l);
347                         break;
348                 }
349
350                 if (IS_DUALBUS(isp)) {
351                         sdp = SDPARAM(isp, 1);
352                         l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
353                         l &= ISP1080_MODE_MASK;
354                         switch (l) {
355                         case ISP1080_LVD_MODE:
356                                 sdp->isp_lvdmode = 1;
357                                 isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
358                                 break;
359                         case ISP1080_HVD_MODE:
360                                 sdp->isp_diffmode = 1;
361                                 isp_prt(isp, ISP_LOGCONFIG,
362                                     m, 1, "Differential");
363                                 break;
364                         case ISP1080_SE_MODE:
365                                 sdp->isp_ultramode = 1;
366                                 isp_prt(isp, ISP_LOGCONFIG,
367                                     m, 1, "Single-Ended");
368                                 break;
369                         default:
370                                 isp_prt(isp, ISP_LOGERR,
371                                     "unknown mode on bus %d (0x%x)", 1, l);
372                                 break;
373                         }
374                 }
375         } else {
376                 sdparam *sdp = SDPARAM(isp, 0);
377                 i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
378                 switch (i) {
379                 default:
380                         isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
381                         /* FALLTHROUGH */
382                 case 1:
383                         btype = "1020";
384                         isp->isp_type = ISP_HA_SCSI_1020;
385                         isp->isp_clock = 40;
386                         break;
387                 case 2:
388                         /*
389                          * Some 1020A chips are Ultra Capable, but don't
390                          * run the clock rate up for that unless told to
391                          * do so by the Ultra Capable bits being set.
392                          */
393                         btype = "1020A";
394                         isp->isp_type = ISP_HA_SCSI_1020A;
395                         isp->isp_clock = 40;
396                         break;
397                 case 3:
398                         btype = "1040";
399                         isp->isp_type = ISP_HA_SCSI_1040;
400                         isp->isp_clock = 60;
401                         break;
402                 case 4:
403                         btype = "1040A";
404                         isp->isp_type = ISP_HA_SCSI_1040A;
405                         isp->isp_clock = 60;
406                         break;
407                 case 5:
408                         btype = "1040B";
409                         isp->isp_type = ISP_HA_SCSI_1040B;
410                         isp->isp_clock = 60;
411                         break;
412                 case 6:
413                         btype = "1040C";
414                         isp->isp_type = ISP_HA_SCSI_1040C;
415                         isp->isp_clock = 60;
416                         break;
417                 }
418                 /*
419                  * Now, while we're at it, gather info about ultra
420                  * and/or differential mode.
421                  */
422                 if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
423                         isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
424                         sdp->isp_diffmode = 1;
425                 } else {
426                         sdp->isp_diffmode = 0;
427                 }
428                 i = ISP_READ(isp, RISC_PSR);
429                 if (isp->isp_bustype == ISP_BT_SBUS) {
430                         i &= RISC_PSR_SBUS_ULTRA;
431                 } else {
432                         i &= RISC_PSR_PCI_ULTRA;
433                 }
434                 if (i != 0) {
435                         isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
436                         sdp->isp_ultramode = 1;
437                         /*
438                          * If we're in Ultra Mode, we have to be 60MHz clock-
439                          * even for the SBus version.
440                          */
441                         isp->isp_clock = 60;
442                 } else {
443                         sdp->isp_ultramode = 0;
444                         /*
445                          * Clock is known. Gronk.
446                          */
447                 }
448
449                 /*
450                  * Machine dependent clock (if set) overrides
451                  * our generic determinations.
452                  */
453                 if (isp->isp_mdvec->dv_clock) {
454                         if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
455                                 isp->isp_clock = isp->isp_mdvec->dv_clock;
456                         }
457                 }
458
459         }
460
461         /*
462          * Clear instrumentation
463          */
464         isp->isp_intcnt = isp->isp_intbogus = 0;
465
466         /*
467          * Do MD specific pre initialization
468          */
469         ISP_RESET0(isp);
470
471         /*
472          * Hit the chip over the head with hammer,
473          * and give it a chance to recover.
474          */
475
476         if (IS_SCSI(isp)) {
477                 ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
478                 /*
479                  * A slight delay...
480                  */
481                 ISP_DELAY(100);
482
483                 /*
484                  * Clear data && control DMA engines.
485                  */
486                 ISP_WRITE(isp, CDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
487                 ISP_WRITE(isp, DDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
488
489
490         } else if (IS_24XX(isp)) {
491                 /*
492                  * Stop DMA and wait for it to stop.
493                  */
494                 ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
495                 for (val = loops = 0; loops < 30000; loops++) {
496                         ISP_DELAY(10);
497                         val = ISP_READ(isp, BIU2400_CSR);
498                         if ((val & BIU2400_DMA_ACTIVE) == 0) {
499                                 break;
500                         }
501                 }
502                 if (val & BIU2400_DMA_ACTIVE) {
503                         ISP_RESET0(isp);
504                         isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
505                         return;
506                 }
507                 /*
508                  * Hold it in SOFT_RESET and STOP state for 100us.
509                  */
510                 ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
511                 ISP_DELAY(100);
512                 for (loops = 0; loops < 10000; loops++) {
513                         ISP_DELAY(5);
514                         val = ISP_READ(isp, OUTMAILBOX0);
515                 }
516                 for (val = loops = 0; loops < 500000; loops ++) {
517                         val = ISP_READ(isp, BIU2400_CSR);
518                         if ((val & BIU2400_SOFT_RESET) == 0) {
519                                 break;
520                         }
521                 }
522                 if (val & BIU2400_SOFT_RESET) {
523                         ISP_RESET0(isp);
524                         isp_prt(isp, ISP_LOGERR, "Failed to come out of reset");
525                         return;
526                 }
527         } else {
528                 ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
529                 /*
530                  * A slight delay...
531                  */
532                 ISP_DELAY(100);
533
534                 /*
535                  * Clear data && control DMA engines.
536                  */
537                 ISP_WRITE(isp, CDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
538                 ISP_WRITE(isp, TDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
539                 ISP_WRITE(isp, RDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
540         }
541
542         /*
543          * Wait for ISP to be ready to go...
544          */
545         loops = MBOX_DELAY_COUNT;
546         for (;;) {
547                 if (IS_SCSI(isp)) {
548                         if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET)) {
549                                 break;
550                         }
551                 } else if (IS_24XX(isp)) {
552                         if (ISP_READ(isp, OUTMAILBOX0) == 0) {
553                                 break;
554                         }
555                 } else {
556                         if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
557                                 break;
558                 }
559                 ISP_DELAY(100);
560                 if (--loops < 0) {
561                         ISP_DUMPREGS(isp, "chip reset timed out");
562                         ISP_RESET0(isp);
563                         return;
564                 }
565         }
566
567         /*
568          * After we've fired this chip up, zero out the conf1 register
569          * for SCSI adapters and other settings for the 2100.
570          */
571
572         if (IS_SCSI(isp)) {
573                 ISP_WRITE(isp, BIU_CONF1, 0);
574         } else if (!IS_24XX(isp)) {
575                 ISP_WRITE(isp, BIU2100_CSR, 0);
576         }
577
578         /*
579          * Reset RISC Processor
580          */
581         if (IS_24XX(isp)) {
582                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
583                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
584                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
585         } else {
586                 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
587                 ISP_DELAY(100);
588                 ISP_WRITE(isp, BIU_SEMA, 0);
589         }
590
591         /*
592          * Post-RISC Reset stuff.
593          */
594         if (IS_24XX(isp)) {
595                 for (val = loops = 0; loops < 5000000; loops++) {
596                         ISP_DELAY(5);
597                         val = ISP_READ(isp, OUTMAILBOX0);
598                         if (val == 0) {
599                                 break;
600                         }
601                 }
602                 if (val != 0) {
603                         ISP_RESET0(isp);
604                         isp_prt(isp, ISP_LOGERR, "reset didn't clear");
605                         return;
606                 }
607         } else if (IS_SCSI(isp)) {
608                 uint16_t tmp = isp->isp_mdvec->dv_conf1;
609                 /*
610                  * Busted FIFO. Turn off all but burst enables.
611                  */
612                 if (isp->isp_type == ISP_HA_SCSI_1040A) {
613                         tmp &= BIU_BURST_ENABLE;
614                 }
615                 ISP_SETBITS(isp, BIU_CONF1, tmp);
616                 if (tmp & BIU_BURST_ENABLE) {
617                         ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
618                         ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
619                 }
620                 if (SDPARAM(isp, 0)->isp_ptisp) {
621                         if (SDPARAM(isp, 0)->isp_ultramode) {
622                                 while (ISP_READ(isp, RISC_MTR) != 0x1313) {
623                                         ISP_WRITE(isp, RISC_MTR, 0x1313);
624                                         ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
625                                 }
626                         } else {
627                                 ISP_WRITE(isp, RISC_MTR, 0x1212);
628                         }
629                         /*
630                          * PTI specific register
631                          */
632                         ISP_WRITE(isp, RISC_EMB, DUAL_BANK);
633                 } else {
634                         ISP_WRITE(isp, RISC_MTR, 0x1212);
635                 }
636                 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
637         } else {
638                 ISP_WRITE(isp, RISC_MTR2100, 0x1212);
639                 if (IS_2200(isp) || IS_23XX(isp)) {
640                         ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
641                 }
642                 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
643         }
644
645         ISP_WRITE(isp, isp->isp_rqstinrp, 0);
646         ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
647         ISP_WRITE(isp, isp->isp_respinrp, 0);
648         ISP_WRITE(isp, isp->isp_respoutrp, 0);
649         if (IS_24XX(isp)) {
650                 ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
651                 ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
652                 ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
653                 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
654         }
655
656         /*
657          * Do MD specific post initialization
658          */
659         ISP_RESET1(isp);
660
661         /*
662          * Wait for everything to finish firing up.
663          *
664          * Avoid doing this on early 2312s because you can generate a PCI
665          * parity error (chip breakage).
666          */
667         if (IS_2312(isp) && isp->isp_revision < 2) {
668                 ISP_DELAY(100);
669         } else {
670                 loops = MBOX_DELAY_COUNT;
671                 while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
672                         ISP_DELAY(100);
673                         if (--loops < 0) {
674                                 ISP_RESET0(isp);
675                                 isp_prt(isp, ISP_LOGERR,
676                                     "MBOX_BUSY never cleared on reset");
677                                 return;
678                         }
679                 }
680         }
681
682         /*
683          * Up until this point we've done everything by just reading or
684          * setting registers. From this point on we rely on at least *some*
685          * kind of firmware running in the card.
686          */
687
688         /*
689          * Do some sanity checking by running a NOP command.
690          * If it succeeds, the ROM firmware is now running.
691          */
692         ISP_MEMZERO(&mbs, sizeof (mbs));
693         mbs.param[0] = MBOX_NO_OP;
694         mbs.logval = MBLOGALL;
695         isp_mboxcmd(isp, &mbs);
696         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
697                 isp_prt(isp, ISP_LOGERR, "NOP command failed (%x)", mbs.param[0]);
698                 ISP_RESET0(isp);
699                 return;
700         }
701
702         /*
703          * Do some operational tests
704          */
705
706         if (IS_SCSI(isp) || IS_24XX(isp)) {
707                 ISP_MEMZERO(&mbs, sizeof (mbs));
708                 mbs.param[0] = MBOX_MAILBOX_REG_TEST;
709                 mbs.param[1] = 0xdead;
710                 mbs.param[2] = 0xbeef;
711                 mbs.param[3] = 0xffff;
712                 mbs.param[4] = 0x1111;
713                 mbs.param[5] = 0xa5a5;
714                 mbs.param[6] = 0x0000;
715                 mbs.param[7] = 0x0000;
716                 mbs.logval = MBLOGALL;
717                 isp_mboxcmd(isp, &mbs);
718                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
719                         ISP_RESET0(isp);
720                         return;
721                 }
722                 if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
723                     mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
724                     mbs.param[5] != 0xa5a5) {
725                         ISP_RESET0(isp);
726                         isp_prt(isp, ISP_LOGERR, "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)", mbs.param[1], mbs.param[2], mbs.param[3], mbs.param[4], mbs.param[5]);
727                         return;
728                 }
729
730         }
731
732         /*
733          * Download new Firmware, unless requested not to do so.
734          * This is made slightly trickier in some cases where the
735          * firmware of the ROM revision is newer than the revision
736          * compiled into the driver. So, where we used to compare
737          * versions of our f/w and the ROM f/w, now we just see
738          * whether we have f/w at all and whether a config flag
739          * has disabled our download.
740          */
741         if ((isp->isp_mdvec->dv_ispfw == NULL) || (isp->isp_confopts & ISP_CFG_NORELOAD)) {
742                 dodnld = 0;
743         }
744
745         if (IS_24XX(isp)) {
746                 code_org = ISP_CODE_ORG_2400;
747         } else if (IS_23XX(isp)) {
748                 code_org = ISP_CODE_ORG_2300;
749         } else {
750                 code_org = ISP_CODE_ORG;
751         }
752
753         if (dodnld && IS_24XX(isp)) {
754                 const uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
755
756                 /*
757                  * Keep loading until we run out of f/w.
758                  */
759                 code_org = ptr[2];      /* 1st load address is our start addr */
760
761                 for (;;) {
762                         uint32_t la, wi, wl;
763
764                         isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], ptr[2]);
765
766                         wi = 0;
767                         la = ptr[2];
768                         wl = ptr[3];
769
770                         while (wi < ptr[3]) {
771                                 uint32_t *cp;
772                                 uint32_t nw;
773
774                                 nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 2;
775                                 if (nw > wl) {
776                                         nw = wl;
777                                 }
778                                 cp = isp->isp_rquest;
779                                 for (i = 0; i < nw; i++) {
780                                         ISP_IOXPUT_32(isp,  ptr[wi++], &cp[i]);
781                                         wl--;
782                                 }
783                                 MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
784                                 ISP_MEMZERO(&mbs, sizeof (mbs));
785                                 if (la < 0x10000 && nw < 0x10000) {
786                                         mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
787                                         mbs.param[1] = la;
788                                         mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
789                                         mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
790                                         mbs.param[4] = nw;
791                                         mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
792                                         mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
793                                 } else {
794                                         mbs.param[0] = MBOX_LOAD_RISC_RAM;
795                                         mbs.param[1] = la;
796                                         mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
797                                         mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
798                                         mbs.param[4] = nw >> 16;
799                                         mbs.param[5] = nw;
800                                         mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
801                                         mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
802                                         mbs.param[8] = la >> 16;
803                                 }
804                                 mbs.logval = MBLOGALL;
805                                 isp_mboxcmd(isp, &mbs);
806                                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
807                                         isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
808                                         ISP_RESET0(isp);
809                                         return;
810                                 }
811                                 la += nw;
812                         }
813
814                         if (ptr[1] == 0) {
815                                 break;
816                         }
817                         ptr += ptr[3];
818                 }
819                 isp->isp_loaded_fw = 1;
820         } else if (dodnld && IS_23XX(isp)) {
821                 const uint16_t *ptr = isp->isp_mdvec->dv_ispfw;
822                 uint16_t wi, wl, segno;
823                 uint32_t la;
824
825                 la = code_org;
826                 segno = 0;
827
828                 for (;;) {
829                         uint32_t nxtaddr;
830
831                         isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], la);
832
833                         wi = 0;
834                         wl = ptr[3];
835
836                         while (wi < ptr[3]) {
837                                 uint16_t *cp;
838                                 uint16_t nw;
839
840                                 nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 1;
841                                 if (nw > wl) {
842                                         nw = wl;
843                                 }
844                                 if (nw > (1 << 15)) {
845                                         nw = 1 << 15;
846                                 }
847                                 cp = isp->isp_rquest;
848                                 for (i = 0; i < nw; i++) {
849                                         ISP_IOXPUT_16(isp,  ptr[wi++], &cp[i]);
850                                         wl--;
851                                 }
852                                 MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
853                                 ISP_MEMZERO(&mbs, sizeof (mbs));
854                                 if (la < 0x10000) {
855                                         mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
856                                         mbs.param[1] = la;
857                                         mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
858                                         mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
859                                         mbs.param[4] = nw;
860                                         mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
861                                         mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
862                                 } else {
863                                         mbs.param[0] = MBOX_LOAD_RISC_RAM;
864                                         mbs.param[1] = la;
865                                         mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
866                                         mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
867                                         mbs.param[4] = nw;
868                                         mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
869                                         mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
870                                         mbs.param[8] = la >> 16;
871                                 }
872                                 mbs.logval = MBLOGALL;
873                                 isp_mboxcmd(isp, &mbs);
874                                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
875                                         isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
876                                         ISP_RESET0(isp);
877                                         return;
878                                 }
879                                 la += nw;
880                         }
881
882                         if (!IS_2322(isp)) {
883                                 break;
884                         }
885
886                         if (++segno == 3) {
887                                 break;
888                         }
889
890                         /*
891                          * If we're a 2322, the firmware actually comes in
892                          * three chunks. We loaded the first at the code_org
893                          * address. The other two chunks, which follow right
894                          * after each other in memory here, get loaded at
895                          * addresses specfied at offset 0x9..0xB.
896                          */
897
898                         nxtaddr = ptr[3];
899                         ptr = &ptr[nxtaddr];
900                         la = ptr[5] | ((ptr[4] & 0x3f) << 16);
901                 }
902                 isp->isp_loaded_fw = 1;
903         } else if (dodnld) {
904                 union {
905                         const uint16_t *cp;
906                         uint16_t *np;
907                 } ucd;
908                 ucd.cp = isp->isp_mdvec->dv_ispfw;
909                 isp->isp_mbxworkp = &ucd.np[1];
910                 isp->isp_mbxwrk0 = ucd.np[3] - 1;
911                 isp->isp_mbxwrk1 = code_org + 1;
912                 ISP_MEMZERO(&mbs, sizeof (mbs));
913                 mbs.param[0] = MBOX_WRITE_RAM_WORD;
914                 mbs.param[1] = code_org;
915                 mbs.param[2] = ucd.np[0];
916                 mbs.logval = MBLOGNONE;
917                 isp_mboxcmd(isp, &mbs);
918                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
919                         isp_prt(isp, ISP_LOGERR, "F/W download failed at word %d", isp->isp_mbxwrk1 - code_org);
920                         ISP_RESET0(isp);
921                         return;
922                 }
923         } else {
924                 isp->isp_loaded_fw = 0;
925                 isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
926         }
927
928         /*
929          * If we loaded firmware, verify its checksum
930          */
931         if (isp->isp_loaded_fw) {
932                 ISP_MEMZERO(&mbs, sizeof (mbs));
933                 mbs.param[0] = MBOX_VERIFY_CHECKSUM;
934                 if (IS_24XX(isp)) {
935                         mbs.param[1] = code_org >> 16;
936                         mbs.param[2] = code_org;
937                 } else {
938                         mbs.param[1] = code_org;
939                 }
940                 isp_mboxcmd(isp, &mbs);
941                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
942                         isp_prt(isp, ISP_LOGERR, dcrc);
943                         ISP_RESET0(isp);
944                         return;
945                 }
946         }
947
948         /*
949          * Now start it rolling.
950          *
951          * If we didn't actually download f/w,
952          * we still need to (re)start it.
953          */
954
955
956         MBSINIT(&mbs, MBOX_EXEC_FIRMWARE, MBLOGALL, 1000000);
957         if (IS_24XX(isp)) {
958                 mbs.param[1] = code_org >> 16;
959                 mbs.param[2] = code_org;
960                 if (isp->isp_loaded_fw) {
961                         mbs.param[3] = 0;
962                 } else {
963                         mbs.param[3] = 1;
964                 }
965                 if (IS_25XX(isp)) {
966                         mbs.ibits |= 0x10;
967                 }
968         } else if (IS_2322(isp)) {
969                 mbs.param[1] = code_org;
970                 if (isp->isp_loaded_fw) {
971                         mbs.param[2] = 0;
972                 } else {
973                         mbs.param[2] = 1;
974                 }
975         } else {
976                 mbs.param[1] = code_org;
977         }
978         isp_mboxcmd(isp, &mbs);
979         if (IS_2322(isp) || IS_24XX(isp)) {
980                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
981                         ISP_RESET0(isp);
982                         return;
983                 }
984         }
985
986         /*
987          * Give it a chance to finish starting up.
988          * Give the 24XX more time.
989          */
990         if (IS_24XX(isp)) {
991                 ISP_DELAY(500000);
992                 /*
993                  * Check to see if the 24XX firmware really started.
994                  */
995                 if (mbs.param[1] == 0xdead) {
996                         isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start");
997                         ISP_RESET0(isp);
998                         return;
999                 }
1000         } else {
1001                 ISP_DELAY(250000);
1002                 if (IS_SCSI(isp)) {
1003                         /*
1004                          * Set CLOCK RATE, but only if asked to.
1005                          */
1006                         if (isp->isp_clock) {
1007                                 mbs.param[0] = MBOX_SET_CLOCK_RATE;
1008                                 mbs.param[1] = isp->isp_clock;
1009                                 mbs.logval = MBLOGNONE;
1010                                 isp_mboxcmd(isp, &mbs);
1011                                 /* we will try not to care if this fails */
1012                         }
1013                 }
1014         }
1015
1016         /*
1017          * Ask the chip for the current firmware version.
1018          * This should prove that the new firmware is working.
1019          */
1020         MBSINIT(&mbs, MBOX_ABOUT_FIRMWARE, MBLOGALL, 0);
1021         isp_mboxcmd(isp, &mbs);
1022         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1023                 ISP_RESET0(isp);
1024                 return;
1025         }
1026
1027         /*
1028          * The SBus firmware that we are using apparently does not return
1029          * major, minor, micro revisions in the mailbox registers, which
1030          * is really, really, annoying.
1031          */
1032         if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
1033                 if (dodnld) {
1034 #ifdef  ISP_TARGET_MODE
1035                         isp->isp_fwrev[0] = 7;
1036                         isp->isp_fwrev[1] = 55;
1037 #else
1038                         isp->isp_fwrev[0] = 1;
1039                         isp->isp_fwrev[1] = 37;
1040 #endif
1041                         isp->isp_fwrev[2] = 0;
1042                 }
1043         } else {
1044                 isp->isp_fwrev[0] = mbs.param[1];
1045                 isp->isp_fwrev[1] = mbs.param[2];
1046                 isp->isp_fwrev[2] = mbs.param[3];
1047         }
1048
1049         isp_prt(isp, ISP_LOGCONFIG, "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
1050             btype, isp->isp_revision, dodnld? "loaded" : "resident", isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
1051
1052         if (IS_FC(isp)) {
1053                 /*
1054                  * We do not believe firmware attributes for 2100 code less
1055                  * than 1.17.0, unless it's the firmware we specifically
1056                  * are loading.
1057                  *
1058                  * Note that all 22XX and later f/w is greater than 1.X.0.
1059                  */
1060                 if ((ISP_FW_OLDER_THAN(isp, 1, 17, 1))) {
1061 #ifdef  USE_SMALLER_2100_FIRMWARE
1062                         isp->isp_fwattr = ISP_FW_ATTR_SCCLUN;
1063 #else
1064                         isp->isp_fwattr = 0;
1065 #endif
1066                 } else {
1067                         isp->isp_fwattr = mbs.param[6];
1068                         isp_prt(isp, ISP_LOGDEBUG0, "Firmware Attributes = 0x%x", mbs.param[6]);
1069                 }
1070         } else {
1071 #ifndef ISP_TARGET_MODE
1072                 isp->isp_fwattr = ISP_FW_ATTR_TMODE;
1073 #else
1074                 isp->isp_fwattr = 0;
1075 #endif
1076         }
1077
1078         if (!IS_24XX(isp)) {
1079                 MBSINIT(&mbs, MBOX_GET_FIRMWARE_STATUS, MBLOGALL, 0);
1080                 isp_mboxcmd(isp, &mbs);
1081                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1082                         ISP_RESET0(isp);
1083                         return;
1084                 }
1085                 if (isp->isp_maxcmds >= mbs.param[2]) {
1086                         isp->isp_maxcmds = mbs.param[2];
1087                 }
1088         }
1089         isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", isp->isp_maxcmds);
1090
1091         /*
1092          * If we don't have Multi-ID f/w loaded, we need to restrict channels to one.
1093          * Only make this check for non-SCSI cards (I'm not sure firmware attributes
1094          * work for them).
1095          */
1096         if (IS_FC(isp) && ISP_CAP_MULTI_ID(isp) == 0 && isp->isp_nchan > 1) {
1097                 isp_prt(isp, ISP_LOGWARN, "non-MULTIID f/w loaded, only can enable 1 of %d channels", isp->isp_nchan);
1098                 isp->isp_nchan = 1;
1099         }
1100
1101         for (i = 0; i < isp->isp_nchan; i++) {
1102                 isp_fw_state(isp, i);
1103         }
1104         if (isp->isp_dead) {
1105                 isp_shutdown(isp);
1106                 ISP_DISABLE_INTS(isp);
1107                 return;
1108         }
1109
1110         isp->isp_state = ISP_RESETSTATE;
1111
1112         /*
1113          * Okay- now that we have new firmware running, we now (re)set our
1114          * notion of how many luns we support. This is somewhat tricky because
1115          * if we haven't loaded firmware, we sometimes do not have an easy way
1116          * of knowing how many luns we support.
1117          *
1118          * Expanded lun firmware gives you 32 luns for SCSI cards and
1119          * 16384 luns for Fibre Channel cards.
1120          *
1121          * It turns out that even for QLogic 2100s with ROM 1.10 and above
1122          * we do get a firmware attributes word returned in mailbox register 6.
1123          *
1124          * Because the lun is in a different position in the Request Queue
1125          * Entry structure for Fibre Channel with expanded lun firmware, we
1126          * can only support one lun (lun zero) when we don't know what kind
1127          * of firmware we're running.
1128          */
1129         if (IS_SCSI(isp)) {
1130                 if (dodnld) {
1131                         if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
1132                                 isp->isp_maxluns = 32;
1133                         } else {
1134                                 isp->isp_maxluns = 8;
1135                         }
1136                 } else {
1137                         isp->isp_maxluns = 8;
1138                 }
1139         } else {
1140                 if (ISP_CAP_SCCFW(isp)) {
1141                         isp->isp_maxluns = 16384;
1142                 } else {
1143                         isp->isp_maxluns = 16;
1144                 }
1145         }
1146
1147         /*
1148          * We get some default values established. As a side
1149          * effect, NVRAM is read here (unless overriden by
1150          * a configuration flag).
1151          */
1152         if (do_load_defaults) {
1153                 if (IS_SCSI(isp)) {
1154                         isp_setdfltsdparm(isp);
1155                 } else {
1156                         for (i = 0; i < isp->isp_nchan; i++) {
1157                                 isp_setdfltfcparm(isp, i);
1158                         }
1159                 }
1160         }
1161 }
1162
1163 /*
1164  * Initialize Parameters of Hardware to a known state.
1165  *
1166  * Locks are held before coming here.
1167  */
1168
1169 void
1170 isp_init(ispsoftc_t *isp)
1171 {
1172         if (IS_FC(isp)) {
1173                 if (IS_24XX(isp)) {
1174                         isp_fibre_init_2400(isp);
1175                 } else {
1176                         isp_fibre_init(isp);
1177                 }
1178         } else {
1179                 isp_scsi_init(isp);
1180         }
1181         GET_NANOTIME(&isp->isp_init_time);
1182 }
1183
1184 static void
1185 isp_scsi_init(ispsoftc_t *isp)
1186 {
1187         sdparam *sdp_chan0, *sdp_chan1;
1188         mbreg_t mbs;
1189
1190         sdp_chan0 = SDPARAM(isp, 0);
1191         sdp_chan1 = sdp_chan0;
1192         if (IS_DUALBUS(isp)) {
1193                 sdp_chan1 = SDPARAM(isp, 1);
1194         }
1195
1196         /* First do overall per-card settings. */
1197
1198         /*
1199          * If we have fast memory timing enabled, turn it on.
1200          */
1201         if (sdp_chan0->isp_fast_mttr) {
1202                 ISP_WRITE(isp, RISC_MTR, 0x1313);
1203         }
1204
1205         /*
1206          * Set Retry Delay and Count.
1207          * You set both channels at the same time.
1208          */
1209         MBSINIT(&mbs, MBOX_SET_RETRY_COUNT, MBLOGALL, 0);
1210         mbs.param[1] = sdp_chan0->isp_retry_count;
1211         mbs.param[2] = sdp_chan0->isp_retry_delay;
1212         mbs.param[6] = sdp_chan1->isp_retry_count;
1213         mbs.param[7] = sdp_chan1->isp_retry_delay;
1214         isp_mboxcmd(isp, &mbs);
1215         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1216                 return;
1217         }
1218
1219         /*
1220          * Set ASYNC DATA SETUP time. This is very important.
1221          */
1222         MBSINIT(&mbs, MBOX_SET_ASYNC_DATA_SETUP_TIME, MBLOGALL, 0);
1223         mbs.param[1] = sdp_chan0->isp_async_data_setup;
1224         mbs.param[2] = sdp_chan1->isp_async_data_setup;
1225         isp_mboxcmd(isp, &mbs);
1226         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1227                 return;
1228         }
1229
1230         /*
1231          * Set ACTIVE Negation State.
1232          */
1233         MBSINIT(&mbs, MBOX_SET_ACT_NEG_STATE, MBLOGNONE, 0);
1234         mbs.param[1] =
1235             (sdp_chan0->isp_req_ack_active_neg << 4) |
1236             (sdp_chan0->isp_data_line_active_neg << 5);
1237         mbs.param[2] =
1238             (sdp_chan1->isp_req_ack_active_neg << 4) |
1239             (sdp_chan1->isp_data_line_active_neg << 5);
1240         isp_mboxcmd(isp, &mbs);
1241         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1242                 isp_prt(isp, ISP_LOGERR,
1243                     "failed to set active negation state (%d,%d), (%d,%d)",
1244                     sdp_chan0->isp_req_ack_active_neg,
1245                     sdp_chan0->isp_data_line_active_neg,
1246                     sdp_chan1->isp_req_ack_active_neg,
1247                     sdp_chan1->isp_data_line_active_neg);
1248                 /*
1249                  * But don't return.
1250                  */
1251         }
1252
1253         /*
1254          * Set the Tag Aging limit
1255          */
1256         MBSINIT(&mbs, MBOX_SET_TAG_AGE_LIMIT, MBLOGALL, 0);
1257         mbs.param[1] = sdp_chan0->isp_tag_aging;
1258         mbs.param[2] = sdp_chan1->isp_tag_aging;
1259         isp_mboxcmd(isp, &mbs);
1260         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1261                 isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
1262                     sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
1263                 return;
1264         }
1265
1266         /*
1267          * Set selection timeout.
1268          */
1269         MBSINIT(&mbs, MBOX_SET_SELECT_TIMEOUT, MBLOGALL, 0);
1270         mbs.param[1] = sdp_chan0->isp_selection_timeout;
1271         mbs.param[2] = sdp_chan1->isp_selection_timeout;
1272         isp_mboxcmd(isp, &mbs);
1273         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1274                 return;
1275         }
1276
1277         /* now do per-channel settings */
1278         isp_scsi_channel_init(isp, 0);
1279         if (IS_DUALBUS(isp))
1280                 isp_scsi_channel_init(isp, 1);
1281
1282         /*
1283          * Now enable request/response queues
1284          */
1285
1286         if (IS_ULTRA2(isp) || IS_1240(isp)) {
1287                 MBSINIT(&mbs, MBOX_INIT_RES_QUEUE_A64, MBLOGALL, 0);
1288                 mbs.param[1] = RESULT_QUEUE_LEN(isp);
1289                 mbs.param[2] = DMA_WD1(isp->isp_result_dma);
1290                 mbs.param[3] = DMA_WD0(isp->isp_result_dma);
1291                 mbs.param[4] = 0;
1292                 mbs.param[6] = DMA_WD3(isp->isp_result_dma);
1293                 mbs.param[7] = DMA_WD2(isp->isp_result_dma);
1294                 isp_mboxcmd(isp, &mbs);
1295                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1296                         return;
1297                 }
1298                 isp->isp_residx = mbs.param[5];
1299
1300                 MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE_A64, MBLOGALL, 0);
1301                 mbs.param[1] = RQUEST_QUEUE_LEN(isp);
1302                 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
1303                 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
1304                 mbs.param[5] = 0;
1305                 mbs.param[6] = DMA_WD3(isp->isp_result_dma);
1306                 mbs.param[7] = DMA_WD2(isp->isp_result_dma);
1307                 isp_mboxcmd(isp, &mbs);
1308                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1309                         return;
1310                 }
1311                 isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
1312         } else {
1313                 MBSINIT(&mbs, MBOX_INIT_RES_QUEUE, MBLOGALL, 0);
1314                 mbs.param[1] = RESULT_QUEUE_LEN(isp);
1315                 mbs.param[2] = DMA_WD1(isp->isp_result_dma);
1316                 mbs.param[3] = DMA_WD0(isp->isp_result_dma);
1317                 mbs.param[4] = 0;
1318                 isp_mboxcmd(isp, &mbs);
1319                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1320                         return;
1321                 }
1322                 isp->isp_residx = mbs.param[5];
1323
1324                 MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE, MBLOGALL, 0);
1325                 mbs.param[1] = RQUEST_QUEUE_LEN(isp);
1326                 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
1327                 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
1328                 mbs.param[5] = 0;
1329                 isp_mboxcmd(isp, &mbs);
1330                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1331                         return;
1332                 }
1333                 isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
1334         }
1335
1336         /*
1337          * Turn on Fast Posting, LVD transitions
1338          *
1339          * Ultra2 F/W always has had fast posting (and LVD transitions)
1340          *
1341          * Ultra and older (i.e., SBus) cards may not. It's just safer
1342          * to assume not for them.
1343          */
1344
1345         MBSINIT(&mbs, MBOX_SET_FW_FEATURES, MBLOGALL, 0);
1346         if (IS_ULTRA2(isp))
1347                 mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
1348 #ifndef ISP_NO_RIO
1349         if (IS_ULTRA2(isp) || IS_1240(isp))
1350                 mbs.param[1] |= FW_FEATURE_RIO_16BIT;
1351 #else
1352         if (IS_ULTRA2(isp) || IS_1240(isp))
1353                 mbs.param[1] |= FW_FEATURE_FAST_POST;
1354 #endif
1355         if (mbs.param[1] != 0) {
1356                 uint16_t sfeat = mbs.param[1];
1357                 isp_mboxcmd(isp, &mbs);
1358                 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1359                         isp_prt(isp, ISP_LOGINFO,
1360                             "Enabled FW features (0x%x)", sfeat);
1361                 }
1362         }
1363
1364         isp->isp_state = ISP_INITSTATE;
1365 }
1366
1367 static void
1368 isp_scsi_channel_init(ispsoftc_t *isp, int chan)
1369 {
1370         sdparam *sdp;
1371         mbreg_t mbs;
1372         int tgt;
1373
1374         sdp = SDPARAM(isp, chan);
1375
1376         /*
1377          * Set (possibly new) Initiator ID.
1378          */
1379         MBSINIT(&mbs, MBOX_SET_INIT_SCSI_ID, MBLOGALL, 0);
1380         mbs.param[1] = (chan << 7) | sdp->isp_initiator_id;
1381         isp_mboxcmd(isp, &mbs);
1382         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1383                 return;
1384         }
1385         isp_prt(isp, ISP_LOGINFO, "Chan %d Initiator ID is %d",
1386             chan, sdp->isp_initiator_id);
1387
1388
1389         /*
1390          * Set current per-target parameters to an initial safe minimum.
1391          */
1392         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1393                 int lun;
1394                 uint16_t sdf;
1395
1396                 if (sdp->isp_devparam[tgt].dev_enable == 0) {
1397                         continue;
1398                 }
1399 #ifndef ISP_TARGET_MODE
1400                 sdf = sdp->isp_devparam[tgt].goal_flags;
1401                 sdf &= DPARM_SAFE_DFLT;
1402                 /*
1403                  * It is not quite clear when this changed over so that
1404                  * we could force narrow and async for 1000/1020 cards,
1405                  * but assume that this is only the case for loaded
1406                  * firmware.
1407                  */
1408                 if (isp->isp_loaded_fw) {
1409                         sdf |= DPARM_NARROW | DPARM_ASYNC;
1410                 }
1411 #else
1412                 /*
1413                  * The !$*!)$!$)* f/w uses the same index into some
1414                  * internal table to decide how to respond to negotiations,
1415                  * so if we've said "let's be safe" for ID X, and ID X
1416                  * selects *us*, the negotiations will back to 'safe'
1417                  * (as in narrow/async). What the f/w *should* do is
1418                  * use the initiator id settings to decide how to respond.
1419                  */
1420                 sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
1421 #endif
1422                 MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGNONE, 0);
1423                 mbs.param[1] = (chan << 15) | (tgt << 8);
1424                 mbs.param[2] = sdf;
1425                 if ((sdf & DPARM_SYNC) == 0) {
1426                         mbs.param[3] = 0;
1427                 } else {
1428                         mbs.param[3] =
1429                             (sdp->isp_devparam[tgt].goal_offset << 8) |
1430                             (sdp->isp_devparam[tgt].goal_period);
1431                 }
1432                 isp_prt(isp, ISP_LOGDEBUG0,
1433                     "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
1434                     chan, tgt, mbs.param[2], mbs.param[3] >> 8,
1435                     mbs.param[3] & 0xff);
1436                 isp_mboxcmd(isp, &mbs);
1437                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1438                         sdf = DPARM_SAFE_DFLT;
1439                         MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGALL, 0);
1440                         mbs.param[1] = (tgt << 8) | (chan << 15);
1441                         mbs.param[2] = sdf;
1442                         mbs.param[3] = 0;
1443                         isp_mboxcmd(isp, &mbs);
1444                         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1445                                 continue;
1446                         }
1447                 }
1448
1449                 /*
1450                  * We don't update any information directly from the f/w
1451                  * because we need to run at least one command to cause a
1452                  * new state to be latched up. So, we just assume that we
1453                  * converge to the values we just had set.
1454                  *
1455                  * Ensure that we don't believe tagged queuing is enabled yet.
1456                  * It turns out that sometimes the ISP just ignores our
1457                  * attempts to set parameters for devices that it hasn't
1458                  * seen yet.
1459                  */
1460                 sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
1461                 for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
1462                         MBSINIT(&mbs, MBOX_SET_DEV_QUEUE_PARAMS, MBLOGALL, 0);
1463                         mbs.param[1] = (chan << 15) | (tgt << 8) | lun;
1464                         mbs.param[2] = sdp->isp_max_queue_depth;
1465                         mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
1466                         isp_mboxcmd(isp, &mbs);
1467                         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1468                                 break;
1469                         }
1470                 }
1471         }
1472         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1473                 if (sdp->isp_devparam[tgt].dev_refresh) {
1474                         sdp->sendmarker = 1;
1475                         sdp->update = 1;
1476                         break;
1477                 }
1478         }
1479 }
1480
1481 /*
1482  * Fibre Channel specific initialization.
1483  */
1484 static void
1485 isp_fibre_init(ispsoftc_t *isp)
1486 {
1487         fcparam *fcp;
1488         isp_icb_t local, *icbp = &local;
1489         mbreg_t mbs;
1490         int ownloopid;
1491
1492         /*
1493          * We only support one channel on non-24XX cards
1494          */
1495         fcp = FCPARAM(isp, 0);
1496         if (fcp->role == ISP_ROLE_NONE) {
1497                 isp->isp_state = ISP_INITSTATE;
1498                 return;
1499         }
1500
1501         ISP_MEMZERO(icbp, sizeof (*icbp));
1502         icbp->icb_version = ICB_VERSION1;
1503         icbp->icb_fwoptions = fcp->isp_fwoptions;
1504
1505         /*
1506          * Firmware Options are either retrieved from NVRAM or
1507          * are patched elsewhere. We check them for sanity here
1508          * and make changes based on board revision, but otherwise
1509          * let others decide policy.
1510          */
1511
1512         /*
1513          * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
1514          */
1515         if (IS_2100(isp) && isp->isp_revision < 5) {
1516                 icbp->icb_fwoptions &= ~ICBOPT_FAIRNESS;
1517         }
1518
1519         /*
1520          * We have to use FULL LOGIN even though it resets the loop too much
1521          * because otherwise port database entries don't get updated after
1522          * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
1523          */
1524         if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
1525                 icbp->icb_fwoptions |= ICBOPT_FULL_LOGIN;
1526         }
1527
1528         /*
1529          * Insist on Port Database Update Async notifications
1530          */
1531         icbp->icb_fwoptions |= ICBOPT_PDBCHANGE_AE;
1532
1533         /*
1534          * Make sure that target role reflects into fwoptions.
1535          */
1536         if (fcp->role & ISP_ROLE_TARGET) {
1537                 icbp->icb_fwoptions |= ICBOPT_TGT_ENABLE;
1538         } else {
1539                 icbp->icb_fwoptions &= ~ICBOPT_TGT_ENABLE;
1540         }
1541
1542         if (fcp->role & ISP_ROLE_INITIATOR) {
1543                 icbp->icb_fwoptions &= ~ICBOPT_INI_DISABLE;
1544         } else {
1545                 icbp->icb_fwoptions |= ICBOPT_INI_DISABLE;
1546         }
1547
1548         icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
1549         if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
1550                 isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
1551                 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
1552         }
1553         icbp->icb_maxalloc = fcp->isp_maxalloc;
1554         if (icbp->icb_maxalloc < 1) {
1555                 isp_prt(isp, ISP_LOGERR, "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
1556                 icbp->icb_maxalloc = 16;
1557         }
1558         icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
1559         if (icbp->icb_execthrottle < 1) {
1560                 isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
1561                 icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
1562         }
1563         icbp->icb_retry_delay = fcp->isp_retry_delay;
1564         icbp->icb_retry_count = fcp->isp_retry_count;
1565         icbp->icb_hardaddr = fcp->isp_loopid;
1566         ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
1567         if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
1568                 icbp->icb_hardaddr = 0;
1569                 ownloopid = 0;
1570         }
1571
1572         /*
1573          * Our life seems so much better with 2200s and later with
1574          * the latest f/w if we set Hard Address.
1575          */
1576         if (ownloopid || ISP_FW_NEWER_THAN(isp, 2, 2, 5)) {
1577                 icbp->icb_fwoptions |= ICBOPT_HARD_ADDRESS;
1578         }
1579
1580         /*
1581          * Right now we just set extended options to prefer point-to-point
1582          * over loop based upon some soft config options.
1583          *
1584          * NB: for the 2300, ICBOPT_EXTENDED is required.
1585          */
1586         if (IS_2200(isp) || IS_23XX(isp)) {
1587                 icbp->icb_fwoptions |= ICBOPT_EXTENDED;
1588                 /*
1589                  * Prefer or force Point-To-Point instead Loop?
1590                  */
1591                 switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
1592                 case ISP_CFG_NPORT:
1593                         icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
1594                         break;
1595                 case ISP_CFG_NPORT_ONLY:
1596                         icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY;
1597                         break;
1598                 case ISP_CFG_LPORT_ONLY:
1599                         icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY;
1600                         break;
1601                 default:
1602                         icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
1603                         break;
1604                 }
1605                 if (IS_2200(isp)) {
1606                         /*
1607                          * There seems to just be too much breakage here
1608                          * with RIO and Fast Posting- it probably actually
1609                          * works okay but this driver is messing it up.
1610                          * This card is really ancient by now, so let's
1611                          * just opt for safety and not use the feature.
1612                          */
1613 #if     0
1614                         if (ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
1615                                 icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
1616                                 icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
1617                                 icbp->icb_racctimer = 4;
1618                                 icbp->icb_idelaytimer = 8;
1619                         } else {
1620                                 icbp->icb_fwoptions |= ICBOPT_FAST_POST;
1621                         }
1622 #else
1623                         icbp->icb_xfwoptions &= ~ICBXOPT_RIO_16BIT;
1624                         icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
1625 #endif
1626                 } else {
1627                         /*
1628                          * QLogic recommends that FAST Posting be turned
1629                          * off for 23XX cards and instead allow the HBA
1630                          * to write response queue entries and interrupt
1631                          * after a delay (ZIO).
1632                          */
1633                         icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
1634                         if ((fcp->isp_xfwoptions & ICBXOPT_TIMER_MASK) == ICBXOPT_ZIO) {
1635                                 icbp->icb_xfwoptions |= ICBXOPT_ZIO;
1636                                 icbp->icb_idelaytimer = 10;
1637                         }
1638                         if (isp->isp_confopts & ISP_CFG_ONEGB) {
1639                                 icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
1640                         } else if (isp->isp_confopts & ISP_CFG_TWOGB) {
1641                                 icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB;
1642                         } else {
1643                                 icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
1644                         }
1645                         if (fcp->isp_zfwoptions & ICBZOPT_50_OHM) {
1646                                 icbp->icb_zfwoptions |= ICBZOPT_50_OHM;
1647                         }
1648                 }
1649         }
1650
1651
1652         /*
1653          * For 22XX > 2.1.26 && 23XX, set some options.
1654          */
1655         if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
1656                 MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
1657                 mbs.param[1] = IFCOPT1_DISF7SWTCH|IFCOPT1_LIPASYNC|IFCOPT1_LIPF8;
1658                 mbs.param[2] = 0;
1659                 mbs.param[3] = 0;
1660                 if (ISP_FW_NEWER_THAN(isp, 3, 16, 0)) {
1661                         mbs.param[1] |= IFCOPT1_EQFQASYNC|IFCOPT1_CTIO_RETRY;
1662                         if (fcp->role & ISP_ROLE_TARGET) {
1663                                 mbs.param[3] = IFCOPT3_NOPRLI;
1664                         }
1665                 }
1666                 isp_mboxcmd(isp, &mbs);
1667                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1668                         return;
1669                 }
1670         }
1671         icbp->icb_logintime = ICB_LOGIN_TOV;
1672         icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV;
1673
1674         if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
1675                 icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
1676                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
1677                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1678                 isp_prt(isp, ISP_LOGDEBUG1,
1679                     "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
1680                     ((uint32_t) (fcp->isp_wwnn >> 32)),
1681                     ((uint32_t) (fcp->isp_wwnn)),
1682                     ((uint32_t) (fcp->isp_wwpn >> 32)),
1683                     ((uint32_t) (fcp->isp_wwpn)));
1684         } else if (fcp->isp_wwpn) {
1685                 icbp->icb_fwoptions &= ~ICBOPT_BOTH_WWNS;
1686                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1687                 isp_prt(isp, ISP_LOGDEBUG1,
1688                     "Setting ICB Port 0x%08x%08x",
1689                     ((uint32_t) (fcp->isp_wwpn >> 32)),
1690                     ((uint32_t) (fcp->isp_wwpn)));
1691         } else {
1692                 isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
1693                 return;
1694         }
1695         icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
1696         if (icbp->icb_rqstqlen < 1) {
1697                 isp_prt(isp, ISP_LOGERR, "bad request queue length");
1698         }
1699         icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
1700         if (icbp->icb_rsltqlen < 1) {
1701                 isp_prt(isp, ISP_LOGERR, "bad result queue length");
1702         }
1703         icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1704         icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1705         icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1706         icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
1707         icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1708         icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1709         icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1710         icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
1711
1712         if (FC_SCRATCH_ACQUIRE(isp, 0)) {
1713                 isp_prt(isp, ISP_LOGERR, sacq);
1714                 return;
1715         }
1716         isp_prt(isp, ISP_LOGDEBUG0,
1717             "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
1718             icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
1719
1720         isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
1721
1722         /*
1723          * Init the firmware
1724          */
1725         MBSINIT(&mbs, MBOX_INIT_FIRMWARE, MBLOGALL, 30000000);
1726         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1727         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1728         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1729         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1730         mbs.logval = MBLOGALL;
1731         isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %p (%08x%08x)",
1732             fcp->isp_scratch, (uint32_t) ((uint64_t)fcp->isp_scdma >> 32),
1733             (uint32_t) fcp->isp_scdma);
1734         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp));
1735         isp_mboxcmd(isp, &mbs);
1736         FC_SCRATCH_RELEASE(isp, 0);
1737         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1738                 isp_print_bytes(isp, "isp_fibre_init", sizeof (*icbp), icbp);
1739                 return;
1740         }
1741         isp->isp_reqidx = 0;
1742         isp->isp_reqodx = 0;
1743         isp->isp_residx = 0;
1744
1745         /*
1746          * Whatever happens, we're now committed to being here.
1747          */
1748         isp->isp_state = ISP_INITSTATE;
1749 }
1750
1751 static void
1752 isp_fibre_init_2400(ispsoftc_t *isp)
1753 {
1754         fcparam *fcp;
1755         isp_icb_2400_t local, *icbp = &local;
1756         mbreg_t mbs;
1757         int chan;
1758
1759         /*
1760          * Check to see whether all channels have *some* kind of role
1761          */
1762         for (chan = 0; chan < isp->isp_nchan; chan++) {
1763                 fcp = FCPARAM(isp, chan);
1764                 if (fcp->role != ISP_ROLE_NONE) {
1765                         break;
1766                 }
1767         }
1768         if (chan == isp->isp_nchan) {
1769                 isp_prt(isp, ISP_LOGDEBUG0, "all %d channels with role 'none'", chan);
1770                 isp->isp_state = ISP_INITSTATE;
1771                 return;
1772         }
1773
1774         /*
1775          * Start with channel 0.
1776          */
1777         fcp = FCPARAM(isp, 0);
1778
1779         /*
1780          * Turn on LIP F8 async event (1)
1781          */
1782         MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
1783         mbs.param[1] = 1;
1784         isp_mboxcmd(isp, &mbs);
1785         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1786                 return;
1787         }
1788
1789         ISP_MEMZERO(icbp, sizeof (*icbp));
1790         icbp->icb_fwoptions1 = fcp->isp_fwoptions;
1791         if (fcp->role & ISP_ROLE_TARGET) {
1792                 icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
1793         } else {
1794                 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_TGT_ENABLE;
1795         }
1796
1797         if (fcp->role & ISP_ROLE_INITIATOR) {
1798                 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
1799         } else {
1800                 icbp->icb_fwoptions1 |= ICB2400_OPT1_INI_DISABLE;
1801         }
1802
1803         icbp->icb_version = ICB_VERSION1;
1804         icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
1805         if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
1806                 isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
1807                 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
1808         }
1809
1810         icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
1811         if (icbp->icb_execthrottle < 1) {
1812                 isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
1813                 icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
1814         }
1815
1816         if (icbp->icb_fwoptions1 & ICB2400_OPT1_TGT_ENABLE) {
1817                 /*
1818                  * Get current resource count
1819                  */
1820                 MBSINIT(&mbs, MBOX_GET_RESOURCE_COUNT, MBLOGALL, 0);
1821                 mbs.obits = 0x4cf;
1822                 isp_mboxcmd(isp, &mbs);
1823                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1824                         return;
1825                 }
1826                 icbp->icb_xchgcnt = mbs.param[3];
1827         }
1828
1829
1830         icbp->icb_hardaddr = fcp->isp_loopid;
1831         if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
1832                 icbp->icb_hardaddr = 0;
1833         }
1834
1835         /*
1836          * Force this on.
1837          */
1838         icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
1839
1840         icbp->icb_fwoptions2 = fcp->isp_xfwoptions;
1841         switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
1842 #if     0
1843         case ISP_CFG_NPORT:
1844                 /*
1845                  * XXX: This causes the f/w to crash.
1846                  */
1847                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1848                 icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_2_LOOP;
1849                 break;
1850 #endif
1851         case ISP_CFG_NPORT_ONLY:
1852                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1853                 icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY;
1854                 break;
1855         case ISP_CFG_LPORT_ONLY:
1856                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1857                 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY;
1858                 break;
1859         default:
1860                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1861                 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
1862                 break;
1863         }
1864
1865         /* force this on for now */
1866         icbp->icb_fwoptions2 |= ICB2400_OPT2_ZIO;
1867
1868         switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) {
1869         case ICB2400_OPT2_ZIO:
1870         case ICB2400_OPT2_ZIO1:
1871                 icbp->icb_idelaytimer = 0;
1872                 break;
1873         case 0:
1874                 break;
1875         default:
1876                 isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field", icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
1877                 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK;
1878                 break;
1879         }
1880
1881         /*
1882          * We don't support FCTAPE, so clear it.
1883          */
1884         icbp->icb_fwoptions2 &= ~ICB2400_OPT2_FCTAPE;
1885
1886         icbp->icb_fwoptions3 = fcp->isp_zfwoptions;
1887         icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_AUTO;
1888         if (isp->isp_confopts & ISP_CFG_ONEGB) {
1889                 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_ONEGB;
1890         } else if (isp->isp_confopts & ISP_CFG_TWOGB) {
1891                 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_TWOGB;
1892         } else if (isp->isp_confopts & ISP_CFG_FOURGB) {
1893                 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_FOURGB;
1894         } else {
1895                 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
1896         }
1897
1898         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
1899                 icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID;
1900         }
1901         icbp->icb_logintime = ICB_LOGIN_TOV;
1902
1903         if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
1904                 icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
1905                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1906                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
1907                 isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node 0x%08x%08x Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwnn >> 32)), ((uint32_t) (fcp->isp_wwnn)),
1908                     ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
1909         } else if (fcp->isp_wwpn) {
1910                 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS;
1911                 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1912                 isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node to be same as Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
1913         } else {
1914                 isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
1915                 return;
1916         }
1917         icbp->icb_retry_count = fcp->isp_retry_count;
1918
1919         icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
1920         if (icbp->icb_rqstqlen < 8) {
1921                 isp_prt(isp, ISP_LOGERR, "bad request queue length %d", icbp->icb_rqstqlen);
1922                 return;
1923         }
1924         icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
1925         if (icbp->icb_rsltqlen < 8) {
1926                 isp_prt(isp, ISP_LOGERR, "bad result queue length %d",
1927                     icbp->icb_rsltqlen);
1928                 return;
1929         }
1930         icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1931         icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1932         icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1933         icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
1934
1935         icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1936         icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1937         icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1938         icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
1939
1940 #ifdef  ISP_TARGET_MODE
1941         /* unconditionally set up the ATIO queue if we support target mode */
1942         icbp->icb_atioqlen = RESULT_QUEUE_LEN(isp);
1943         if (icbp->icb_atioqlen < 8) {
1944                 isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d", icbp->icb_atioqlen);
1945                 return;
1946         }
1947         icbp->icb_atioqaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_atioq_dma);
1948         icbp->icb_atioqaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_atioq_dma);
1949         icbp->icb_atioqaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_atioq_dma);
1950         icbp->icb_atioqaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_atioq_dma);
1951         isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: atioq %04x%04x%04x%04x", DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma),
1952             DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma));
1953 #endif
1954
1955         isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3);
1956
1957         isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x", DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma),
1958             DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma), DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
1959             DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
1960
1961         if (isp->isp_dblev & ISP_LOGDEBUG1) {
1962                 isp_print_bytes(isp, "isp_fibre_init_2400", sizeof (*icbp), icbp);
1963         }
1964
1965         if (FC_SCRATCH_ACQUIRE(isp, 0)) {
1966                 isp_prt(isp, ISP_LOGERR, sacq);
1967                 return;
1968         }
1969         ISP_MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
1970         isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
1971
1972         /*
1973          * Now fill in information about any additional channels
1974          */
1975         if (isp->isp_nchan > 1) {
1976                 isp_icb_2400_vpinfo_t vpinfo, *vdst;
1977                 vp_port_info_t pi, *pdst;
1978                 size_t amt = 0;
1979                 uint8_t *off;
1980
1981                 vpinfo.vp_count = isp->isp_nchan - 1;
1982                 vpinfo.vp_global_options = 0;
1983                 off = fcp->isp_scratch;
1984                 off += ICB2400_VPINFO_OFF;
1985                 vdst = (isp_icb_2400_vpinfo_t *) off;
1986                 isp_put_icb_2400_vpinfo(isp, &vpinfo, vdst);
1987                 amt = ICB2400_VPINFO_OFF + sizeof (isp_icb_2400_vpinfo_t);
1988                 for (chan = 1; chan < isp->isp_nchan; chan++) {
1989                         fcparam *fcp2;
1990
1991                         ISP_MEMZERO(&pi, sizeof (pi));
1992                         fcp2 = FCPARAM(isp, chan);
1993                         if (fcp2->role != ISP_ROLE_NONE) {
1994                                 pi.vp_port_options = ICB2400_VPOPT_ENABLED;
1995                                 if (fcp2->role & ISP_ROLE_INITIATOR) {
1996                                         pi.vp_port_options |= ICB2400_VPOPT_INI_ENABLE;
1997                                 }
1998                                 if ((fcp2->role & ISP_ROLE_TARGET) == 0) {
1999                                         pi.vp_port_options |= ICB2400_VPOPT_TGT_DISABLE;
2000                                 }
2001                                 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname, fcp2->isp_wwpn);
2002                                 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename, fcp2->isp_wwnn);
2003                         }
2004                         off = fcp->isp_scratch;
2005                         off += ICB2400_VPINFO_PORT_OFF(chan);
2006                         pdst = (vp_port_info_t *) off;
2007                         isp_put_vp_port_info(isp, &pi, pdst);
2008                         amt += ICB2400_VPOPT_WRITE_SIZE;
2009                 }
2010         }
2011
2012         /*
2013          * Init the firmware
2014          */
2015         MBSINIT(&mbs, 0, MBLOGALL, 30000000);
2016         if (isp->isp_nchan > 1) {
2017                 mbs.param[0] = MBOX_INIT_FIRMWARE_MULTI_ID;
2018         } else {
2019                 mbs.param[0] = MBOX_INIT_FIRMWARE;
2020         }
2021         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2022         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2023         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2024         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2025         isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %04x%04x%04x%04x", DMA_WD3(fcp->isp_scdma), DMA_WD2(fcp->isp_scdma), DMA_WD1(fcp->isp_scdma), DMA_WD0(fcp->isp_scdma));
2026         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp));
2027         isp_mboxcmd(isp, &mbs);
2028         FC_SCRATCH_RELEASE(isp, 0);
2029
2030         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2031                 return;
2032         }
2033         isp->isp_reqidx = 0;
2034         isp->isp_reqodx = 0;
2035         isp->isp_residx = 0;
2036
2037         /*
2038          * Whatever happens, we're now committed to being here.
2039          */
2040         isp->isp_state = ISP_INITSTATE;
2041 }
2042
2043 static void
2044 isp_mark_portdb(ispsoftc_t *isp, int chan, int disposition)
2045 {
2046         fcparam *fcp = FCPARAM(isp, chan);
2047         int i;
2048
2049         if (chan < 0 || chan >= isp->isp_nchan) {
2050                 isp_prt(isp, ISP_LOGWARN, "isp_mark_portdb: bad channel %d", chan);
2051                 return;
2052         }
2053         for (i = 0; i < MAX_FC_TARG; i++) {
2054                 if (fcp->portdb[i].target_mode) {
2055                         if (disposition < 0) {
2056                                 isp_prt(isp, ISP_LOGTINFO, "isp_mark_portdb: Chan %d zeroing handle 0x" "%04x port 0x%06x", chan,
2057                                     fcp->portdb[i].handle, fcp->portdb[i].portid);
2058                                 ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
2059                         }
2060                         continue;
2061                 }
2062                 if (disposition == 0) {
2063                         ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
2064                 } else {
2065                         switch (fcp->portdb[i].state) {
2066                         case FC_PORTDB_STATE_CHANGED:
2067                         case FC_PORTDB_STATE_PENDING_VALID:
2068                         case FC_PORTDB_STATE_VALID:
2069                         case FC_PORTDB_STATE_PROBATIONAL:
2070                                 fcp->portdb[i].state = FC_PORTDB_STATE_PROBATIONAL;
2071                                 break;
2072                         case FC_PORTDB_STATE_ZOMBIE:
2073                                 break;
2074                         case FC_PORTDB_STATE_NIL:
2075                         default:
2076                                 ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
2077                                 fcp->portdb[i].state = FC_PORTDB_STATE_NIL;
2078                                 break;
2079                         }
2080                 }
2081         }
2082 }
2083
2084 /*
2085  * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards
2086  * or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
2087  */
2088 static int
2089 isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags, int gs)
2090 {
2091         mbreg_t mbs;
2092         uint8_t q[QENTRY_LEN];
2093         isp_plogx_t *plp;
2094         fcparam *fcp;
2095         uint8_t *scp;
2096         uint32_t sst, parm1;
2097         int rval, lev;
2098         const char *msg;
2099         char buf[64];
2100
2101         if (!IS_24XX(isp)) {
2102                 int action = flags & PLOGX_FLG_CMD_MASK;
2103                 if (action == PLOGX_FLG_CMD_PLOGI) {
2104                         return (isp_port_login(isp, handle, portid));
2105                 } else if (action == PLOGX_FLG_CMD_LOGO) {
2106                         return (isp_port_logout(isp, handle, portid));
2107                 } else {
2108                         return (MBOX_INVALID_COMMAND);
2109                 }
2110         }
2111
2112         ISP_MEMZERO(q, QENTRY_LEN);
2113         plp = (isp_plogx_t *) q;
2114         plp->plogx_header.rqs_entry_count = 1;
2115         plp->plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
2116         plp->plogx_handle = 0xffffffff;
2117         plp->plogx_nphdl = handle;
2118         plp->plogx_vphdl = chan;
2119         plp->plogx_portlo = portid;
2120         plp->plogx_rspsz_porthi = (portid >> 16) & 0xff;
2121         plp->plogx_flags = flags;
2122
2123         if (isp->isp_dblev & ISP_LOGDEBUG1) {
2124                 isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, plp);
2125         }
2126
2127         if (gs == 0) {
2128                 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2129                         isp_prt(isp, ISP_LOGERR, sacq);
2130                         return (-1);
2131                 }
2132         }
2133         fcp = FCPARAM(isp, chan);
2134         scp = fcp->isp_scratch;
2135         isp_put_plogx(isp, plp, (isp_plogx_t *) scp);
2136
2137         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
2138         mbs.param[1] = QENTRY_LEN;
2139         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2140         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2141         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2142         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2143         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN);
2144         isp_mboxcmd(isp, &mbs);
2145         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2146                 rval = mbs.param[0];
2147                 goto out;
2148         }
2149         MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN);
2150         scp += QENTRY_LEN;
2151         isp_get_plogx(isp, (isp_plogx_t *) scp, plp);
2152         if (isp->isp_dblev & ISP_LOGDEBUG1) {
2153                 isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, plp);
2154         }
2155
2156         if (plp->plogx_status == PLOGX_STATUS_OK) {
2157                 rval = 0;
2158                 goto out;
2159         } else if (plp->plogx_status != PLOGX_STATUS_IOCBERR) {
2160                 isp_prt(isp, ISP_LOGWARN,
2161                     "status 0x%x on port login IOCB chanel %d",
2162                     plp->plogx_status, chan);
2163                 rval = -1;
2164                 goto out;
2165         }
2166
2167         sst = plp->plogx_ioparm[0].lo16 | (plp->plogx_ioparm[0].hi16 << 16);
2168         parm1 = plp->plogx_ioparm[1].lo16 | (plp->plogx_ioparm[1].hi16 << 16);
2169
2170         rval = -1;
2171         lev = ISP_LOGERR;
2172         msg = NULL;
2173
2174         switch (sst) {
2175         case PLOGX_IOCBERR_NOLINK:
2176                 msg = "no link";
2177                 break;
2178         case PLOGX_IOCBERR_NOIOCB:
2179                 msg = "no IOCB buffer";
2180                 break;
2181         case PLOGX_IOCBERR_NOXGHG:
2182                 msg = "no Exchange Control Block";
2183                 break;
2184         case PLOGX_IOCBERR_FAILED:
2185                 ISP_SNPRINTF(buf, sizeof (buf),
2186                     "reason 0x%x (last LOGIN state 0x%x)",
2187                     parm1 & 0xff, (parm1 >> 8) & 0xff);
2188                 msg = buf;
2189                 break;
2190         case PLOGX_IOCBERR_NOFABRIC:
2191                 msg = "no fabric";
2192                 break;
2193         case PLOGX_IOCBERR_NOTREADY:
2194                 msg = "firmware not ready";
2195                 break;
2196         case PLOGX_IOCBERR_NOLOGIN:
2197                 ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)",
2198                     parm1);
2199                 msg = buf;
2200                 rval = MBOX_NOT_LOGGED_IN;
2201                 break;
2202         case PLOGX_IOCBERR_REJECT:
2203                 ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1);
2204                 msg = buf;
2205                 break;
2206         case PLOGX_IOCBERR_NOPCB:
2207                 msg = "no PCB allocated";
2208                 break;
2209         case PLOGX_IOCBERR_EINVAL:
2210                 ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x",
2211                     parm1);
2212                 msg = buf;
2213                 break;
2214         case PLOGX_IOCBERR_PORTUSED:
2215                 lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
2216                 ISP_SNPRINTF(buf, sizeof (buf),
2217                     "already logged in with N-Port handle 0x%x", parm1);
2218                 msg = buf;
2219                 rval = MBOX_PORT_ID_USED | (parm1 << 16);
2220                 break;
2221         case PLOGX_IOCBERR_HNDLUSED:
2222                 lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
2223                 ISP_SNPRINTF(buf, sizeof (buf),
2224                     "handle already used for PortID 0x%06x", parm1);
2225                 msg = buf;
2226                 rval = MBOX_LOOP_ID_USED;
2227                 break;
2228         case PLOGX_IOCBERR_NOHANDLE:
2229                 msg = "no handle allocated";
2230                 break;
2231         case PLOGX_IOCBERR_NOFLOGI:
2232                 msg = "no FLOGI_ACC";
2233                 break;
2234         default:
2235                 ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x",
2236                     plp->plogx_status, flags);
2237                 msg = buf;
2238                 break;
2239         }
2240         if (msg) {
2241                 isp_prt(isp, ISP_LOGERR,
2242                     "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s",
2243                     chan, portid, handle, msg);
2244         }
2245 out:
2246         if (gs == 0) {
2247                 FC_SCRATCH_RELEASE(isp, chan);
2248         }
2249         return (rval);
2250 }
2251
2252 static int
2253 isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
2254 {
2255         mbreg_t mbs;
2256
2257         MBSINIT(&mbs, MBOX_FABRIC_LOGIN, MBLOGNONE, 500000);
2258         if (ISP_CAP_2KLOGIN(isp)) {
2259                 mbs.param[1] = handle;
2260                 mbs.ibits = (1 << 10);
2261         } else {
2262                 mbs.param[1] = handle << 8;
2263         }
2264         mbs.param[2] = portid >> 16;
2265         mbs.param[3] = portid;
2266         mbs.logval = MBLOGNONE;
2267         mbs.timeout = 500000;
2268         isp_mboxcmd(isp, &mbs);
2269
2270         switch (mbs.param[0]) {
2271         case MBOX_PORT_ID_USED:
2272                 isp_prt(isp, ISP_LOGDEBUG0,
2273                     "isp_port_login: portid 0x%06x already logged in as %u",
2274                     portid, mbs.param[1]);
2275                 return (MBOX_PORT_ID_USED | (mbs.param[1] << 16));
2276
2277         case MBOX_LOOP_ID_USED:
2278                 isp_prt(isp, ISP_LOGDEBUG0,
2279                     "isp_port_login: handle 0x%04x in use for port id 0x%02xXXXX",
2280                     handle, mbs.param[1] & 0xff);
2281                 return (MBOX_LOOP_ID_USED);
2282
2283         case MBOX_COMMAND_COMPLETE:
2284                 return (0);
2285
2286         case MBOX_COMMAND_ERROR:
2287                 isp_prt(isp, ISP_LOGINFO,
2288                     "isp_port_login: error 0x%x in PLOGI to port 0x%06x",
2289                     mbs.param[1], portid);
2290                 return (MBOX_COMMAND_ERROR);
2291
2292         case MBOX_ALL_IDS_USED:
2293                 isp_prt(isp, ISP_LOGINFO,
2294                     "isp_port_login: all IDs used for fabric login");
2295                 return (MBOX_ALL_IDS_USED);
2296
2297         default:
2298                 isp_prt(isp, ISP_LOGINFO,
2299                     "isp_port_login: error 0x%x on port login of 0x%06x@0x%0x",
2300                     mbs.param[0], portid, handle);
2301                 return (mbs.param[0]);
2302         }
2303 }
2304
2305 static int
2306 isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
2307 {
2308         mbreg_t mbs;
2309
2310         MBSINIT(&mbs, MBOX_FABRIC_LOGOUT, MBLOGNONE, 500000);
2311         if (ISP_CAP_2KLOGIN(isp)) {
2312                 mbs.param[1] = handle;
2313                 mbs.ibits = (1 << 10);
2314         } else {
2315                 mbs.param[1] = handle << 8;
2316         }
2317         isp_mboxcmd(isp, &mbs);
2318         return (mbs.param[0] == MBOX_COMMAND_COMPLETE? 0 : mbs.param[0]);
2319 }
2320
2321 static int
2322 isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
2323 {
2324         fcparam *fcp = FCPARAM(isp, chan);
2325         mbreg_t mbs;
2326         union {
2327                 isp_pdb_21xx_t fred;
2328                 isp_pdb_24xx_t bill;
2329         } un;
2330
2331         MBSINIT(&mbs, MBOX_GET_PORT_DB, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 250000);
2332         if (IS_24XX(isp)) {
2333                 mbs.ibits = (1 << 9)|(1 << 10);
2334                 mbs.param[1] = id;
2335                 mbs.param[9] = chan;
2336         } else if (ISP_CAP_2KLOGIN(isp)) {
2337                 mbs.param[1] = id;
2338         } else {
2339                 mbs.param[1] = id << 8;
2340         }
2341         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2342         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2343         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2344         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2345         if (dolock) {
2346                 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2347                         isp_prt(isp, ISP_LOGERR, sacq);
2348                         return (-1);
2349                 }
2350         }
2351         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (un));
2352         isp_mboxcmd(isp, &mbs);
2353         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2354                 if (dolock) {
2355                         FC_SCRATCH_RELEASE(isp, chan);
2356                 }
2357                 return (mbs.param[0]);
2358         }
2359         if (IS_24XX(isp)) {
2360                 isp_get_pdb_24xx(isp, fcp->isp_scratch, &un.bill);
2361                 pdb->handle = un.bill.pdb_handle;
2362                 pdb->s3_role = un.bill.pdb_prli_svc3;
2363                 pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
2364                 ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
2365                 ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
2366                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2367                     "Chan %d Port 0x%06x flags 0x%x curstate %x",
2368                     chan, pdb->portid, un.bill.pdb_flags,
2369                     un.bill.pdb_curstate);
2370                 if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE ||
2371                     un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) {
2372                         mbs.param[0] = MBOX_NOT_LOGGED_IN;
2373                         if (dolock) {
2374                                 FC_SCRATCH_RELEASE(isp, chan);
2375                         }
2376                         return (mbs.param[0]);
2377                 }
2378         } else {
2379                 isp_get_pdb_21xx(isp, fcp->isp_scratch, &un.fred);
2380                 pdb->handle = un.fred.pdb_loopid;
2381                 pdb->s3_role = un.fred.pdb_prli_svc3;
2382                 pdb->portid = BITS2WORD(un.fred.pdb_portid_bits);
2383                 ISP_MEMCPY(pdb->portname, un.fred.pdb_portname, 8);
2384                 ISP_MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8);
2385         }
2386         if (dolock) {
2387                 FC_SCRATCH_RELEASE(isp, chan);
2388         }
2389         return (0);
2390 }
2391
2392 static void
2393 isp_dump_chip_portdb(ispsoftc_t *isp, int chan, int dolock)
2394 {
2395         isp_pdb_t pdb;
2396         int lim, loopid;
2397
2398         if (ISP_CAP_2KLOGIN(isp)) {
2399                 lim = NPH_MAX_2K;
2400         } else {
2401                 lim = NPH_MAX;
2402         }
2403         for (loopid = 0; loopid != lim; loopid++) {
2404                 if (isp_getpdb(isp, chan, loopid, &pdb, dolock)) {
2405                         continue;
2406                 }
2407                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGINFO, "Chan %d Loopid 0x%04x "
2408                     "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x",
2409                     chan, loopid, pdb.portid, pdb.portname[0], pdb.portname[1],
2410                     pdb.portname[2], pdb.portname[3], pdb.portname[4],
2411                     pdb.portname[5], pdb.portname[6], pdb.portname[7]);
2412         }
2413 }
2414
2415 static uint64_t
2416 isp_get_wwn(ispsoftc_t *isp, int chan, int loopid, int nodename)
2417 {
2418         uint64_t wwn = INI_NONE;
2419         fcparam *fcp = FCPARAM(isp, chan);
2420         mbreg_t mbs;
2421
2422         if (fcp->isp_fwstate < FW_READY ||
2423             fcp->isp_loopstate < LOOP_PDB_RCVD) {
2424                 return (wwn);
2425         }
2426         MBSINIT(&mbs, MBOX_GET_PORT_NAME, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 500000);
2427         if (ISP_CAP_2KLOGIN(isp)) {
2428                 mbs.param[1] = loopid;
2429                 mbs.ibits = (1 << 10);
2430                 if (nodename) {
2431                         mbs.param[10] = 1;
2432                 }
2433                 if (ISP_CAP_MULTI_ID(isp)) {
2434                         mbs.ibits |= (1 << 9);
2435                         mbs.param[9] = chan;
2436                 }
2437         } else {
2438                 mbs.param[1] = loopid << 8;
2439                 if (nodename) {
2440                         mbs.param[1] |= 1;
2441                 }
2442         }
2443         isp_mboxcmd(isp, &mbs);
2444         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2445                 return (wwn);
2446         }
2447         if (IS_24XX(isp)) {
2448                 wwn =
2449                     (((uint64_t)(mbs.param[2] >> 8))    << 56) |
2450                     (((uint64_t)(mbs.param[2] & 0xff))  << 48) |
2451                     (((uint64_t)(mbs.param[3] >> 8))    << 40) |
2452                     (((uint64_t)(mbs.param[3] & 0xff))  << 32) |
2453                     (((uint64_t)(mbs.param[6] >> 8))    << 24) |
2454                     (((uint64_t)(mbs.param[6] & 0xff))  << 16) |
2455                     (((uint64_t)(mbs.param[7] >> 8))    <<  8) |
2456                     (((uint64_t)(mbs.param[7] & 0xff)));
2457         } else {
2458                 wwn =
2459                     (((uint64_t)(mbs.param[2] & 0xff))  << 56) |
2460                     (((uint64_t)(mbs.param[2] >> 8))    << 48) |
2461                     (((uint64_t)(mbs.param[3] & 0xff))  << 40) |
2462                     (((uint64_t)(mbs.param[3] >> 8))    << 32) |
2463                     (((uint64_t)(mbs.param[6] & 0xff))  << 24) |
2464                     (((uint64_t)(mbs.param[6] >> 8))    << 16) |
2465                     (((uint64_t)(mbs.param[7] & 0xff))  <<  8) |
2466                     (((uint64_t)(mbs.param[7] >> 8)));
2467         }
2468         return (wwn);
2469 }
2470
2471 /*
2472  * Make sure we have good FC link.
2473  */
2474
2475 static int
2476 isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
2477 {
2478         mbreg_t mbs;
2479         int count, check_for_fabric, r;
2480         uint8_t lwfs;
2481         int loopid;
2482         fcparam *fcp;
2483         fcportdb_t *lp;
2484         isp_pdb_t pdb;
2485
2486         fcp = FCPARAM(isp, chan);
2487
2488         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d FC Link Test Entry", chan);
2489         ISP_MARK_PORTDB(isp, chan, 1);
2490
2491         /*
2492          * Wait up to N microseconds for F/W to go to a ready state.
2493          */
2494         lwfs = FW_CONFIG_WAIT;
2495         count = 0;
2496         while (count < usdelay) {
2497                 uint64_t enano;
2498                 uint32_t wrk;
2499                 NANOTIME_T hra, hrb;
2500
2501                 GET_NANOTIME(&hra);
2502                 isp_fw_state(isp, chan);
2503                 if (lwfs != fcp->isp_fwstate) {
2504                         isp_prt(isp, ISP_LOGCONFIG|ISP_LOGSANCFG, "Chan %d Firmware State <%s->%s>", chan, isp_fc_fw_statename((int)lwfs), isp_fc_fw_statename((int)fcp->isp_fwstate));
2505                         lwfs = fcp->isp_fwstate;
2506                 }
2507                 if (fcp->isp_fwstate == FW_READY) {
2508                         break;
2509                 }
2510                 GET_NANOTIME(&hrb);
2511
2512                 /*
2513                  * Get the elapsed time in nanoseconds.
2514                  * Always guaranteed to be non-zero.
2515                  */
2516                 enano = NANOTIME_SUB(&hrb, &hra);
2517
2518                 isp_prt(isp, ISP_LOGDEBUG1, "usec%d: 0x%lx->0x%lx enano 0x%x%08x", count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb), (uint32_t)(enano >> 32), (uint32_t)(enano));
2519
2520                 /*
2521                  * If the elapsed time is less than 1 millisecond,
2522                  * delay a period of time up to that millisecond of
2523                  * waiting.
2524                  *
2525                  * This peculiar code is an attempt to try and avoid
2526                  * invoking uint64_t math support functions for some
2527                  * platforms where linkage is a problem.
2528                  */
2529                 if (enano < (1000 * 1000)) {
2530                         count += 1000;
2531                         enano = (1000 * 1000) - enano;
2532                         while (enano > (uint64_t) 4000000000U) {
2533                                 ISP_SLEEP(isp, 4000000);
2534                                 enano -= (uint64_t) 4000000000U;
2535                         }
2536                         wrk = enano;
2537                         wrk /= 1000;
2538                         ISP_SLEEP(isp, wrk);
2539                 } else {
2540                         while (enano > (uint64_t) 4000000000U) {
2541                                 count += 4000000;
2542                                 enano -= (uint64_t) 4000000000U;
2543                         }
2544                         wrk = enano;
2545                         count += (wrk / 1000);
2546                 }
2547         }
2548
2549
2550
2551         /*
2552          * If we haven't gone to 'ready' state, return.
2553          */
2554         if (fcp->isp_fwstate != FW_READY) {
2555                 isp_prt(isp, ISP_LOGSANCFG, "%s: chan %d not at FW_READY state", __func__, chan);
2556                 return (-1);
2557         }
2558
2559         /*
2560          * Get our Loop ID and Port ID.
2561          */
2562         MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0);
2563         if (ISP_CAP_MULTI_ID(isp)) {
2564                 mbs.param[9] = chan;
2565                 mbs.ibits = (1 << 9);
2566                 mbs.obits = (1 << 7);
2567         }
2568         isp_mboxcmd(isp, &mbs);
2569         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2570                 return (-1);
2571         }
2572
2573         if (ISP_CAP_2KLOGIN(isp)) {
2574                 fcp->isp_loopid = mbs.param[1];
2575         } else {
2576                 fcp->isp_loopid = mbs.param[1] & 0xff;
2577         }
2578
2579         if (IS_2100(isp)) {
2580                 fcp->isp_topo = TOPO_NL_PORT;
2581         } else {
2582                 int topo = (int) mbs.param[6];
2583                 if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB) {
2584                         topo = TOPO_PTP_STUB;
2585                 }
2586                 fcp->isp_topo = topo;
2587         }
2588         fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
2589
2590         if (IS_2100(isp)) {
2591                 /*
2592                  * Don't bother with fabric if we are using really old
2593                  * 2100 firmware. It's just not worth it.
2594                  */
2595                 if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) {
2596                         check_for_fabric = 1;
2597                 } else {
2598                         check_for_fabric = 0;
2599                 }
2600         } else if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_F_PORT) {
2601                 check_for_fabric = 1;
2602         } else {
2603                 check_for_fabric = 0;
2604         }
2605
2606         /*
2607          * Check to make sure we got a valid loopid
2608          * The 24XX seems to mess this up for multiple channels.
2609          */
2610         if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT) {
2611                 uint8_t alpa = fcp->isp_portid;
2612
2613                 if (alpa == 0) {
2614                         /* "Cannot Happen" */
2615                         isp_prt(isp, ISP_LOGWARN, "Zero AL_PA for Loop Topology?");
2616                 } else {
2617                         int i;
2618                         for (i = 0; alpa_map[i]; i++) {
2619                                 if (alpa_map[i] == alpa) {
2620                                         break;
2621                                 }
2622                         }
2623                         if (alpa_map[i] && fcp->isp_loopid != i) {
2624                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d deriving loopid %d from AL_PA map  (AL_PA 0x%x) and ignoring returned value %d (AL_PA 0x%x)", chan, i, alpa_map[i], fcp->isp_loopid, alpa);
2625                                 fcp->isp_loopid = i;
2626                         }
2627                 }
2628         }
2629
2630
2631         if (IS_24XX(isp)) { /* XXX SHOULDN'T THIS BE FOR 2K F/W? XXX */
2632                 loopid = NPH_FL_ID;
2633         } else {
2634                 loopid = FL_ID;
2635         }
2636         if (check_for_fabric) {
2637                 r = isp_getpdb(isp, chan, loopid, &pdb, 1);
2638                 if (r && (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT)) {
2639                         isp_prt(isp, ISP_LOGWARN, "fabric topology but cannot get info about fabric controller (0x%x)", r);
2640                         fcp->isp_topo = TOPO_PTP_STUB;
2641                 }
2642         } else {
2643                 r = -1;
2644         }
2645         if (r == 0) {
2646                 if (IS_2100(isp)) {
2647                         fcp->isp_topo = TOPO_FL_PORT;
2648                 }
2649                 if (pdb.portid == 0) {
2650                         /*
2651                          * Crock.
2652                          */
2653                         fcp->isp_topo = TOPO_NL_PORT;
2654                         goto not_on_fabric;
2655                 }
2656
2657                 /*
2658                  * Save the Fabric controller's port database entry.
2659                  */
2660                 lp = &fcp->portdb[FL_ID];
2661                 lp->state = FC_PORTDB_STATE_PENDING_VALID;
2662                 MAKE_WWN_FROM_NODE_NAME(lp->node_wwn, pdb.nodename);
2663                 MAKE_WWN_FROM_NODE_NAME(lp->port_wwn, pdb.portname);
2664                 lp->roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
2665                 lp->portid = pdb.portid;
2666                 lp->handle = pdb.handle;
2667                 lp->new_portid = lp->portid;
2668                 lp->new_roles = lp->roles;
2669                 if (IS_24XX(isp)) {
2670                         fcp->inorder = (mbs.param[7] & ISP24XX_INORDER) != 0;
2671                         if (ISP_FW_NEWER_THAN(isp, 4, 0, 27)) {
2672                                 fcp->npiv_fabric = (mbs.param[7] & ISP24XX_NPIV_SAN) != 0;
2673                                 if (fcp->npiv_fabric) {
2674                                         isp_prt(isp, ISP_LOGCONFIG, "fabric supports NP-IV");
2675                                 }
2676                         }
2677                         if (chan) {
2678                                 fcp->isp_sns_hdl = NPH_SNS_HDLBASE + chan;
2679                                 r = isp_plogx(isp, chan, fcp->isp_sns_hdl, SNS_PORT_ID, PLOGX_FLG_CMD_PLOGI | PLOGX_FLG_COND_PLOGI | PLOGX_FLG_SKIP_PRLI, 0);
2680                                 if (r) {
2681                                         isp_prt(isp, ISP_LOGWARN, "%s: Chan %d cannot log into SNS", __func__, chan);
2682                                         return (-1);
2683                                 }
2684                         } else {
2685                                 fcp->isp_sns_hdl = NPH_SNS_ID;
2686                         }
2687                         r = isp_register_fc4_type_24xx(isp, chan);
2688                 } else {
2689                         fcp->isp_sns_hdl = SNS_ID;
2690                         r = isp_register_fc4_type(isp, chan);
2691                 }
2692                 if (r) {
2693                         isp_prt(isp, ISP_LOGWARN|ISP_LOGSANCFG, "%s: register fc4 type failed", __func__);
2694                         return (-1);
2695                 }
2696         } else {
2697 not_on_fabric:
2698                 fcp->portdb[FL_ID].state = FC_PORTDB_STATE_NIL;
2699         }
2700
2701         fcp->isp_gbspeed = 1;
2702         if (IS_23XX(isp) || IS_24XX(isp)) {
2703                 MBSINIT(&mbs, MBOX_GET_SET_DATA_RATE, MBLOGALL, 3000000);
2704                 mbs.param[1] = MBGSD_GET_RATE;
2705                 /* mbs.param[2] undefined if we're just getting rate */
2706                 isp_mboxcmd(isp, &mbs);
2707                 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
2708                         if (mbs.param[1] == MBGSD_EIGHTGB) {
2709                                 isp_prt(isp, ISP_LOGINFO, "Chan %d 8Gb link speed", chan);
2710                                 fcp->isp_gbspeed = 8;
2711                         } else if (mbs.param[1] == MBGSD_FOURGB) {
2712                                 isp_prt(isp, ISP_LOGINFO, "Chan %d 4Gb link speed", chan);
2713                                 fcp->isp_gbspeed = 4;
2714                         } else if (mbs.param[1] == MBGSD_TWOGB) {
2715                                 isp_prt(isp, ISP_LOGINFO, "Chan %d 2Gb link speed", chan);
2716                                 fcp->isp_gbspeed = 2;
2717                         } else if (mbs.param[1] == MBGSD_ONEGB) {
2718                                 isp_prt(isp, ISP_LOGINFO, "Chan %d 1Gb link speed", chan);
2719                                 fcp->isp_gbspeed = 1;
2720                         }
2721                 }
2722         }
2723
2724         /*
2725          * Announce ourselves, too.
2726          */
2727         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGCONFIG, topology, chan, (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) fcp->isp_wwpn, fcp->isp_portid, fcp->isp_loopid, isp_fc_toponame(fcp));
2728         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d FC Link Test Complete", chan);
2729         return (0);
2730 }
2731
2732 /*
2733  * Complete the synchronization of our Port Database.
2734  *
2735  * At this point, we've scanned the local loop (if any) and the fabric
2736  * and performed fabric logins on all new devices.
2737  *
2738  * Our task here is to go through our port database and remove any entities
2739  * that are still marked probational (issuing PLOGO for ones which we had
2740  * PLOGI'd into) or are dead.
2741  *
2742  * Our task here is to also check policy to decide whether devices which
2743  * have *changed* in some way should still be kept active. For example,
2744  * if a device has just changed PortID, we can either elect to treat it
2745  * as an old device or as a newly arrived device (and notify the outer
2746  * layer appropriately).
2747  *
2748  * We also do initiator map target id assignment here for new initiator
2749  * devices and refresh old ones ot make sure that they point to the corret
2750  * entities.
2751  */
2752 static int
2753 isp_pdb_sync(ispsoftc_t *isp, int chan)
2754 {
2755         fcparam *fcp = FCPARAM(isp, chan);
2756         fcportdb_t *lp;
2757         uint16_t dbidx;
2758
2759         if (fcp->isp_loopstate == LOOP_READY) {
2760                 return (0);
2761         }
2762
2763         /*
2764          * Make sure we're okay for doing this right now.
2765          */
2766         if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
2767             fcp->isp_loopstate != LOOP_FSCAN_DONE &&
2768             fcp->isp_loopstate != LOOP_LSCAN_DONE) {
2769                 isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d",
2770                     fcp->isp_loopstate);
2771                 return (-1);
2772         }
2773
2774         if (fcp->isp_topo == TOPO_FL_PORT ||
2775             fcp->isp_topo == TOPO_NL_PORT ||
2776             fcp->isp_topo == TOPO_N_PORT) {
2777                 if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
2778                         if (isp_scan_loop(isp, chan) != 0) {
2779                                 isp_prt(isp, ISP_LOGWARN,
2780                                     "isp_pdb_sync: isp_scan_loop failed");
2781                                 return (-1);
2782                         }
2783                 }
2784         }
2785
2786         if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
2787                 if (fcp->isp_loopstate < LOOP_FSCAN_DONE) {
2788                         if (isp_scan_fabric(isp, chan) != 0) {
2789                                 isp_prt(isp, ISP_LOGWARN,
2790                                     "isp_pdb_sync: isp_scan_fabric failed");
2791                                 return (-1);
2792                         }
2793                 }
2794         }
2795
2796         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2797             "Chan %d Synchronizing PDBs", chan);
2798
2799         fcp->isp_loopstate = LOOP_SYNCING_PDB;
2800
2801         for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
2802                 lp = &fcp->portdb[dbidx];
2803
2804                 if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode) {
2805                         continue;
2806                 }
2807
2808                 if (lp->state == FC_PORTDB_STATE_VALID) {
2809                         if (dbidx != FL_ID) {
2810                                 isp_prt(isp,
2811                                     ISP_LOGERR, "portdb idx %d already valid",
2812                                     dbidx);
2813                         }
2814                         continue;
2815                 }
2816
2817                 switch (lp->state) {
2818                 case FC_PORTDB_STATE_PROBATIONAL:
2819                 case FC_PORTDB_STATE_DEAD:
2820                         /*
2821                          * It's up to the outer layers to clear isp_dev_map.
2822                          */
2823                         lp->state = FC_PORTDB_STATE_NIL;
2824                         isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
2825                         if (lp->autologin == 0) {
2826                                 (void) isp_plogx(isp, chan, lp->handle,
2827                                     lp->portid,
2828                                     PLOGX_FLG_CMD_LOGO |
2829                                     PLOGX_FLG_IMPLICIT |
2830                                     PLOGX_FLG_FREE_NPHDL, 0);
2831                         } else {
2832                                 lp->autologin = 0;
2833                         }
2834                         lp->new_roles = 0;
2835                         lp->new_portid = 0;
2836                         /*
2837                          * Note that we might come out of this with our state
2838                          * set to FC_PORTDB_STATE_ZOMBIE.
2839                          */
2840                         break;
2841                 case FC_PORTDB_STATE_NEW:
2842                         /*
2843                          * It's up to the outer layers to assign a virtual
2844                          * target id in isp_dev_map (if any).
2845                          */
2846                         lp->portid = lp->new_portid;
2847                         lp->roles = lp->new_roles;
2848                         lp->state = FC_PORTDB_STATE_VALID;
2849                         isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
2850                         lp->new_roles = 0;
2851                         lp->new_portid = 0;
2852                         lp->reserved = 0;
2853                         lp->new_reserved = 0;
2854                         break;
2855                 case FC_PORTDB_STATE_CHANGED:
2856 /*
2857  * XXXX FIX THIS
2858  */
2859                         lp->state = FC_PORTDB_STATE_VALID;
2860                         isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
2861                         lp->new_roles = 0;
2862                         lp->new_portid = 0;
2863                         lp->reserved = 0;
2864                         lp->new_reserved = 0;
2865                         break;
2866                 case FC_PORTDB_STATE_PENDING_VALID:
2867                         lp->portid = lp->new_portid;
2868                         lp->roles = lp->new_roles;
2869                         if (lp->dev_map_idx) {
2870                                 int t = lp->dev_map_idx - 1;
2871                                 fcp->isp_dev_map[t] = dbidx + 1;
2872                         }
2873                         lp->state = FC_PORTDB_STATE_VALID;
2874                         isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
2875                         if (dbidx != FL_ID) {
2876                                 lp->new_roles = 0;
2877                                 lp->new_portid = 0;
2878                         }
2879                         lp->reserved = 0;
2880                         lp->new_reserved = 0;
2881                         break;
2882                 case FC_PORTDB_STATE_ZOMBIE:
2883                         break;
2884                 default:
2885                         isp_prt(isp, ISP_LOGWARN,
2886                             "isp_scan_loop: state %d for idx %d",
2887                             lp->state, dbidx);
2888                         isp_dump_portdb(isp, chan);
2889                 }
2890         }
2891
2892         /*
2893          * If we get here, we've for sure seen not only a valid loop
2894          * but know what is or isn't on it, so mark this for usage
2895          * in isp_start.
2896          */
2897         fcp->loop_seen_once = 1;
2898         fcp->isp_loopstate = LOOP_READY;
2899         return (0);
2900 }
2901
2902 /*
2903  * Scan local loop for devices.
2904  */
2905 static int
2906 isp_scan_loop(ispsoftc_t *isp, int chan)
2907 {
2908         fcportdb_t *lp, tmp;
2909         fcparam *fcp = FCPARAM(isp, chan);
2910         int i;
2911         isp_pdb_t pdb;
2912         uint16_t handle, lim = 0;
2913
2914         if (fcp->isp_fwstate < FW_READY ||
2915             fcp->isp_loopstate < LOOP_PDB_RCVD) {
2916                 return (-1);
2917         }
2918
2919         if (fcp->isp_loopstate > LOOP_SCANNING_LOOP) {
2920                 return (0);
2921         }
2922
2923         /*
2924          * Check our connection topology.
2925          *
2926          * If we're a public or private loop, we scan 0..125 as handle values.
2927          * The firmware has (typically) peformed a PLOGI for us. We skip this
2928          * step if we're a ISP_24XX in NP-IV mode.
2929          *
2930          * If we're a N-port connection, we treat this is a short loop (0..1).
2931          */
2932         switch (fcp->isp_topo) {
2933         case TOPO_NL_PORT:
2934                 lim = LOCAL_LOOP_LIM;
2935                 break;
2936         case TOPO_FL_PORT:
2937                 if (IS_24XX(isp) && isp->isp_nchan > 1) {
2938                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2939                             "Chan %d Skipping Local Loop Scan", chan);
2940                         fcp->isp_loopstate = LOOP_LSCAN_DONE;
2941                         return (0);
2942                 }
2943                 lim = LOCAL_LOOP_LIM;
2944                 break;
2945         case TOPO_N_PORT:
2946                 lim = 2;
2947                 break;
2948         default:
2949                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2950                     "Chan %d no loop topology to scan", chan);
2951                 fcp->isp_loopstate = LOOP_LSCAN_DONE;
2952                 return (0);
2953         }
2954
2955         fcp->isp_loopstate = LOOP_SCANNING_LOOP;
2956
2957         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2958             "Chan %d FC scan loop 0..%d", chan, lim-1);
2959
2960
2961         /*
2962          * Run through the list and get the port database info for each one.
2963          */
2964         for (handle = 0; handle < lim; handle++) {
2965                 int r;
2966                 /*
2967                  * Don't scan "special" ids.
2968                  */
2969                 if (handle >= FL_ID && handle <= SNS_ID) {
2970                         continue;
2971                 }
2972                 if (ISP_CAP_2KLOGIN(isp)) {
2973                         if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
2974                                 continue;
2975                         }
2976                 }
2977                 /*
2978                  * In older cards with older f/w GET_PORT_DATABASE has been
2979                  * known to hang. This trick gets around that problem.
2980                  */
2981                 if (IS_2100(isp) || IS_2200(isp)) {
2982                         uint64_t node_wwn = isp_get_wwn(isp, chan, handle, 1);
2983                         if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2984                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2985                                     "Chan %d FC scan loop DONE (bad)", chan);
2986                                 return (-1);
2987                         }
2988                         if (node_wwn == INI_NONE) {
2989                                 continue;
2990                         }
2991                 }
2992
2993                 /*
2994                  * Get the port database entity for this index.
2995                  */
2996                 r = isp_getpdb(isp, chan, handle, &pdb, 1);
2997                 if (r != 0) {
2998                         isp_prt(isp, ISP_LOGDEBUG1,
2999                             "Chan %d FC scan loop handle %d returned %x",
3000                             chan, handle, r);
3001                         if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
3002                                 ISP_MARK_PORTDB(isp, chan, 1);
3003                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3004                                     "Chan %d FC scan loop DONE (bad)", chan);
3005                                 return (-1);
3006                         }
3007                         continue;
3008                 }
3009
3010                 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
3011                         ISP_MARK_PORTDB(isp, chan, 1);
3012                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3013                             "Chan %d FC scan loop DONE (bad)", chan);
3014                         return (-1);
3015                 }
3016
3017                 /*
3018                  * On *very* old 2100 firmware we would end up sometimes
3019                  * with the firmware returning the port database entry
3020                  * for something else. We used to restart this, but
3021                  * now we just punt.
3022                  */
3023                 if (IS_2100(isp) && pdb.handle != handle) {
3024                         isp_prt(isp, ISP_LOGWARN,
3025                             "Chan %d cannot synchronize port database", chan);
3026                         ISP_MARK_PORTDB(isp, chan, 1);
3027                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3028                             "Chan %d FC scan loop DONE (bad)", chan);
3029                         return (-1);
3030                 }
3031
3032                 /*
3033                  * Save the pertinent info locally.
3034                  */
3035                 MAKE_WWN_FROM_NODE_NAME(tmp.node_wwn, pdb.nodename);
3036                 MAKE_WWN_FROM_NODE_NAME(tmp.port_wwn, pdb.portname);
3037                 tmp.roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
3038                 tmp.portid = pdb.portid;
3039                 tmp.handle = pdb.handle;
3040
3041                 /*
3042                  * Check to make sure it's still a valid entry. The 24XX seems
3043                  * to return a portid but not a WWPN/WWNN or role for devices
3044                  * which shift on a loop.
3045                  */
3046                 if (tmp.node_wwn == 0 || tmp.port_wwn == 0 || tmp.portid == 0) {
3047                         int a, b, c;
3048                         a = (tmp.node_wwn == 0);
3049                         b = (tmp.port_wwn == 0);
3050                         c = (tmp.portid == 0);
3051                         if (a == 0 && b == 0) {
3052                                 tmp.node_wwn =
3053                                     isp_get_wwn(isp, chan, handle, 1);
3054                                 tmp.port_wwn =
3055                                     isp_get_wwn(isp, chan, handle, 0);
3056                                 if (tmp.node_wwn && tmp.port_wwn) {
3057                                         isp_prt(isp, ISP_LOGINFO, "DODGED!");
3058                                         goto cont;
3059                                 }
3060                         }
3061                         isp_prt(isp, ISP_LOGWARN,
3062                             "Chan %d bad pdb (%1d%1d%1d) @ handle 0x%x", chan,
3063                             a, b, c, handle);
3064                         isp_dump_portdb(isp, chan);
3065                         continue;
3066                 }
3067   cont:
3068
3069                 /*
3070                  * Now search the entire port database
3071                  * for the same Port and Node WWN.
3072                  */
3073                 for (i = 0; i < MAX_FC_TARG; i++) {
3074                         lp = &fcp->portdb[i];
3075
3076                         if (lp->state == FC_PORTDB_STATE_NIL ||
3077                             lp->target_mode) {
3078                                 continue;
3079                         }
3080                         if (lp->node_wwn != tmp.node_wwn) {
3081                                 continue;
3082                         }
3083                         if (lp->port_wwn != tmp.port_wwn) {
3084                                 continue;
3085                         }
3086
3087                         /*
3088                          * Okay- we've found a non-nil entry that matches.
3089                          * Check to make sure it's probational or a zombie.
3090                          */
3091                         if (lp->state != FC_PORTDB_STATE_PROBATIONAL &&
3092                             lp->state != FC_PORTDB_STATE_ZOMBIE) {
3093                                 isp_prt(isp, ISP_LOGERR,
3094                                     "Chan %d [%d] not probational/zombie (0x%x)",
3095                                     chan, i, lp->state);
3096                                 isp_dump_portdb(isp, chan);
3097                                 ISP_MARK_PORTDB(isp, chan, 1);
3098                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3099                                     "Chan %d FC scan loop DONE (bad)", chan);
3100                                 return (-1);
3101                         }
3102
3103                         /*
3104                          * Mark the device as something the f/w logs into
3105                          * automatically.
3106                          */
3107                         lp->autologin = 1;
3108
3109                         /*
3110                          * Check to make see if really still the same
3111                          * device. If it is, we mark it pending valid.
3112                          */
3113                         if (lp->portid == tmp.portid &&
3114                             lp->handle == tmp.handle &&
3115                             lp->roles == tmp.roles) {
3116                                 lp->new_portid = tmp.portid;
3117                                 lp->new_roles = tmp.roles;
3118                                 lp->state = FC_PORTDB_STATE_PENDING_VALID;
3119                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3120                                     "Chan %d Loop Port 0x%06x@0x%04x Pending "
3121                                     "Valid", chan, tmp.portid, tmp.handle);
3122                                 break;
3123                         }
3124
3125                         /*
3126                          * We can wipe out the old handle value
3127                          * here because it's no longer valid.
3128                          */
3129                         lp->handle = tmp.handle;
3130
3131                         /*
3132                          * Claim that this has changed and let somebody else
3133                          * decide what to do.
3134                          */
3135                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3136                             "Chan %d Loop Port 0x%06x@0x%04x changed",
3137                             chan, tmp.portid, tmp.handle);
3138                         lp->state = FC_PORTDB_STATE_CHANGED;
3139                         lp->new_portid = tmp.portid;
3140                         lp->new_roles = tmp.roles;
3141                         break;
3142                 }
3143
3144                 /*
3145                  * Did we find and update an old entry?
3146                  */
3147                 if (i < MAX_FC_TARG) {
3148                         continue;
3149                 }
3150
3151                 /*
3152                  * Ah. A new device entry. Find an empty slot
3153                  * for it and save info for later disposition.
3154                  */
3155                 for (i = 0; i < MAX_FC_TARG; i++) {
3156                         if (fcp->portdb[i].target_mode) {
3157                                 continue;
3158                         }
3159                         if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL) {
3160                                 break;
3161                         }
3162                 }
3163                 if (i == MAX_FC_TARG) {
3164                         isp_prt(isp, ISP_LOGERR,
3165                             "Chan %d out of portdb entries", chan);
3166                         continue;
3167                 }
3168                 lp = &fcp->portdb[i];
3169
3170                 ISP_MEMZERO(lp, sizeof (fcportdb_t));
3171                 lp->autologin = 1;
3172                 lp->state = FC_PORTDB_STATE_NEW;
3173                 lp->new_portid = tmp.portid;
3174                 lp->new_roles = tmp.roles;
3175                 lp->handle = tmp.handle;
3176                 lp->port_wwn = tmp.port_wwn;
3177                 lp->node_wwn = tmp.node_wwn;
3178                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3179                     "Chan %d Loop Port 0x%06x@0x%04x is New Entry",
3180                     chan, tmp.portid, tmp.handle);
3181         }
3182         fcp->isp_loopstate = LOOP_LSCAN_DONE;
3183         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3184             "Chan %d FC scan loop DONE", chan);
3185         return (0);
3186 }
3187
3188 /*
3189  * Scan the fabric for devices and add them to our port database.
3190  *
3191  * Use the GID_FT command to get all Port IDs for FC4 SCSI devices it knows.
3192  *
3193  * For 2100-23XX cards, we can use the SNS mailbox command to pass simple
3194  * name server commands to the switch management server via the QLogic f/w.
3195  *
3196  * For the 24XX card, we have to use CT-Pass through run via the Execute IOCB
3197  * mailbox command.
3198  *
3199  * The net result is to leave the list of Port IDs setting untranslated in
3200  * offset IGPOFF of the FC scratch area, whereupon we'll canonicalize it to
3201  * host order at OGPOFF.
3202  */
3203
3204 /*
3205  * Take less than half of our scratch area to store Port IDs
3206  */
3207 #define GIDLEN  ((ISP_FC_SCRLEN >> 1) - 16 - SNS_GID_FT_REQ_SIZE)
3208 #define NGENT   ((GIDLEN - 16) >> 2)
3209
3210 #define IGPOFF  (2 * QENTRY_LEN)
3211 #define OGPOFF  (ISP_FC_SCRLEN >> 1)
3212 #define ZTXOFF  (ISP_FC_SCRLEN - (1 * QENTRY_LEN))
3213 #define CTXOFF  (ISP_FC_SCRLEN - (2 * QENTRY_LEN))
3214 #define XTXOFF  (ISP_FC_SCRLEN - (3 * QENTRY_LEN))
3215
3216 static int
3217 isp_gid_ft_sns(ispsoftc_t *isp, int chan)
3218 {
3219         union {
3220                 sns_gid_ft_req_t _x;
3221                 uint8_t _y[SNS_GID_FT_REQ_SIZE];
3222         } un;
3223         fcparam *fcp = FCPARAM(isp, chan);
3224         sns_gid_ft_req_t *rq = &un._x;
3225         mbreg_t mbs;
3226
3227         isp_prt(isp, ISP_LOGDEBUG0,
3228             "Chan %d scanning fabric (GID_FT) via SNS", chan);
3229
3230         ISP_MEMZERO(rq, SNS_GID_FT_REQ_SIZE);
3231         rq->snscb_rblen = GIDLEN >> 1;
3232         rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + IGPOFF);
3233         rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + IGPOFF);
3234         rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + IGPOFF);
3235         rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + IGPOFF);
3236         rq->snscb_sblen = 6;
3237         rq->snscb_cmd = SNS_GID_FT;
3238         rq->snscb_mword_div_2 = NGENT;
3239         rq->snscb_fc4_type = FC4_SCSI;
3240
3241         isp_put_gid_ft_request(isp, rq, fcp->isp_scratch);
3242         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
3243
3244         MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 10000000);
3245         mbs.param[0] = MBOX_SEND_SNS;
3246         mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
3247         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
3248         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
3249         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
3250         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
3251         isp_mboxcmd(isp, &mbs);
3252         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3253                 if (mbs.param[0] == MBOX_INVALID_COMMAND) {
3254                         return (1);
3255                 } else {
3256                         return (-1);
3257                 }
3258         }
3259         return (0);
3260 }
3261
3262 static int
3263 isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
3264 {
3265         mbreg_t mbs;
3266         fcparam *fcp = FCPARAM(isp, chan);
3267         union {
3268                 isp_ct_pt_t plocal;
3269                 ct_hdr_t clocal;
3270                 uint8_t q[QENTRY_LEN];
3271         } un;
3272         isp_ct_pt_t *pt;
3273         ct_hdr_t *ct;
3274         uint32_t *rp;
3275         uint8_t *scp = fcp->isp_scratch;
3276
3277         isp_prt(isp, ISP_LOGDEBUG0,
3278             "Chan %d scanning fabric (GID_FT) via CT", chan);
3279
3280         if (!IS_24XX(isp)) {
3281                 return (1);
3282         }
3283
3284         /*
3285          * Build a Passthrough IOCB in memory.
3286          */
3287         pt = &un.plocal;
3288         ISP_MEMZERO(un.q, QENTRY_LEN);
3289         pt->ctp_header.rqs_entry_count = 1;
3290         pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
3291         pt->ctp_handle = 0xffffffff;
3292         pt->ctp_nphdl = fcp->isp_sns_hdl;
3293         pt->ctp_cmd_cnt = 1;
3294         pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
3295         pt->ctp_time = 30;
3296         pt->ctp_rsp_cnt = 1;
3297         pt->ctp_rsp_bcnt = GIDLEN;
3298         pt->ctp_cmd_bcnt = sizeof (*ct) + sizeof (uint32_t);
3299         pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
3300         pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
3301         pt->ctp_dataseg[0].ds_count = sizeof (*ct) + sizeof (uint32_t);
3302         pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
3303         pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
3304         pt->ctp_dataseg[1].ds_count = GIDLEN;
3305         if (isp->isp_dblev & ISP_LOGDEBUG1) {
3306                 isp_print_bytes(isp, "ct IOCB", QENTRY_LEN, pt);
3307         }
3308         isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
3309
3310         /*
3311          * Build the CT header and command in memory.
3312          *
3313          * Note that the CT header has to end up as Big Endian format in memory.
3314          */
3315         ct = &un.clocal;
3316         ISP_MEMZERO(ct, sizeof (*ct));
3317         ct->ct_revision = CT_REVISION;
3318         ct->ct_fcs_type = CT_FC_TYPE_FC;
3319         ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
3320         ct->ct_cmd_resp = SNS_GID_FT;
3321         ct->ct_bcnt_resid = (GIDLEN - 16) >> 2;
3322
3323         isp_put_ct_hdr(isp, ct, (ct_hdr_t *) &scp[XTXOFF]);
3324         rp = (uint32_t *) &scp[XTXOFF+sizeof (*ct)];
3325         ISP_IOZPUT_32(isp, FC4_SCSI, rp);
3326         if (isp->isp_dblev & ISP_LOGDEBUG1) {
3327                 isp_print_bytes(isp, "CT HDR + payload after put",
3328                     sizeof (*ct) + sizeof (uint32_t), &scp[XTXOFF]);
3329         }
3330         ISP_MEMZERO(&scp[ZTXOFF], QENTRY_LEN);
3331         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
3332         mbs.param[1] = QENTRY_LEN;
3333         mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
3334         mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
3335         mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
3336         mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
3337         MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN);
3338         isp_mboxcmd(isp, &mbs);
3339         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3340                 return (-1);
3341         }
3342         MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN);
3343         pt = &un.plocal;
3344         isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
3345         if (isp->isp_dblev & ISP_LOGDEBUG1) {
3346                 isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
3347         }
3348
3349         if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) {
3350                 isp_prt(isp, ISP_LOGWARN,
3351                     "Chan %d ISP GID FT CT Passthrough returned 0x%x",
3352                     chan, pt->ctp_status);
3353                 return (-1);
3354         }
3355         MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN + 16);
3356         if (isp->isp_dblev & ISP_LOGDEBUG1) {
3357                 isp_print_bytes(isp, "CT response", GIDLEN+16, &scp[IGPOFF]);
3358         }
3359         return (0);
3360 }
3361
3362 static int
3363 isp_scan_fabric(ispsoftc_t *isp, int chan)
3364 {
3365         fcparam *fcp = FCPARAM(isp, chan);
3366         uint32_t portid;
3367         uint16_t handle, oldhandle, loopid;
3368         isp_pdb_t pdb;
3369         int portidx, portlim, r;
3370         sns_gid_ft_rsp_t *rs0, *rs1;
3371
3372         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3373             "Chan %d FC Scan Fabric", chan);
3374         if (fcp->isp_fwstate != FW_READY ||
3375             fcp->isp_loopstate < LOOP_LSCAN_DONE) {
3376                 return (-1);
3377         }
3378         if (fcp->isp_loopstate > LOOP_SCANNING_FABRIC) {
3379                 return (0);
3380         }
3381         if (fcp->isp_topo != TOPO_FL_PORT && fcp->isp_topo != TOPO_F_PORT) {
3382                 fcp->isp_loopstate = LOOP_FSCAN_DONE;
3383                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3384                     "Chan %d FC Scan Fabric Done (no fabric)", chan);
3385                 return (0);
3386         }
3387
3388         fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
3389         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
3390                 isp_prt(isp, ISP_LOGERR, sacq);
3391                 ISP_MARK_PORTDB(isp, chan, 1);
3392                 return (-1);
3393         }
3394         if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3395                 FC_SCRATCH_RELEASE(isp, chan);
3396                 ISP_MARK_PORTDB(isp, chan, 1);
3397                 return (-1);
3398         }
3399
3400         /*
3401          * Make sure we still are logged into the fabric controller.
3402          */
3403         if (IS_24XX(isp)) {     /* XXX SHOULDN'T THIS BE TRUE FOR 2K F/W? XXX */
3404                 loopid = NPH_FL_ID;
3405         } else {
3406                 loopid = FL_ID;
3407         }
3408         r = isp_getpdb(isp, chan, loopid, &pdb, 0);
3409         if (r == MBOX_NOT_LOGGED_IN) {
3410                 isp_dump_chip_portdb(isp, chan, 0);
3411         }
3412         if (r) {
3413                 fcp->isp_loopstate = LOOP_PDB_RCVD;
3414                 FC_SCRATCH_RELEASE(isp, chan);
3415                 ISP_MARK_PORTDB(isp, chan, 1);
3416                 return (-1);
3417         }
3418
3419         if (IS_24XX(isp)) {
3420                 r = isp_gid_ft_ct_passthru(isp, chan);
3421         } else {
3422                 r = isp_gid_ft_sns(isp, chan);
3423         }
3424
3425         if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3426                 FC_SCRATCH_RELEASE(isp, chan);
3427                 ISP_MARK_PORTDB(isp, chan, 1);
3428                 return (-1);
3429         }
3430
3431         if (r > 0) {
3432                 fcp->isp_loopstate = LOOP_FSCAN_DONE;
3433                 FC_SCRATCH_RELEASE(isp, chan);
3434                 return (0);
3435         } else if (r < 0) {
3436                 fcp->isp_loopstate = LOOP_PDB_RCVD;     /* try again */
3437                 FC_SCRATCH_RELEASE(isp, chan);
3438                 return (0);
3439         }
3440
3441         MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
3442         rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF);
3443         rs1 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+OGPOFF);
3444         isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
3445         if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3446                 FC_SCRATCH_RELEASE(isp, chan);
3447                 ISP_MARK_PORTDB(isp, chan, 1);
3448                 return (-1);
3449         }
3450         if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) {
3451                 int level;
3452                 if (rs1->snscb_cthdr.ct_reason == 9 &&
3453                     rs1->snscb_cthdr.ct_explanation == 7) {
3454                         level = ISP_LOGSANCFG|ISP_LOGDEBUG0;
3455                 } else {
3456                         level = ISP_LOGWARN;
3457                 }
3458                 isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_FT"
3459                     " (Reason=0x%x Expl=0x%x)", chan,
3460                     rs1->snscb_cthdr.ct_reason,
3461                     rs1->snscb_cthdr.ct_explanation);
3462                 FC_SCRATCH_RELEASE(isp, chan);
3463                 fcp->isp_loopstate = LOOP_FSCAN_DONE;
3464                 return (0);
3465         }
3466
3467
3468         /*
3469          * If we get this far, we certainly still have the fabric controller.
3470          */
3471         fcp->portdb[FL_ID].state = FC_PORTDB_STATE_PENDING_VALID;
3472
3473         /*
3474          * Prime the handle we will start using.
3475          */
3476         oldhandle = FCPARAM(isp, 0)->isp_lasthdl;
3477
3478         /*
3479          * Go through the list and remove duplicate port ids.
3480          */
3481
3482         portlim = 0;
3483         portidx = 0;
3484         for (portidx = 0; portidx < NGENT-1; portidx++) {
3485                 if (rs1->snscb_ports[portidx].control & 0x80) {
3486                         break;
3487                 }
3488         }
3489
3490         /*
3491          * If we're not at the last entry, our list wasn't big enough.
3492          */
3493         if ((rs1->snscb_ports[portidx].control & 0x80) == 0) {
3494                 isp_prt(isp, ISP_LOGWARN,
3495                     "fabric too big for scratch area: increase ISP_FC_SCRLEN");
3496         }
3497         portlim = portidx + 1;
3498         isp_prt(isp, ISP_LOGSANCFG,
3499             "Chan %d got %d ports back from name server", chan, portlim);
3500
3501         for (portidx = 0; portidx < portlim; portidx++) {
3502                 int npidx;
3503
3504                 portid =
3505                     ((rs1->snscb_ports[portidx].portid[0]) << 16) |
3506                     ((rs1->snscb_ports[portidx].portid[1]) << 8) |
3507                     ((rs1->snscb_ports[portidx].portid[2]));
3508
3509                 for (npidx = portidx + 1; npidx < portlim; npidx++) {
3510                         uint32_t new_portid =
3511                             ((rs1->snscb_ports[npidx].portid[0]) << 16) |
3512                             ((rs1->snscb_ports[npidx].portid[1]) << 8) |
3513                             ((rs1->snscb_ports[npidx].portid[2]));
3514                         if (new_portid == portid) {
3515                                 break;
3516                         }
3517                 }
3518
3519                 if (npidx < portlim) {
3520                         rs1->snscb_ports[npidx].portid[0] = 0;
3521                         rs1->snscb_ports[npidx].portid[1] = 0;
3522                         rs1->snscb_ports[npidx].portid[2] = 0;
3523                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3524                             "Chan %d removing duplicate PortID 0x%06x"
3525                             " entry from list", chan, portid);
3526                 }
3527         }
3528
3529         /*
3530          * We now have a list of Port IDs for all FC4 SCSI devices
3531          * that the Fabric Name server knows about.
3532          *
3533          * For each entry on this list go through our port database looking
3534          * for probational entries- if we find one, then an old entry is
3535          * maybe still this one. We get some information to find out.
3536          *
3537          * Otherwise, it's a new fabric device, and we log into it
3538          * (unconditionally). After searching the entire database
3539          * again to make sure that we never ever ever ever have more
3540          * than one entry that has the same PortID or the same
3541          * WWNN/WWPN duple, we enter the device into our database.
3542          */
3543
3544         for (portidx = 0; portidx < portlim; portidx++) {
3545                 fcportdb_t *lp;
3546                 uint64_t wwnn, wwpn;
3547                 int dbidx, nr;
3548
3549                 portid =
3550                     ((rs1->snscb_ports[portidx].portid[0]) << 16) |
3551                     ((rs1->snscb_ports[portidx].portid[1]) << 8) |
3552                     ((rs1->snscb_ports[portidx].portid[2]));
3553
3554                 if (portid == 0) {
3555                         isp_prt(isp, ISP_LOGSANCFG,
3556                             "Chan %d skipping null PortID at idx %d",
3557                             chan, portidx);
3558                         continue;
3559                 }
3560
3561                 /*
3562                  * Skip ourselves here and on other channels. If we're
3563                  * multi-id, we can't check the portids in other FCPARAM
3564                  * arenas because the resolutions here aren't synchronized.
3565                  * The best way to do this is to exclude looking at portids
3566                  * that have the same domain and area code as our own
3567                  * portid.
3568                  */
3569                 if (ISP_CAP_MULTI_ID(isp)) {
3570                         if ((portid >> 8) == (fcp->isp_portid >> 8)) {
3571                                 isp_prt(isp, ISP_LOGSANCFG,
3572                                     "Chan %d skip PortID 0x%06x",
3573                                     chan, portid);
3574                                 continue;
3575                         }
3576                 } else if (portid == fcp->isp_portid) {
3577                         isp_prt(isp, ISP_LOGSANCFG,
3578                             "Chan %d skip ourselves on @ PortID 0x%06x",
3579                             chan, portid);
3580                         continue;
3581                 }
3582
3583                 isp_prt(isp, ISP_LOGSANCFG,
3584                     "Chan %d Checking Fabric Port 0x%06x", chan, portid);
3585
3586                 /*
3587                  * We now search our Port Database for any
3588                  * probational entries with this PortID. We don't
3589                  * look for zombies here- only probational
3590                  * entries (we've already logged out of zombies).
3591                  */
3592                 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
3593                         lp = &fcp->portdb[dbidx];
3594
3595                         if (lp->state != FC_PORTDB_STATE_PROBATIONAL ||
3596                             lp->target_mode) {
3597                                 continue;
3598                         }
3599                         if (lp->portid == portid) {
3600                                 break;
3601                         }
3602                 }
3603
3604                 /*
3605                  * We found a probational entry with this Port ID.
3606                  */
3607                 if (dbidx < MAX_FC_TARG) {
3608                         int handle_changed = 0;
3609
3610                         lp = &fcp->portdb[dbidx];
3611
3612                         /*
3613                          * See if we're still logged into it.
3614                          *
3615                          * If we aren't, mark it as a dead device and
3616                          * leave the new portid in the database entry
3617                          * for somebody further along to decide what to
3618                          * do (policy choice).
3619                          *
3620                          * If we are, check to see if it's the same
3621                          * device still (it should be). If for some
3622                          * reason it isn't, mark it as a changed device
3623                          * and leave the new portid and role in the
3624                          * database entry for somebody further along to
3625                          * decide what to do (policy choice).
3626                          *
3627                          */
3628
3629                         r = isp_getpdb(isp, chan, lp->handle, &pdb, 0);
3630                         if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3631                                 FC_SCRATCH_RELEASE(isp, chan);
3632                                 ISP_MARK_PORTDB(isp, chan, 1);
3633                                 return (-1);
3634                         }
3635                         if (r != 0) {
3636                                 lp->new_portid = portid;
3637                                 lp->state = FC_PORTDB_STATE_DEAD;
3638                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3639                                     "Chan %d Fabric Port 0x%06x is dead",
3640                                     chan, portid);
3641                                 continue;
3642                         }
3643
3644
3645                         /*
3646                          * Check to make sure that handle, portid, WWPN and
3647                          * WWNN agree. If they don't, then the association
3648                          * between this PortID and the stated handle has been
3649                          * broken by the firmware.
3650                          */
3651                         MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3652                         MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3653                         if (pdb.handle != lp->handle ||
3654                             pdb.portid != portid ||
3655                             wwpn != lp->port_wwn ||
3656                             wwnn != lp->node_wwn) {
3657                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3658                                     fconf, chan, dbidx, pdb.handle, pdb.portid,
3659                                     (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
3660                                     (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
3661                                     lp->handle, portid,
3662                                     (uint32_t) (lp->node_wwn >> 32),
3663                                     (uint32_t) lp->node_wwn,
3664                                     (uint32_t) (lp->port_wwn >> 32),
3665                                     (uint32_t) lp->port_wwn);
3666                                 /*
3667                                  * Try to re-login to this device using a
3668                                  * new handle. If that fails, mark it dead.
3669                                  *
3670                                  * isp_login_device will check for handle and
3671                                  * portid consistency after re-login.
3672                                  *
3673                                  */
3674                                 if (isp_login_device(isp, chan, portid, &pdb,
3675                                     &oldhandle)) {
3676                                         lp->new_portid = portid;
3677                                         lp->state = FC_PORTDB_STATE_DEAD;
3678                                         if (fcp->isp_loopstate !=
3679                                             LOOP_SCANNING_FABRIC) {
3680                                                 FC_SCRATCH_RELEASE(isp, chan);
3681                                                 ISP_MARK_PORTDB(isp, chan, 1);
3682                                                 return (-1);
3683                                         }
3684                                         continue;
3685                                 }
3686                                 if (fcp->isp_loopstate !=
3687                                     LOOP_SCANNING_FABRIC) {
3688                                         FC_SCRATCH_RELEASE(isp, chan);
3689                                         ISP_MARK_PORTDB(isp, chan, 1);
3690                                         return (-1);
3691                                 }
3692                                 FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
3693                                 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3694                                 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3695                                 if (wwpn != lp->port_wwn ||
3696                                     wwnn != lp->node_wwn) {
3697                                         isp_prt(isp, ISP_LOGWARN, "changed WWN"
3698                                             " after relogin");
3699                                         lp->new_portid = portid;
3700                                         lp->state = FC_PORTDB_STATE_DEAD;
3701                                         continue;
3702                                 }
3703
3704                                 lp->handle = pdb.handle;
3705                                 handle_changed++;
3706                         }
3707
3708                         nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
3709
3710                         /*
3711                          * Check to see whether the portid and roles have
3712                          * stayed the same. If they have stayed the same,
3713                          * we believe that this is the same device and it
3714                          * hasn't become disconnected and reconnected, so
3715                          * mark it as pending valid.
3716                          *
3717                          * If they aren't the same, mark the device as a
3718                          * changed device and save the new port id and role
3719                          * and let somebody else decide.
3720                          */
3721
3722                         lp->new_portid = portid;
3723                         lp->new_roles = nr;
3724                         if (pdb.portid != lp->portid || nr != lp->roles ||
3725                             handle_changed) {
3726                                 isp_prt(isp, ISP_LOGSANCFG,
3727                                     "Chan %d Fabric Port 0x%06x changed",
3728                                     chan, portid);
3729                                 lp->state = FC_PORTDB_STATE_CHANGED;
3730                         } else {
3731                                 isp_prt(isp, ISP_LOGSANCFG,
3732                                     "Chan %d Fabric Port 0x%06x "
3733                                     "Now Pending Valid", chan, portid);
3734                                 lp->state = FC_PORTDB_STATE_PENDING_VALID;
3735                         }
3736                         continue;
3737                 }
3738
3739                 /*
3740                  * Ah- a new entry. Search the database again for all non-NIL
3741                  * entries to make sure we never ever make a new database entry
3742                  * with the same port id. While we're at it, mark where the
3743                  * last free entry was.
3744                  */
3745
3746                 dbidx = MAX_FC_TARG;
3747                 for (lp = fcp->portdb; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
3748                         if (lp >= &fcp->portdb[FL_ID] &&
3749                             lp <= &fcp->portdb[SNS_ID]) {
3750                                 continue;
3751                         }
3752                         /*
3753                          * Skip any target mode entries.
3754                          */
3755                         if (lp->target_mode) {
3756                                 continue;
3757                         }
3758                         if (lp->state == FC_PORTDB_STATE_NIL) {
3759                                 if (dbidx == MAX_FC_TARG) {
3760                                         dbidx = lp - fcp->portdb;
3761                                 }
3762                                 continue;
3763                         }
3764                         if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
3765                                 continue;
3766                         }
3767                         if (lp->portid == portid) {
3768                                 break;
3769                         }
3770                 }
3771
3772                 if (lp < &fcp->portdb[MAX_FC_TARG]) {
3773                         isp_prt(isp, ISP_LOGWARN, "Chan %d PortID 0x%06x "
3774                             "already at %d handle %d state %d",
3775                             chan, portid, dbidx, lp->handle, lp->state);
3776                         continue;
3777                 }
3778
3779                 /*
3780                  * We should have the index of the first free entry seen.
3781                  */
3782                 if (dbidx == MAX_FC_TARG) {
3783                         isp_prt(isp, ISP_LOGERR,
3784                             "port database too small to login PortID 0x%06x"
3785                             "- increase MAX_FC_TARG", portid);
3786                         continue;
3787                 }
3788
3789                 /*
3790                  * Otherwise, point to our new home.
3791                  */
3792                 lp = &fcp->portdb[dbidx];
3793
3794                 /*
3795                  * Try to see if we are logged into this device,
3796                  * and maybe log into it.
3797                  *
3798                  * isp_login_device will check for handle and
3799                  * portid consistency after login.
3800                  */
3801                 if (isp_login_device(isp, chan, portid, &pdb, &oldhandle)) {
3802                         if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3803                                 FC_SCRATCH_RELEASE(isp, chan);
3804                                 ISP_MARK_PORTDB(isp, chan, 1);
3805                                 return (-1);
3806                         }
3807                         continue;
3808                 }
3809                 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3810                         FC_SCRATCH_RELEASE(isp, chan);
3811                         ISP_MARK_PORTDB(isp, chan, 1);
3812                         return (-1);
3813                 }
3814                 FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
3815
3816                 handle = pdb.handle;
3817                 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3818                 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3819                 nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
3820
3821                 /*
3822                  * And go through the database *one* more time to make sure
3823                  * that we do not make more than one entry that has the same
3824                  * WWNN/WWPN duple
3825                  */
3826                 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
3827                         if (dbidx >= FL_ID && dbidx <= SNS_ID) {
3828                                 continue;
3829                         }
3830                         if (fcp->portdb[dbidx].target_mode) {
3831                                 continue;
3832                         }
3833                         if (fcp->portdb[dbidx].node_wwn == wwnn &&
3834                             fcp->portdb[dbidx].port_wwn == wwpn) {
3835                                 break;
3836                         }
3837                 }
3838
3839                 if (dbidx == MAX_FC_TARG) {
3840                         ISP_MEMZERO(lp, sizeof (fcportdb_t));
3841                         lp->handle = handle;
3842                         lp->node_wwn = wwnn;
3843                         lp->port_wwn = wwpn;
3844                         lp->new_portid = portid;
3845                         lp->new_roles = nr;
3846                         lp->state = FC_PORTDB_STATE_NEW;
3847                         isp_prt(isp, ISP_LOGSANCFG,
3848                             "Chan %d Fabric Port 0x%06x is a New Entry",
3849                             chan, portid);
3850                         continue;
3851                 }
3852
3853                 if (fcp->portdb[dbidx].state != FC_PORTDB_STATE_ZOMBIE) {
3854                         isp_prt(isp, ISP_LOGWARN,
3855                             "Chan %d PortID 0x%x 0x%08x%08x/0x%08x%08x %ld "
3856                             "already at idx %d, state 0x%x", chan, portid,
3857                             (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
3858                             (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
3859                             (long) (lp - fcp->portdb), dbidx,
3860                             fcp->portdb[dbidx].state);
3861                         continue;
3862                 }
3863
3864                 /*
3865                  * We found a zombie entry that matches us.
3866                  * Revive it. We know that WWN and WWPN
3867                  * are the same. For fabric devices, we
3868                  * don't care that handle is different
3869                  * as we assign that. If role or portid
3870                  * are different, it maybe a changed device.
3871                  */
3872                 lp = &fcp->portdb[dbidx];
3873                 lp->handle = handle;
3874                 lp->new_portid = portid;
3875                 lp->new_roles = nr;
3876                 if (lp->portid != portid || lp->roles != nr) {
3877                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3878                             "Chan %d Zombie Fabric Port 0x%06x Now Changed",
3879                             chan, portid);
3880                         lp->state = FC_PORTDB_STATE_CHANGED;
3881                 } else {
3882                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3883                             "Chan %d Zombie Fabric Port 0x%06x "
3884                             "Now Pending Valid", chan, portid);
3885                         lp->state = FC_PORTDB_STATE_PENDING_VALID;
3886                 }
3887         }
3888
3889         FC_SCRATCH_RELEASE(isp, chan);
3890         if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3891                 ISP_MARK_PORTDB(isp, chan, 1);
3892                 return (-1);
3893         }
3894         fcp->isp_loopstate = LOOP_FSCAN_DONE;
3895         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3896             "Chan %d FC Scan Fabric Done", chan);
3897         return (0);
3898 }
3899
3900 /*
3901  * Find an unused handle and try and use to login to a port.
3902  */
3903 static int
3904 isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p,
3905     uint16_t *ohp)
3906 {
3907         int lim, i, r;
3908         uint16_t handle;
3909
3910         if (ISP_CAP_2KLOGIN(isp)) {
3911                 lim = NPH_MAX_2K;
3912         } else {
3913                 lim = NPH_MAX;
3914         }
3915
3916         handle = isp_nxt_handle(isp, chan, *ohp);
3917         for (i = 0; i < lim; i++) {
3918                 /*
3919                  * See if we're still logged into something with
3920                  * this handle and that something agrees with this
3921                  * port id.
3922                  */
3923                 r = isp_getpdb(isp, chan, handle, p, 0);
3924                 if (r == 0 && p->portid != portid) {
3925                         (void) isp_plogx(isp, chan, handle, portid,
3926                             PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT, 1);
3927                 } else if (r == 0) {
3928                         break;
3929                 }
3930                 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3931                         return (-1);
3932                 }
3933                 /*
3934                  * Now try and log into the device
3935                  */
3936                 r = isp_plogx(isp, chan, handle, portid,
3937                     PLOGX_FLG_CMD_PLOGI, 1);
3938                 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3939                         return (-1);
3940                 }
3941                 if (r == 0) {
3942                         *ohp = handle;
3943                         break;
3944                 } else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
3945                         handle = r >> 16;
3946                         break;
3947                 } else if (r != MBOX_LOOP_ID_USED) {
3948                         i = lim;
3949                         break;
3950                 } else if (r == MBOX_TIMEOUT) {
3951                         return (-1);
3952                 } else {
3953                         *ohp = handle;
3954                         handle = isp_nxt_handle(isp, chan, *ohp);
3955                 }
3956         }
3957
3958         if (i == lim) {
3959                 isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed",
3960                     chan, portid);
3961                 return (-1);
3962         }
3963
3964         /*
3965          * If we successfully logged into it, get the PDB for it
3966          * so we can crosscheck that it is still what we think it
3967          * is and that we also have the role it plays
3968          */
3969         r = isp_getpdb(isp, chan, handle, p, 0);
3970         if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3971                 return (-1);
3972         }
3973         if (r != 0) {
3974                 isp_prt(isp, ISP_LOGERR,
3975                     "Chan %d new device 0x%06x@0x%x disappeared",
3976                     chan, portid, handle);
3977                 return (-1);
3978         }
3979
3980         if (p->handle != handle || p->portid != portid) {
3981                 isp_prt(isp, ISP_LOGERR,
3982                     "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
3983                     chan, portid, handle, p->portid, p->handle);
3984                 return (-1);
3985         }
3986         return (0);
3987 }
3988
3989 static int
3990 isp_register_fc4_type(ispsoftc_t *isp, int chan)
3991 {
3992         fcparam *fcp = FCPARAM(isp, chan);
3993         uint8_t local[SNS_RFT_ID_REQ_SIZE];
3994         sns_screq_t *reqp = (sns_screq_t *) local;
3995         mbreg_t mbs;
3996
3997         ISP_MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
3998         reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
3999         reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
4000         reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
4001         reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
4002         reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
4003         reqp->snscb_sblen = 22;
4004         reqp->snscb_data[0] = SNS_RFT_ID;
4005         reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
4006         reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
4007         reqp->snscb_data[6] = (1 << FC4_SCSI);
4008         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4009                 isp_prt(isp, ISP_LOGERR, sacq);
4010                 return (-1);
4011         }
4012         isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
4013         MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 1000000);
4014         mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
4015         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4016         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4017         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4018         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4019         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE);
4020         isp_mboxcmd(isp, &mbs);
4021         FC_SCRATCH_RELEASE(isp, chan);
4022         if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
4023                 return (0);
4024         } else {
4025                 return (-1);
4026         }
4027 }
4028
4029 static int
4030 isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
4031 {
4032         mbreg_t mbs;
4033         fcparam *fcp = FCPARAM(isp, chan);
4034         union {
4035                 isp_ct_pt_t plocal;
4036                 rft_id_t clocal;
4037                 uint8_t q[QENTRY_LEN];
4038         } un;
4039         isp_ct_pt_t *pt;
4040         ct_hdr_t *ct;
4041         rft_id_t *rp;
4042         uint8_t *scp = fcp->isp_scratch;
4043
4044         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4045                 isp_prt(isp, ISP_LOGERR, sacq);
4046                 return (-1);
4047         }
4048
4049         /*
4050          * Build a Passthrough IOCB in memory.
4051          */
4052         ISP_MEMZERO(un.q, QENTRY_LEN);
4053         pt = &un.plocal;
4054         pt->ctp_header.rqs_entry_count = 1;
4055         pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
4056         pt->ctp_handle = 0xffffffff;
4057         pt->ctp_nphdl = fcp->isp_sns_hdl;
4058         pt->ctp_cmd_cnt = 1;
4059         pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
4060         pt->ctp_time = 1;
4061         pt->ctp_rsp_cnt = 1;
4062         pt->ctp_rsp_bcnt = sizeof (ct_hdr_t);
4063         pt->ctp_cmd_bcnt = sizeof (rft_id_t);
4064         pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
4065         pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
4066         pt->ctp_dataseg[0].ds_count = sizeof (rft_id_t);
4067         pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
4068         pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
4069         pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t);
4070         isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
4071         if (isp->isp_dblev & ISP_LOGDEBUG1) {
4072                 isp_print_bytes(isp, "IOCB CT Request", QENTRY_LEN, pt);
4073         }
4074
4075         /*
4076          * Build the CT header and command in memory.
4077          *
4078          * Note that the CT header has to end up as Big Endian format in memory.
4079          */
4080         ISP_MEMZERO(&un.clocal, sizeof (un.clocal));
4081         ct = &un.clocal.rftid_hdr;
4082         ct->ct_revision = CT_REVISION;
4083         ct->ct_fcs_type = CT_FC_TYPE_FC;
4084         ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
4085         ct->ct_cmd_resp = SNS_RFT_ID;
4086         ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
4087         rp = &un.clocal;
4088         rp->rftid_portid[0] = fcp->isp_portid >> 16;
4089         rp->rftid_portid[1] = fcp->isp_portid >> 8;
4090         rp->rftid_portid[2] = fcp->isp_portid;
4091         rp->rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
4092         isp_put_rft_id(isp, rp, (rft_id_t *) &scp[XTXOFF]);
4093         if (isp->isp_dblev & ISP_LOGDEBUG1) {
4094                 isp_print_bytes(isp, "CT Header", QENTRY_LEN, &scp[XTXOFF]);
4095         }
4096
4097         ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
4098
4099         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 1000000);
4100         mbs.param[1] = QENTRY_LEN;
4101         mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
4102         mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
4103         mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
4104         mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
4105         MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN);
4106         isp_mboxcmd(isp, &mbs);
4107         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4108                 FC_SCRATCH_RELEASE(isp, chan);
4109                 return (-1);
4110         }
4111         MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN);
4112         pt = &un.plocal;
4113         isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
4114         if (isp->isp_dblev & ISP_LOGDEBUG1) {
4115                 isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
4116         }
4117         if (pt->ctp_status) {
4118                 FC_SCRATCH_RELEASE(isp, chan);
4119                 isp_prt(isp, ISP_LOGWARN,
4120                     "Chan %d Register FC4 Type CT Passthrough returned 0x%x",
4121                     chan, pt->ctp_status);
4122                 return (1);
4123         }
4124
4125         isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct);
4126         FC_SCRATCH_RELEASE(isp, chan);
4127
4128         if (ct->ct_cmd_resp == LS_RJT) {
4129                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
4130                     "Chan %d Register FC4 Type rejected", chan);
4131                 return (-1);
4132         } else if (ct->ct_cmd_resp == LS_ACC) {
4133                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
4134                     "Chan %d Register FC4 Type accepted", chan);
4135                 return (0);
4136         } else {
4137                 isp_prt(isp, ISP_LOGWARN,
4138                     "Chan %d Register FC4 Type: 0x%x",
4139                     chan, ct->ct_cmd_resp);
4140                 return (-1);
4141         }
4142 }
4143
4144 static uint16_t
4145 isp_nxt_handle(ispsoftc_t *isp, int chan, uint16_t handle)
4146 {
4147         int i;
4148         if (handle == NIL_HANDLE) {
4149                 if (FCPARAM(isp, chan)->isp_topo == TOPO_F_PORT) {
4150                         handle = 0;
4151                 } else {
4152                         handle = SNS_ID+1;
4153                 }
4154         } else {
4155                 handle += 1;
4156                 if (handle >= FL_ID && handle <= SNS_ID) {
4157                         handle = SNS_ID+1;
4158                 }
4159                 if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
4160                         handle = NPH_FL_ID+1;
4161                 }
4162                 if (ISP_CAP_2KLOGIN(isp)) {
4163                         if (handle == NPH_MAX_2K) {
4164                                 handle = 0;
4165                         }
4166                 } else {
4167                         if (handle == NPH_MAX) {
4168                                 handle = 0;
4169                         }
4170                 }
4171         }
4172         if (handle == FCPARAM(isp, chan)->isp_loopid) {
4173                 return (isp_nxt_handle(isp, chan, handle));
4174         }
4175         for (i = 0; i < MAX_FC_TARG; i++) {
4176                 if (FCPARAM(isp, chan)->portdb[i].state ==
4177                     FC_PORTDB_STATE_NIL) {
4178                         continue;
4179                 }
4180                 if (FCPARAM(isp, chan)->portdb[i].handle == handle) {
4181                         return (isp_nxt_handle(isp, chan, handle));
4182                 }
4183         }
4184         return (handle);
4185 }
4186
4187 /*
4188  * Start a command. Locking is assumed done in the caller.
4189  */
4190
4191 int
4192 isp_start(XS_T *xs)
4193 {
4194         ispsoftc_t *isp;
4195         uint32_t handle;
4196         uint8_t local[QENTRY_LEN];
4197         ispreq_t *reqp;
4198         void *cdbp, *qep;
4199         uint16_t *tptr;
4200         int target, dmaresult, hdlidx = 0;
4201
4202         XS_INITERR(xs);
4203         isp = XS_ISP(xs);
4204
4205         /*
4206          * Now make sure we're running.
4207          */
4208
4209         if (isp->isp_state != ISP_RUNSTATE) {
4210                 isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
4211                 XS_SETERR(xs, HBA_BOTCH);
4212                 return (CMD_COMPLETE);
4213         }
4214
4215         /*
4216          * Check command CDB length, etc.. We really are limited to 16 bytes
4217          * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
4218          * but probably only if we're running fairly new firmware (we'll
4219          * let the old f/w choke on an extended command queue entry).
4220          */
4221
4222         if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
4223                 isp_prt(isp, ISP_LOGERR, "unsupported cdb length (%d, CDB[0]=0x%x)", XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
4224                 XS_SETERR(xs, HBA_BOTCH);
4225                 return (CMD_COMPLETE);
4226         }
4227
4228         /*
4229          * Translate the target to device handle as appropriate, checking
4230          * for correct device state as well.
4231          */
4232         target = XS_TGT(xs);
4233         if (IS_FC(isp)) {
4234                 fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
4235
4236                 if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
4237                         XS_SETERR(xs, HBA_SELTIMEOUT);
4238                         return (CMD_COMPLETE);
4239                 }
4240
4241                 /*
4242                  * Try again later.
4243                  */
4244                 if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate != LOOP_READY) {
4245                         return (CMD_RQLATER);
4246                 }
4247
4248                 if (XS_TGT(xs) >= MAX_FC_TARG) {
4249                         XS_SETERR(xs, HBA_SELTIMEOUT);
4250                         return (CMD_COMPLETE);
4251                 }
4252
4253                 hdlidx = fcp->isp_dev_map[XS_TGT(xs)] - 1;
4254                 isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d- hdlidx value %d", XS_TGT(xs), hdlidx);
4255                 if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4256                         XS_SETERR(xs, HBA_SELTIMEOUT);
4257                         return (CMD_COMPLETE);
4258                 }
4259                 if (fcp->portdb[hdlidx].state == FC_PORTDB_STATE_ZOMBIE) {
4260                         return (CMD_RQLATER);
4261                 }
4262                 if (fcp->portdb[hdlidx].state != FC_PORTDB_STATE_VALID) {
4263                         XS_SETERR(xs, HBA_SELTIMEOUT);
4264                         return (CMD_COMPLETE);
4265                 }
4266                 target = fcp->portdb[hdlidx].handle;
4267                 fcp->portdb[hdlidx].dirty = 1;
4268         } else {
4269                 sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
4270                 if ((sdp->role & ISP_ROLE_INITIATOR) == 0) {
4271                         XS_SETERR(xs, HBA_SELTIMEOUT);
4272                         return (CMD_COMPLETE);
4273                 }
4274                 if (sdp->update) {
4275                         isp_spi_update(isp, XS_CHANNEL(xs));
4276                 }
4277         }
4278
4279  start_again:
4280
4281         qep = isp_getrqentry(isp);
4282         if (qep == NULL) {
4283                 isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
4284                 XS_SETERR(xs, HBA_BOTCH);
4285                 return (CMD_EAGAIN);
4286         }
4287         XS_SETERR(xs, HBA_NOERROR);
4288
4289         /*
4290          * Now see if we need to synchronize the ISP with respect to anything.
4291          * We do dual duty here (cough) for synchronizing for busses other
4292          * than which we got here to send a command to.
4293          */
4294         reqp = (ispreq_t *) local;
4295         ISP_MEMZERO(local, QENTRY_LEN);
4296         if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) {
4297                 if (IS_24XX(isp)) {
4298                         isp_marker_24xx_t *m = (isp_marker_24xx_t *) reqp;
4299                         m->mrk_header.rqs_entry_count = 1;
4300                         m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
4301                         m->mrk_modifier = SYNC_ALL;
4302                         isp_put_marker_24xx(isp, m, qep);
4303                 } else {
4304                         isp_marker_t *m = (isp_marker_t *) reqp;
4305                         m->mrk_header.rqs_entry_count = 1;
4306                         m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
4307                         m->mrk_target = (XS_CHANNEL(xs) << 7);  /* bus # */
4308                         m->mrk_modifier = SYNC_ALL;
4309                         isp_put_marker(isp, m, qep);
4310                 }
4311                 ISP_SYNC_REQUEST(isp);
4312                 ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0);
4313                 goto start_again;
4314         }
4315
4316         reqp->req_header.rqs_entry_count = 1;
4317         if (IS_24XX(isp)) {
4318                 reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
4319         } else if (IS_FC(isp)) {
4320                 reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
4321         } else {
4322                 if (XS_CDBLEN(xs) > 12) {
4323                         reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
4324                 } else {
4325                         reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
4326                 }
4327         }
4328         /* reqp->req_header.rqs_flags = 0; */
4329         /* reqp->req_header.rqs_seqno = 0; */
4330         if (IS_24XX(isp)) {
4331                 int ttype;
4332                 if (XS_TAG_P(xs)) {
4333                         ttype = XS_TAG_TYPE(xs);
4334                 } else {
4335                         if (XS_CDBP(xs)[0] == 0x3) {
4336                                 ttype = REQFLAG_HTAG;
4337                         } else {
4338                                 ttype = REQFLAG_STAG;
4339                         }
4340                 }
4341                 if (ttype == REQFLAG_OTAG) {
4342                         ttype = FCP_CMND_TASK_ATTR_ORDERED;
4343                 } else if (ttype == REQFLAG_HTAG) {
4344                         ttype = FCP_CMND_TASK_ATTR_HEAD;
4345                 } else {
4346                         ttype = FCP_CMND_TASK_ATTR_SIMPLE;
4347                 }
4348                 ((ispreqt7_t *)reqp)->req_task_attribute = ttype;
4349         } else if (IS_FC(isp)) {
4350                 /*
4351                  * See comment in isp_intr
4352                  */
4353                 /* XS_SET_RESID(xs, 0); */
4354
4355                 /*
4356                  * Fibre Channel always requires some kind of tag.
4357                  * The Qlogic drivers seem be happy not to use a tag,
4358                  * but this breaks for some devices (IBM drives).
4359                  */
4360                 if (XS_TAG_P(xs)) {
4361                         ((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
4362                 } else {
4363                         /*
4364                          * If we don't know what tag to use, use HEAD OF QUEUE
4365                          * for Request Sense or Simple.
4366                          */
4367                         if (XS_CDBP(xs)[0] == 0x3)      /* REQUEST SENSE */
4368                                 ((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
4369                         else
4370                                 ((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
4371                 }
4372         } else {
4373                 sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
4374                 if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) && XS_TAG_P(xs)) {
4375                         reqp->req_flags = XS_TAG_TYPE(xs);
4376                 }
4377         }
4378         cdbp = reqp->req_cdb;
4379         tptr = &reqp->req_time;
4380
4381         if (IS_SCSI(isp)) {
4382                 reqp->req_target = target | (XS_CHANNEL(xs) << 7);
4383                 reqp->req_lun_trn = XS_LUN(xs);
4384                 reqp->req_cdblen = XS_CDBLEN(xs);
4385         } else if (IS_24XX(isp)) {
4386                 fcportdb_t *lp;
4387
4388                 lp = &FCPARAM(isp, XS_CHANNEL(xs))->portdb[hdlidx];
4389                 ((ispreqt7_t *)reqp)->req_nphdl = target;
4390                 ((ispreqt7_t *)reqp)->req_tidlo = lp->portid;
4391                 ((ispreqt7_t *)reqp)->req_tidhi = lp->portid >> 16;
4392                 ((ispreqt7_t *)reqp)->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs));
4393                 if (XS_LUN(xs) > 256) {
4394                         ((ispreqt7_t *)reqp)->req_lun[0] = XS_LUN(xs) >> 8;
4395                         ((ispreqt7_t *)reqp)->req_lun[0] |= 0x40;
4396                 }
4397                 ((ispreqt7_t *)reqp)->req_lun[1] = XS_LUN(xs);
4398                 cdbp = ((ispreqt7_t *)reqp)->req_cdb;
4399                 tptr = &((ispreqt7_t *)reqp)->req_time;
4400         } else if (ISP_CAP_2KLOGIN(isp)) {
4401                 ((ispreqt2e_t *)reqp)->req_target = target;
4402                 ((ispreqt2e_t *)reqp)->req_scclun = XS_LUN(xs);
4403         } else if (ISP_CAP_SCCFW(isp)) {
4404                 ((ispreqt2_t *)reqp)->req_target = target;
4405                 ((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
4406         } else {
4407                 ((ispreqt2_t *)reqp)->req_target = target;
4408                 ((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
4409         }
4410         ISP_MEMCPY(cdbp, XS_CDBP(xs), XS_CDBLEN(xs));
4411
4412         *tptr = XS_TIME(xs) / 1000;
4413         if (*tptr == 0 && XS_TIME(xs)) {
4414                 *tptr = 1;
4415         }
4416         if (IS_24XX(isp) && *tptr > 0x1999) {
4417                 *tptr = 0x1999;
4418         }
4419
4420         if (isp_allocate_xs(isp, xs, &handle)) {
4421                 isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
4422                 XS_SETERR(xs, HBA_BOTCH);
4423                 return (CMD_EAGAIN);
4424         }
4425         /* Whew. Thankfully the same for type 7 requests */
4426         reqp->req_handle = handle;
4427
4428         /*
4429          * Set up DMA and/or do any platform dependent swizzling of the request entry
4430          * so that the Qlogic F/W understands what is being asked of it.
4431          *
4432          * The callee is responsible for adding all requests at this point.
4433          */
4434         dmaresult = ISP_DMASETUP(isp, xs, reqp);
4435         if (dmaresult != CMD_QUEUED) {
4436                 isp_destroy_handle(isp, handle);
4437                 /*
4438                  * dmasetup sets actual error in packet, and
4439                  * return what we were given to return.
4440                  */
4441                 return (dmaresult);
4442         }
4443         isp_prt(isp, ISP_LOGDEBUG0, "START cmd for %d.%d.%d cmd 0x%x datalen %ld", XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0], (long) XS_XFRLEN(xs));
4444         isp->isp_nactive++;
4445         return (CMD_QUEUED);
4446 }
4447
4448 /*
4449  * isp control
4450  * Locks (ints blocked) assumed held.
4451  */
4452
4453 int
4454 isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
4455 {
4456         XS_T *xs;
4457         mbreg_t *mbr, mbs;
4458         int chan, tgt;
4459         uint32_t handle;
4460         va_list ap;
4461
4462         switch (ctl) {
4463         case ISPCTL_RESET_BUS:
4464                 /*
4465                  * Issue a bus reset.
4466                  */
4467                 if (IS_24XX(isp)) {
4468                         isp_prt(isp, ISP_LOGWARN, "RESET BUS NOT IMPLEMENTED");
4469                         break;
4470                 } else if (IS_FC(isp)) {
4471                         mbs.param[1] = 10;
4472                         chan = 0;
4473                 } else {
4474                         va_start(ap, ctl);
4475                         chan = va_arg(ap, int);
4476                         va_end(ap);
4477                         mbs.param[1] = SDPARAM(isp, chan)->isp_bus_reset_delay;
4478                         if (mbs.param[1] < 2) {
4479                                 mbs.param[1] = 2;
4480                         }
4481                         mbs.param[2] = chan;
4482                 }
4483                 MBSINIT(&mbs, MBOX_BUS_RESET, MBLOGALL, 0);
4484                 ISP_SET_SENDMARKER(isp, chan, 1);
4485                 isp_mboxcmd(isp, &mbs);
4486                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4487                         break;
4488                 }
4489                 isp_prt(isp, ISP_LOGINFO,
4490                     "driver initiated bus reset of bus %d", chan);
4491                 return (0);
4492
4493         case ISPCTL_RESET_DEV:
4494                 va_start(ap, ctl);
4495                 chan = va_arg(ap, int);
4496                 tgt = va_arg(ap, int);
4497                 va_end(ap);
4498                 if (IS_24XX(isp)) {
4499                         uint8_t local[QENTRY_LEN];
4500                         isp24xx_tmf_t *tmf;
4501                         isp24xx_statusreq_t *sp;
4502                         fcparam *fcp = FCPARAM(isp, chan);
4503                         fcportdb_t *lp;
4504                         int hdlidx;
4505
4506                         hdlidx = fcp->isp_dev_map[tgt] - 1;
4507                         if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4508                                 isp_prt(isp, ISP_LOGWARN,
4509                                     "Chan %d bad handle %d trying to reset"
4510                                     "target %d", chan, hdlidx, tgt);
4511                                 break;
4512                         }
4513                         lp = &fcp->portdb[hdlidx];
4514                         if (lp->state != FC_PORTDB_STATE_VALID) {
4515                                 isp_prt(isp, ISP_LOGWARN,
4516                                     "Chan %d handle %d for abort of target %d "
4517                                     "no longer valid", chan,
4518                                     hdlidx, tgt);
4519                                 break;
4520                         }
4521
4522                         tmf = (isp24xx_tmf_t *) local;
4523                         ISP_MEMZERO(tmf, QENTRY_LEN);
4524                         tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
4525                         tmf->tmf_header.rqs_entry_count = 1;
4526                         tmf->tmf_nphdl = lp->handle;
4527                         tmf->tmf_delay = 2;
4528                         tmf->tmf_timeout = 2;
4529                         tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
4530                         tmf->tmf_tidlo = lp->portid;
4531                         tmf->tmf_tidhi = lp->portid >> 16;
4532                         tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
4533                         isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
4534                         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
4535                         mbs.param[1] = QENTRY_LEN;
4536                         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4537                         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4538                         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4539                         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4540
4541                         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4542                                 isp_prt(isp, ISP_LOGERR, sacq);
4543                                 break;
4544                         }
4545                         isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch);
4546                         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN);
4547                         fcp->sendmarker = 1;
4548                         isp_mboxcmd(isp, &mbs);
4549                         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4550                                 FC_SCRATCH_RELEASE(isp, chan);
4551                                 break;
4552                         }
4553                         MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
4554                             QENTRY_LEN);
4555                         sp = (isp24xx_statusreq_t *) local;
4556                         isp_get_24xx_response(isp,
4557                             &((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp);
4558                         FC_SCRATCH_RELEASE(isp, chan);
4559                         if (sp->req_completion_status == 0) {
4560                                 return (0);
4561                         }
4562                         isp_prt(isp, ISP_LOGWARN,
4563                             "Chan %d reset of target %d returned 0x%x",
4564                             chan, tgt, sp->req_completion_status);
4565                         break;
4566                 } else if (IS_FC(isp)) {
4567                         if (ISP_CAP_2KLOGIN(isp)) {
4568                                 mbs.param[1] = tgt;
4569                                 mbs.ibits = (1 << 10);
4570                         } else {
4571                                 mbs.param[1] = (tgt << 8);
4572                         }
4573                 } else {
4574                         mbs.param[1] = (chan << 15) | (tgt << 8);
4575                 }
4576                 MBSINIT(&mbs, MBOX_ABORT_TARGET, MBLOGALL, 0);
4577                 mbs.param[2] = 3;       /* 'delay', in seconds */
4578                 isp_mboxcmd(isp, &mbs);
4579                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4580                         break;
4581                 }
4582                 isp_prt(isp, ISP_LOGINFO,
4583                     "Target %d on Bus %d Reset Succeeded", tgt, chan);
4584                 ISP_SET_SENDMARKER(isp, chan, 1);
4585                 return (0);
4586
4587         case ISPCTL_ABORT_CMD:
4588                 va_start(ap, ctl);
4589                 xs = va_arg(ap, XS_T *);
4590                 va_end(ap);
4591
4592                 tgt = XS_TGT(xs);
4593                 chan = XS_CHANNEL(xs);
4594
4595                 handle = isp_find_handle(isp, xs);
4596                 if (handle == 0) {
4597                         isp_prt(isp, ISP_LOGWARN,
4598                             "cannot find handle for command to abort");
4599                         break;
4600                 }
4601                 if (IS_24XX(isp)) {
4602                         isp24xx_abrt_t local, *ab = &local, *ab2;
4603                         fcparam *fcp;
4604                         fcportdb_t *lp;
4605                         int hdlidx;
4606
4607                         fcp = FCPARAM(isp, chan);
4608                         hdlidx = fcp->isp_dev_map[tgt] - 1;
4609                         if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4610                                 isp_prt(isp, ISP_LOGWARN,
4611                                     "Chan %d bad handle %d trying to abort"
4612                                     "target %d", chan, hdlidx, tgt);
4613                                 break;
4614                         }
4615                         lp = &fcp->portdb[hdlidx];
4616                         if (lp->state != FC_PORTDB_STATE_VALID) {
4617                                 isp_prt(isp, ISP_LOGWARN,
4618                                     "Chan %d handle %d for abort of target %d "
4619                                     "no longer valid", chan, hdlidx, tgt);
4620                                 break;
4621                         }
4622                         isp_prt(isp, ISP_LOGALL,
4623                             "Chan %d Abort Cmd for N-Port 0x%04x @ Port "
4624                             "0x%06x %p", chan, lp->handle, lp->portid, xs);
4625                         ISP_MEMZERO(ab, QENTRY_LEN);
4626                         ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
4627                         ab->abrt_header.rqs_entry_count = 1;
4628                         ab->abrt_handle = lp->handle;
4629                         ab->abrt_cmd_handle = handle;
4630                         ab->abrt_tidlo = lp->portid;
4631                         ab->abrt_tidhi = lp->portid >> 16;
4632                         ab->abrt_vpidx = ISP_GET_VPIDX(isp, chan);
4633
4634                         ISP_MEMZERO(&mbs, sizeof (mbs));
4635                         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
4636                         mbs.param[1] = QENTRY_LEN;
4637                         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4638                         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4639                         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4640                         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4641
4642                         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4643                                 isp_prt(isp, ISP_LOGERR, sacq);
4644                                 break;
4645                         }
4646                         isp_put_24xx_abrt(isp, ab, fcp->isp_scratch);
4647                         ab2 = (isp24xx_abrt_t *)
4648                             &((uint8_t *)fcp->isp_scratch)[QENTRY_LEN];
4649                         ab2->abrt_nphdl = 0xdeaf;
4650                         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, 2 * QENTRY_LEN);
4651                         isp_mboxcmd(isp, &mbs);
4652                         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4653                                 FC_SCRATCH_RELEASE(isp, chan);
4654                                 break;
4655                         }
4656                         MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
4657                             QENTRY_LEN);
4658                         isp_get_24xx_abrt(isp, ab2, ab);
4659                         FC_SCRATCH_RELEASE(isp, chan);
4660                         if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY) {
4661                                 return (0);
4662                         }
4663                         isp_prt(isp, ISP_LOGWARN,
4664                             "Chan %d handle %d abort returned 0x%x", chan,
4665                             hdlidx, ab->abrt_nphdl);
4666                         break;
4667                 } else if (IS_FC(isp)) {
4668                         if (ISP_CAP_SCCFW(isp)) {
4669                                 if (ISP_CAP_2KLOGIN(isp)) {
4670                                         mbs.param[1] = tgt;
4671                                 } else {
4672                                         mbs.param[1] = tgt << 8;
4673                                 }
4674                                 mbs.param[6] = XS_LUN(xs);
4675                         } else {
4676                                 mbs.param[1] = tgt << 8 | XS_LUN(xs);
4677                         }
4678                 } else {
4679                         mbs.param[1] = (chan << 15) | (tgt << 8) | XS_LUN(xs);
4680                 }
4681                 MBSINIT(&mbs, MBOX_ABORT, MBLOGALL & ~MBOX_COMMAND_ERROR, 0);
4682                 mbs.param[2] = handle;
4683                 isp_mboxcmd(isp, &mbs);
4684                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4685                         break;
4686                 }
4687                 return (0);
4688
4689         case ISPCTL_UPDATE_PARAMS:
4690
4691                 va_start(ap, ctl);
4692                 chan = va_arg(ap, int);
4693                 va_end(ap);
4694                 isp_spi_update(isp, chan);
4695                 return (0);
4696
4697         case ISPCTL_FCLINK_TEST:
4698
4699                 if (IS_FC(isp)) {
4700                         int usdelay;
4701                         va_start(ap, ctl);
4702                         chan = va_arg(ap, int);
4703                         usdelay = va_arg(ap, int);
4704                         va_end(ap);
4705                         if (usdelay == 0) {
4706                                 usdelay =  250000;
4707                         }
4708                         return (isp_fclink_test(isp, chan, usdelay));
4709                 }
4710                 break;
4711
4712         case ISPCTL_SCAN_FABRIC:
4713
4714                 if (IS_FC(isp)) {
4715                         va_start(ap, ctl);
4716                         chan = va_arg(ap, int);
4717                         va_end(ap);
4718                         return (isp_scan_fabric(isp, chan));
4719                 }
4720                 break;
4721
4722         case ISPCTL_SCAN_LOOP:
4723
4724                 if (IS_FC(isp)) {
4725                         va_start(ap, ctl);
4726                         chan = va_arg(ap, int);
4727                         va_end(ap);
4728                         return (isp_scan_loop(isp, chan));
4729                 }
4730                 break;
4731
4732         case ISPCTL_PDB_SYNC:
4733
4734                 if (IS_FC(isp)) {
4735                         va_start(ap, ctl);
4736                         chan = va_arg(ap, int);
4737                         va_end(ap);
4738                         return (isp_pdb_sync(isp, chan));
4739                 }
4740                 break;
4741
4742         case ISPCTL_SEND_LIP:
4743
4744                 if (IS_FC(isp) && !IS_24XX(isp)) {
4745                         MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
4746                         if (ISP_CAP_2KLOGIN(isp)) {
4747                                 mbs.ibits = (1 << 10);
4748                         }
4749                         isp_mboxcmd(isp, &mbs);
4750                         if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
4751                                 return (0);
4752                         }
4753                 }
4754                 break;
4755
4756         case ISPCTL_GET_PDB:
4757                 if (IS_FC(isp)) {
4758                         isp_pdb_t *pdb;
4759                         va_start(ap, ctl);
4760                         chan = va_arg(ap, int);
4761                         tgt = va_arg(ap, int);
4762                         pdb = va_arg(ap, isp_pdb_t *);
4763                         va_end(ap);
4764                         return (isp_getpdb(isp, chan, tgt, pdb, 1));
4765                 }
4766                 break;
4767
4768         case ISPCTL_GET_NAMES:
4769         {
4770                 uint64_t *wwnn, *wwnp;
4771                 va_start(ap, ctl);
4772                 chan = va_arg(ap, int);
4773                 tgt = va_arg(ap, int);
4774                 wwnn = va_arg(ap, uint64_t *);
4775                 wwnp = va_arg(ap, uint64_t *);
4776                 va_end(ap);
4777                 if (wwnn == NULL && wwnp == NULL) {
4778                         break;
4779                 }
4780                 if (wwnn) {
4781                         *wwnn = isp_get_wwn(isp, chan, tgt, 1);
4782                         if (*wwnn == INI_NONE) {
4783                                 break;
4784                         }
4785                 }
4786                 if (wwnp) {
4787                         *wwnp = isp_get_wwn(isp, chan, tgt, 0);
4788                         if (*wwnp == INI_NONE) {
4789                                 break;
4790                         }
4791                 }
4792                 return (0);
4793         }
4794         case ISPCTL_RUN_MBOXCMD:
4795         {
4796                 va_start(ap, ctl);
4797                 mbr = va_arg(ap, mbreg_t *);
4798                 va_end(ap);
4799                 isp_mboxcmd(isp, mbr);
4800                 return (0);
4801         }
4802         case ISPCTL_PLOGX:
4803         {
4804                 isp_plcmd_t *p;
4805                 int r;
4806
4807                 va_start(ap, ctl);
4808                 p = va_arg(ap, isp_plcmd_t *);
4809                 va_end(ap);
4810
4811                 if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
4812                         return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0));
4813                 }
4814                 do {
4815                         p->handle = isp_nxt_handle(isp, p->channel, p->handle);
4816                         r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0);
4817                         if ((r & 0xffff) == MBOX_PORT_ID_USED) {
4818                                 p->handle = r >> 16;
4819                                 r = 0;
4820                                 break;
4821                         }
4822                 } while ((r & 0xffff) == MBOX_LOOP_ID_USED);
4823                 return (r);
4824         }
4825         default:
4826                 isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
4827                 break;
4828
4829         }
4830         return (-1);
4831 }
4832
4833 /*
4834  * Interrupt Service Routine(s).
4835  *
4836  * External (OS) framework has done the appropriate locking,
4837  * and the locking will be held throughout this function.
4838  */
4839
4840 /*
4841  * Limit our stack depth by sticking with the max likely number
4842  * of completions on a request queue at any one time.
4843  */
4844 #ifndef MAX_REQUESTQ_COMPLETIONS
4845 #define MAX_REQUESTQ_COMPLETIONS        32
4846 #endif
4847
4848 void
4849 isp_intr(ispsoftc_t *isp, uint32_t isr, uint16_t sema, uint16_t mbox)
4850 {
4851         XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
4852         uint32_t iptr, optr, junk;
4853         int i, nlooked = 0, ndone = 0;
4854
4855 again:
4856         optr = isp->isp_residx;
4857         /*
4858          * Is this a mailbox related interrupt?
4859          * The mailbox semaphore will be nonzero if so.
4860          */
4861         if (sema) {
4862  fmbox:
4863                 if (mbox & 0x4000) {
4864                         isp->isp_intmboxc++;
4865                         if (isp->isp_mboxbsy) {
4866                                 int obits = isp->isp_obits;
4867                                 isp->isp_mboxtmp[0] = mbox;
4868                                 for (i = 1; i < MAX_MAILBOX(isp); i++) {
4869                                         if ((obits & (1 << i)) == 0) {
4870                                                 continue;
4871                                         }
4872                                         isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
4873                                 }
4874                                 if (isp->isp_mbxwrk0) {
4875                                         if (isp_mbox_continue(isp) == 0) {
4876                                                 return;
4877                                         }
4878                                 }
4879                                 MBOX_NOTIFY_COMPLETE(isp);
4880                         } else {
4881                                 isp_prt(isp, ISP_LOGWARN, "mailbox cmd (0x%x) with no waiters", mbox);
4882                         }
4883                 } else if (isp_parse_async(isp, mbox) < 0) {
4884                         return;
4885                 }
4886                 if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) || isp->isp_state != ISP_RUNSTATE) {
4887                         goto out;
4888                 }
4889         }
4890
4891         /*
4892          * We can't be getting this now.
4893          */
4894         if (isp->isp_state != ISP_RUNSTATE) {
4895                 /*
4896                  * This seems to happen to 23XX and 24XX cards- don't know why.
4897                  */
4898                  if (isp->isp_mboxbsy && isp->isp_lastmbxcmd == MBOX_ABOUT_FIRMWARE) {
4899                         goto fmbox;
4900                 }
4901                 isp_prt(isp, ISP_LOGINFO, "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
4902                 /*
4903                  * Thank you very much!  *Burrrp*!
4904                  */
4905                 ISP_WRITE(isp, isp->isp_respoutrp, ISP_READ(isp, isp->isp_respinrp));
4906                 if (IS_24XX(isp)) {
4907                         ISP_DISABLE_INTS(isp);
4908                 }
4909                 goto out;
4910         }
4911
4912 #ifdef  ISP_TARGET_MODE
4913         /*
4914          * Check for ATIO Queue entries.
4915          */
4916         if (IS_24XX(isp)) {
4917                 iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
4918                 optr = ISP_READ(isp, BIU2400_ATIO_RSPOUTP);
4919
4920                 while (optr != iptr) {
4921                         uint8_t qe[QENTRY_LEN];
4922                         isphdr_t *hp;
4923                         uint32_t oop;
4924                         void *addr;
4925
4926                         oop = optr;
4927                         MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN);
4928                         addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
4929                         isp_get_hdr(isp, addr, (isphdr_t *)qe);
4930                         hp = (isphdr_t *)qe;
4931                         switch (hp->rqs_entry_type) {
4932                         case RQSTYPE_NOTIFY:
4933                         case RQSTYPE_ATIO:
4934                                 (void) isp_target_notify(isp, addr, &oop);
4935                                 break;
4936                         default:
4937                                 isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
4938                                 break;
4939                         }
4940                         optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
4941                         ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
4942                 }
4943                 optr = isp->isp_residx;
4944         }
4945 #endif
4946
4947         /*
4948          * Get the current Response Queue Out Pointer.
4949          *
4950          * If we're a 2300 or 2400, we can ask what hardware what it thinks.
4951          */
4952         if (IS_23XX(isp) || IS_24XX(isp)) {
4953                 optr = ISP_READ(isp, isp->isp_respoutrp);
4954                 /*
4955                  * Debug: to be taken out eventually
4956                  */
4957                 if (isp->isp_residx != optr) {
4958                         isp_prt(isp, ISP_LOGINFO, "isp_intr: hard optr=%x, soft optr %x", optr, isp->isp_residx);
4959                         isp->isp_residx = optr;
4960                 }
4961         } else {
4962                 optr = isp->isp_residx;
4963         }
4964
4965         /*
4966          * You *must* read the Response Queue In Pointer
4967          * prior to clearing the RISC interrupt.
4968          *
4969          * Debounce the 2300 if revision less than 2.
4970          */
4971         if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
4972                 i = 0;
4973                 do {
4974                         iptr = ISP_READ(isp, isp->isp_respinrp);
4975                         junk = ISP_READ(isp, isp->isp_respinrp);
4976                 } while (junk != iptr && ++i < 1000);
4977
4978                 if (iptr != junk) {
4979                         isp_prt(isp, ISP_LOGWARN, "Response Queue Out Pointer Unstable (%x, %x)", iptr, junk);
4980                         goto out;
4981                 }
4982         } else {
4983                 iptr = ISP_READ(isp, isp->isp_respinrp);
4984         }
4985         isp->isp_resodx = iptr;
4986
4987
4988         if (optr == iptr && sema == 0) {
4989                 /*
4990                  * There are a lot of these- reasons unknown- mostly on
4991                  * faster Alpha machines.
4992                  *
4993                  * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
4994                  * make sure the old interrupt went away (to avoid 'ringing'
4995                  * effects), but that didn't stop this from occurring.
4996                  */
4997                 if (IS_24XX(isp)) {
4998                         junk = 0;
4999                 } else if (IS_23XX(isp)) {
5000                         ISP_DELAY(100);
5001                         iptr = ISP_READ(isp, isp->isp_respinrp);
5002                         junk = ISP_READ(isp, BIU_R2HSTSLO);
5003                 } else {
5004                         junk = ISP_READ(isp, BIU_ISR);
5005                 }
5006                 if (optr == iptr) {
5007                         if (IS_23XX(isp) || IS_24XX(isp)) {
5008                                 ;
5009                         } else {
5010                                 sema = ISP_READ(isp, BIU_SEMA);
5011                                 mbox = ISP_READ(isp, OUTMAILBOX0);
5012                                 if ((sema & 0x3) && (mbox & 0x8000)) {
5013                                         goto again;
5014                                 }
5015                         }
5016                         isp->isp_intbogus++;
5017                         isp_prt(isp, ISP_LOGDEBUG1, "bogus intr- isr %x (%x) iptr %x optr %x", isr, junk, iptr, optr);
5018                 }
5019         }
5020         isp->isp_resodx = iptr;
5021
5022         while (optr != iptr) {
5023                 uint8_t qe[QENTRY_LEN];
5024                 ispstatusreq_t *sp = (ispstatusreq_t *) qe;
5025                 isphdr_t *hp;
5026                 int buddaboom, etype, scsi_status, completion_status;
5027                 int req_status_flags, req_state_flags;
5028                 uint8_t *snsp, *resp;
5029                 uint32_t rlen, slen;
5030                 long resid;
5031                 uint16_t oop;
5032
5033                 hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
5034                 oop = optr;
5035                 optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
5036                 nlooked++;
5037  read_again:
5038                 buddaboom = req_status_flags = req_state_flags = 0;
5039                 resid = 0L;
5040
5041                 /*
5042                  * Synchronize our view of this response queue entry.
5043                  */
5044                 MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN);
5045                 isp_get_hdr(isp, hp, &sp->req_header);
5046                 etype = sp->req_header.rqs_entry_type;
5047
5048                 if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) {
5049                         isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe;
5050                         isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp2);
5051                         if (isp->isp_dblev & ISP_LOGDEBUG1) {
5052                                 isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp2);
5053                         }
5054                         scsi_status = sp2->req_scsi_status;
5055                         completion_status = sp2->req_completion_status;
5056                         req_state_flags = 0;
5057                         resid = sp2->req_resid;
5058                 } else if (etype == RQSTYPE_RESPONSE) {
5059                         isp_get_response(isp, (ispstatusreq_t *) hp, sp);
5060                         if (isp->isp_dblev & ISP_LOGDEBUG1) {
5061                                 isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp);
5062                         }
5063                         scsi_status = sp->req_scsi_status;
5064                         completion_status = sp->req_completion_status;
5065                         req_status_flags = sp->req_status_flags;
5066                         req_state_flags = sp->req_state_flags;
5067                         resid = sp->req_resid;
5068                 } else if (etype == RQSTYPE_RIO2) {
5069                         isp_rio2_t *rio = (isp_rio2_t *)qe;
5070                         isp_get_rio2(isp, (isp_rio2_t *) hp, rio);
5071                         if (isp->isp_dblev & ISP_LOGDEBUG1) {
5072                                 isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, rio);
5073                         }
5074                         for (i = 0; i < rio->req_header.rqs_seqno; i++) {
5075                                 isp_fastpost_complete(isp, rio->req_handles[i]);
5076                         }
5077                         if (isp->isp_fpcchiwater < rio->req_header.rqs_seqno) {
5078                                 isp->isp_fpcchiwater = rio->req_header.rqs_seqno;
5079                         }
5080                         ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
5081                         continue;
5082                 } else {
5083                         /*
5084                          * Somebody reachable via isp_handle_other_response
5085                          * may have updated the response queue pointers for
5086                          * us, so we reload our goal index.
5087                          */
5088                         int r;
5089                         uint32_t tsto = oop;
5090                         r = isp_handle_other_response(isp, etype, hp, &tsto);
5091                         if (r < 0) {
5092                                 goto read_again;
5093                         }
5094                         /*
5095                          * If somebody updated the output pointer, then reset
5096                          * optr to be one more than the updated amount.
5097                          */
5098                         while (tsto != oop) {
5099                                 optr = ISP_NXT_QENTRY(tsto,
5100                                     RESULT_QUEUE_LEN(isp));
5101                         }
5102                         if (r > 0) {
5103                                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
5104                                 ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
5105                                 continue;
5106                         }
5107
5108                         /*
5109                          * After this point, we'll just look at the header as
5110                          * we don't know how to deal with the rest of the
5111                          * response.
5112                          */
5113
5114                         /*
5115                          * It really has to be a bounced request just copied
5116                          * from the request queue to the response queue. If
5117                          * not, something bad has happened.
5118                          */
5119                         if (etype != RQSTYPE_REQUEST) {
5120                                 isp_prt(isp, ISP_LOGERR, notresp,
5121                                     etype, oop, optr, nlooked);
5122                                 isp_print_bytes(isp,
5123                                     "Request Queue Entry", QENTRY_LEN, sp);
5124                                 ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
5125                                 continue;
5126                         }
5127                         buddaboom = 1;
5128                         scsi_status = sp->req_scsi_status;
5129                         completion_status = sp->req_completion_status;
5130                         req_status_flags = sp->req_status_flags;
5131                         req_state_flags = sp->req_state_flags;
5132                         resid = sp->req_resid;
5133                 }
5134
5135                 if (sp->req_header.rqs_flags & RQSFLAG_MASK) {
5136                         if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
5137                                 isp_print_bytes(isp, "unexpected continuation segment", QENTRY_LEN, sp);
5138                                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
5139                                 continue;
5140                         }
5141                         if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
5142                                 isp_prt(isp, ISP_LOGDEBUG0, "internal queues full");
5143                                 /*
5144                                  * We'll synthesize a QUEUE FULL message below.
5145                                  */
5146                         }
5147                         if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
5148                                 isp_print_bytes(isp, "bad header flag", QENTRY_LEN, sp);
5149                                 buddaboom++;
5150                         }
5151                         if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
5152                                 isp_print_bytes(isp, "bad request packet", QENTRY_LEN, sp);
5153                                 buddaboom++;
5154                         }
5155                         if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
5156                                 isp_print_bytes(isp, "invalid entry count", QENTRY_LEN, sp);
5157                                 buddaboom++;
5158                         }
5159                         if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
5160                                 isp_print_bytes(isp, "invalid IOCB ordering", QENTRY_LEN, sp);
5161                                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
5162                                 continue;
5163                         }
5164                 }
5165
5166                 if (!ISP_VALID_HANDLE(isp, sp->req_handle)) {
5167                         isp_prt(isp, ISP_LOGERR, "bad request handle 0x%x (iocb type 0x%x)", sp->req_handle, etype);
5168                         ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
5169                         ISP_WRITE(isp, isp->isp_respoutrp, optr);
5170                         continue;
5171                 }
5172                 xs = isp_find_xs(isp, sp->req_handle);
5173                 if (xs == NULL) {
5174                         uint8_t ts = completion_status & 0xff;
5175                         /*
5176                          * Only whine if this isn't the expected fallout of
5177                          * aborting the command or resetting the target.
5178                          */
5179                         if (etype != RQSTYPE_RESPONSE) {
5180                                 isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (type 0x%x)", sp->req_handle, etype);
5181                         } else if (ts != RQCS_ABORTED && ts != RQCS_RESET_OCCURRED) {
5182                                 isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", sp->req_handle, ts);
5183                         }
5184                         ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
5185                         ISP_WRITE(isp, isp->isp_respoutrp, optr);
5186                         continue;
5187                 }
5188                 if (req_status_flags & RQSTF_BUS_RESET) {
5189                         XS_SETERR(xs, HBA_BUSRESET);
5190                         ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
5191                 }
5192                 if (buddaboom) {
5193                         XS_SETERR(xs, HBA_BOTCH);
5194                 }
5195
5196                 resp = NULL;
5197                 rlen = 0;
5198                 snsp = NULL;
5199                 slen = 0;
5200                 if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) {
5201                         resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
5202                         rlen = ((isp24xx_statusreq_t *)sp)->req_response_len;
5203                 } else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) {
5204                         resp = sp->req_response;
5205                         rlen = sp->req_response_len;
5206                 }
5207                 if (IS_FC(isp) && (scsi_status & RQCS_SV) != 0) {
5208                         /*
5209                          * Fibre Channel F/W doesn't say we got status
5210                          * if there's Sense Data instead. I guess they
5211                          * think it goes w/o saying.
5212                          */
5213                         req_state_flags |= RQSF_GOT_STATUS|RQSF_GOT_SENSE;
5214                         if (IS_24XX(isp)) {
5215                                 snsp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
5216                                 snsp += rlen;
5217                                 slen = ((isp24xx_statusreq_t *)sp)->req_sense_len;
5218                         } else {
5219                                 snsp = sp->req_sense_data;
5220                                 slen = sp->req_sense_len;
5221                         }
5222                 } else if (IS_SCSI(isp) && (req_state_flags & RQSF_GOT_SENSE)) {
5223                         snsp = sp->req_sense_data;
5224                         slen = sp->req_sense_len;
5225                 }
5226                 if (req_state_flags & RQSF_GOT_STATUS) {
5227                         *XS_STSP(xs) = scsi_status & 0xff;
5228                 }
5229
5230                 switch (etype) {
5231                 case RQSTYPE_RESPONSE:
5232                         if (resp && rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
5233                                 const char *ptr;
5234                                 char lb[64];
5235                                 const char *rnames[6] = {
5236                                         "Task Management Function Done",
5237                                         "Data Length Differs From Burst Length",
5238                                         "Invalid FCP Cmnd",
5239                                         "FCP DATA RO mismatch with FCP DATA_XFR_RDY RO",
5240                                         "Task Management Function Rejected",
5241                                         "Task Management Function Failed",
5242                                 };
5243                                 if (resp[FCP_RSPNS_CODE_OFFSET] > 5) {
5244                                         ISP_SNPRINTF(lb, sizeof lb, "Unknown FCP Response Code 0x%x", resp[FCP_RSPNS_CODE_OFFSET]);
5245                                         ptr = lb;
5246                                 } else {
5247                                         ptr = rnames[resp[FCP_RSPNS_CODE_OFFSET]];
5248                                 }
5249                                 isp_prt(isp, ISP_LOGWARN, "%d.%d.%d FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x", XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), rlen, ptr, XS_CDBP(xs)[0] & 0xff);
5250                                 if (resp[FCP_RSPNS_CODE_OFFSET] != 0) {
5251                                         XS_SETERR(xs, HBA_BOTCH);
5252                                 }
5253                         }
5254                         if (IS_24XX(isp)) {
5255                                 isp_parse_status_24xx(isp, (isp24xx_statusreq_t *)sp, xs, &resid);
5256                         } else {
5257                                 isp_parse_status(isp, (void *)sp, xs, &resid);
5258                         }
5259                         if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) && (*XS_STSP(xs) == SCSI_BUSY)) {
5260                                 XS_SETERR(xs, HBA_TGTBSY);
5261                         }
5262                         if (IS_SCSI(isp)) {
5263                                 XS_SET_RESID(xs, resid);
5264                                 /*
5265                                  * A new synchronous rate was negotiated for
5266                                  * this target. Mark state such that we'll go
5267                                  * look up that which has changed later.
5268                                  */
5269                                 if (req_status_flags & RQSTF_NEGOTIATION) {
5270                                         int t = XS_TGT(xs);
5271                                         sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
5272                                         sdp->isp_devparam[t].dev_refresh = 1;
5273                                         sdp->update = 1;
5274                                 }
5275                         } else {
5276                                 if (req_status_flags & RQSF_XFER_COMPLETE) {
5277                                         XS_SET_RESID(xs, 0);
5278                                 } else if (scsi_status & RQCS_RESID) {
5279                                         XS_SET_RESID(xs, resid);
5280                                 } else {
5281                                         XS_SET_RESID(xs, 0);
5282                                 }
5283                         }
5284                         if (snsp && slen) {
5285                                 XS_SAVE_SENSE(xs, snsp, slen);
5286                         } else if ((req_status_flags & RQSF_GOT_STATUS) && (scsi_status & 0xff) == SCSI_CHECK && IS_FC(isp)) {
5287                                 isp_prt(isp, ISP_LOGWARN, "CHECK CONDITION w/o sense data for CDB=0x%x", XS_CDBP(xs)[0] & 0xff);
5288                                 isp_print_bytes(isp, "CC with no Sense", QENTRY_LEN, qe);
5289                         }
5290                         isp_prt(isp, ISP_LOGDEBUG2, "asked for %ld got raw resid %ld settled for %ld", (long) XS_XFRLEN(xs), resid, (long) XS_GET_RESID(xs));
5291                         break;
5292                 case RQSTYPE_REQUEST:
5293                 case RQSTYPE_A64:
5294                 case RQSTYPE_T2RQS:
5295                 case RQSTYPE_T3RQS:
5296                 case RQSTYPE_T7RQS:
5297                         if (!IS_24XX(isp) && (sp->req_header.rqs_flags & RQSFLAG_FULL)) {
5298                                 /*
5299                                  * Force Queue Full status.
5300                                  */
5301                                 *XS_STSP(xs) = SCSI_QFULL;
5302                                 XS_SETERR(xs, HBA_NOERROR);
5303                         } else if (XS_NOERR(xs)) {
5304                                 XS_SETERR(xs, HBA_BOTCH);
5305                         }
5306                         XS_SET_RESID(xs, XS_XFRLEN(xs));
5307                         break;
5308                 default:
5309                         isp_print_bytes(isp, "Unhandled Response Type", QENTRY_LEN, qe);
5310                         if (XS_NOERR(xs)) {
5311                                 XS_SETERR(xs, HBA_BOTCH);
5312                         }
5313                         break;
5314                 }
5315
5316                 /*
5317                  * Free any DMA resources. As a side effect, this may
5318                  * also do any cache flushing necessary for data coherence.
5319                  */
5320                 if (XS_XFRLEN(xs)) {
5321                         ISP_DMAFREE(isp, xs, sp->req_handle);
5322                 }
5323                 isp_destroy_handle(isp, sp->req_handle);
5324
5325                 if (((isp->isp_dblev & (ISP_LOGDEBUG1|ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
5326                     ((isp->isp_dblev & ISP_LOGDEBUG0) && ((!XS_NOERR(xs)) ||
5327                     (*XS_STSP(xs) != SCSI_GOOD)))) {
5328                         char skey;
5329                         if (req_state_flags & RQSF_GOT_SENSE) {
5330                                 skey = XS_SNSKEY(xs) & 0xf;
5331                                 if (skey < 10)
5332                                         skey += '0';
5333                                 else
5334                                         skey += 'a' - 10;
5335                         } else if (*XS_STSP(xs) == SCSI_CHECK) {
5336                                 skey = '?';
5337                         } else {
5338                                 skey = '.';
5339                         }
5340                         isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs),
5341                             XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), (long) XS_GET_RESID(xs),
5342                             *XS_STSP(xs), skey, XS_ERR(xs));
5343                 }
5344
5345                 if (isp->isp_nactive > 0) {
5346                     isp->isp_nactive--;
5347                 }
5348                 complist[ndone++] = xs; /* defer completion call until later */
5349                 ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
5350                 if (ndone == MAX_REQUESTQ_COMPLETIONS) {
5351                         break;
5352                 }
5353         }
5354
5355         /*
5356          * If we looked at any commands, then it's valid to find out
5357          * what the outpointer is. It also is a trigger to update the
5358          * ISP's notion of what we've seen so far.
5359          */
5360         if (nlooked) {
5361                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
5362                 /*
5363                  * While we're at it, read the requst queue out pointer.
5364                  */
5365                 isp->isp_reqodx = ISP_READ(isp, isp->isp_rqstoutrp);
5366                 if (isp->isp_rscchiwater < ndone) {
5367                         isp->isp_rscchiwater = ndone;
5368                 }
5369         }
5370
5371 out:
5372
5373         if (IS_24XX(isp)) {
5374                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
5375         } else {
5376                 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
5377                 ISP_WRITE(isp, BIU_SEMA, 0);
5378         }
5379
5380         isp->isp_residx = optr;
5381         for (i = 0; i < ndone; i++) {
5382                 xs = complist[i];
5383                 if (xs) {
5384                         isp->isp_rsltccmplt++;
5385                         isp_done(xs);
5386                 }
5387         }
5388 }
5389
5390 /*
5391  * Support routines.
5392  */
5393
5394 #define GET_24XX_BUS(isp, chan, msg)                                                                            \
5395         if (IS_24XX(isp)) {                                                                                     \
5396                 chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;                                                       \
5397                 if (chan >= isp->isp_nchan) {                                                                   \
5398                         isp_prt(isp, ISP_LOGERR, "bogus channel %u for %s at line %d",  chan, msg, __LINE__);   \
5399                         break;                                                                                  \
5400                 }                                                                                               \
5401         }
5402
5403 static int
5404 isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
5405 {
5406         int rval = 0;
5407         int pattern = 0;
5408         uint16_t chan;
5409
5410         if (IS_DUALBUS(isp)) {
5411                 chan = ISP_READ(isp, OUTMAILBOX6);
5412         } else {
5413                 chan = 0;
5414         }
5415         isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
5416
5417         switch (mbox) {
5418         case ASYNC_BUS_RESET:
5419                 if (IS_FC(isp)) {
5420                         isp_prt(isp, ISP_LOGWARN,
5421                             "ILLEGAL ASYNC_BUS_RESET for FC card");
5422                         break;
5423                 }
5424                 ISP_SET_SENDMARKER(isp, chan, 1);
5425 #ifdef  ISP_TARGET_MODE
5426                 if (isp_target_async(isp, chan, mbox)) {
5427                         rval = -1;
5428                 }
5429 #endif
5430                 isp_async(isp, ISPASYNC_BUS_RESET, chan);
5431                 break;
5432         case ASYNC_SYSTEM_ERROR:
5433                 isp->isp_dead = 1;
5434                 isp->isp_state = ISP_CRASHED;
5435                 if (IS_FC(isp)) {
5436                         FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
5437                         FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
5438                 }
5439                 /*
5440                  * Were we waiting for a mailbox command to complete?
5441                  * If so, it's dead, so wake up the waiter.
5442                  */
5443                 if (isp->isp_mboxbsy) {
5444                         isp->isp_obits = 1;
5445                         isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
5446                         MBOX_NOTIFY_COMPLETE(isp);
5447                 }
5448                 /*
5449                  * It's up to the handler for isp_async to reinit stuff and
5450                  * restart the firmware
5451                  */
5452                 isp_async(isp, ISPASYNC_FW_CRASH);
5453                 rval = -1;
5454                 break;
5455
5456         case ASYNC_RQS_XFER_ERR:
5457                 isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
5458                 break;
5459
5460         case ASYNC_RSP_XFER_ERR:
5461                 isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
5462                 break;
5463
5464         case ASYNC_QWAKEUP:
5465 #ifdef  ISP_TARGET_MODE
5466                 if (IS_24XX(isp)) {
5467                         isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
5468                         break;
5469                 }
5470 #endif
5471                 if (IS_FC(isp)) {
5472                         isp_prt(isp, ISP_LOGWARN,
5473                             "ILLEGAL ASYNC_QWAKEUP for FC card");
5474                         break;
5475                 }
5476                 /*
5477                  * We've just been notified that the Queue has woken up.
5478                  * We don't need to be chatty about this- just unlatch things
5479                  * and move on.
5480                  */
5481                 mbox = ISP_READ(isp, isp->isp_rqstoutrp);
5482                 break;
5483
5484         case ASYNC_TIMEOUT_RESET:
5485                 if (IS_FC(isp)) {
5486                         isp_prt(isp, ISP_LOGWARN,
5487                             "ILLEGAL ASYNC_TIMEOUT_RESET for FC card");
5488                         break;
5489                 }
5490                 isp_prt(isp, ISP_LOGWARN,
5491                     "timeout initiated SCSI bus reset of chan %d", chan);
5492                 ISP_SET_SENDMARKER(isp, chan, 1);
5493 #ifdef  ISP_TARGET_MODE
5494                 if (isp_target_async(isp, chan, mbox)) {
5495                         rval = -1;
5496                 }
5497 #endif
5498                 break;
5499
5500         case ASYNC_DEVICE_RESET:
5501                 if (IS_FC(isp)) {
5502                         isp_prt(isp, ISP_LOGWARN,
5503                             "ILLEGAL DEVICE_RESET for FC card");
5504                         break;
5505                 }
5506                 isp_prt(isp, ISP_LOGINFO, "device reset on chan %d", chan);
5507                 ISP_SET_SENDMARKER(isp, chan, 1);
5508 #ifdef  ISP_TARGET_MODE
5509                 if (isp_target_async(isp, chan, mbox)) {
5510                         rval = -1;
5511                 }
5512 #endif
5513                 break;
5514
5515         case ASYNC_EXTMSG_UNDERRUN:
5516                 if (IS_FC(isp)) {
5517                         isp_prt(isp, ISP_LOGWARN,
5518                             "ILLEGAL ASYNC_EXTMSG_UNDERRUN for FC card");
5519                         break;
5520                 }
5521                 isp_prt(isp, ISP_LOGWARN, "extended message underrun");
5522                 break;
5523
5524         case ASYNC_SCAM_INT:
5525                 if (IS_FC(isp)) {
5526                         isp_prt(isp, ISP_LOGWARN,
5527                             "ILLEGAL ASYNC_SCAM_INT for FC card");
5528                         break;
5529                 }
5530                 isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
5531                 break;
5532
5533         case ASYNC_HUNG_SCSI:
5534                 if (IS_FC(isp)) {
5535                         isp_prt(isp, ISP_LOGWARN,
5536                             "ILLEGAL ASYNC_HUNG_SCSI for FC card");
5537                         break;
5538                 }
5539                 isp_prt(isp, ISP_LOGERR,
5540                     "stalled SCSI Bus after DATA Overrun");
5541                 /* XXX: Need to issue SCSI reset at this point */
5542                 break;
5543
5544         case ASYNC_KILLED_BUS:
5545                 if (IS_FC(isp)) {
5546                         isp_prt(isp, ISP_LOGWARN,
5547                             "ILLEGAL ASYNC_KILLED_BUS for FC card");
5548                         break;
5549                 }
5550                 isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
5551                 break;
5552
5553         case ASYNC_BUS_TRANSIT:
5554                 if (IS_FC(isp)) {
5555                         isp_prt(isp, ISP_LOGWARN,
5556                             "ILLEGAL ASYNC_BUS_TRANSIT for FC card");
5557                         break;
5558                 }
5559                 mbox = ISP_READ(isp, OUTMAILBOX2);
5560                 switch (mbox & 0x1c00) {
5561                 case SXP_PINS_LVD_MODE:
5562                         isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
5563                         SDPARAM(isp, chan)->isp_diffmode = 0;
5564                         SDPARAM(isp, chan)->isp_ultramode = 0;
5565                         SDPARAM(isp, chan)->isp_lvdmode = 1;
5566                         break;
5567                 case SXP_PINS_HVD_MODE:
5568                         isp_prt(isp, ISP_LOGINFO,
5569                             "Transition to Differential mode");
5570                         SDPARAM(isp, chan)->isp_diffmode = 1;
5571                         SDPARAM(isp, chan)->isp_ultramode = 0;
5572                         SDPARAM(isp, chan)->isp_lvdmode = 0;
5573                         break;
5574                 case SXP_PINS_SE_MODE:
5575                         isp_prt(isp, ISP_LOGINFO,
5576                             "Transition to Single Ended mode");
5577                         SDPARAM(isp, chan)->isp_diffmode = 0;
5578                         SDPARAM(isp, chan)->isp_ultramode = 1;
5579                         SDPARAM(isp, chan)->isp_lvdmode = 0;
5580                         break;
5581                 default:
5582                         isp_prt(isp, ISP_LOGWARN,
5583                             "Transition to Unknown Mode 0x%x", mbox);
5584                         break;
5585                 }
5586                 /*
5587                  * XXX: Set up to renegotiate again!
5588                  */
5589                 /* Can only be for a 1080... */
5590                 ISP_SET_SENDMARKER(isp, chan, 1);
5591                 break;
5592
5593         case ASYNC_RIO5:
5594                 pattern = 0xce; /* outgoing mailbox regs 1-3, 6-7 */
5595                 break;
5596
5597         case ASYNC_RIO4:
5598                 pattern = 0x4e; /* outgoing mailbox regs 1-3, 6 */
5599                 break;
5600
5601         case ASYNC_RIO3:
5602                 pattern = 0x0e; /* outgoing mailbox regs 1-3 */
5603                 break;
5604
5605         case ASYNC_RIO2:
5606                 pattern = 0x06; /* outgoing mailbox regs 1-2 */
5607                 break;
5608
5609         case ASYNC_RIO1:
5610         case ASYNC_CMD_CMPLT:
5611                 pattern = 0x02; /* outgoing mailbox regs 1 */
5612                 break;
5613
5614         case ASYNC_RIO_RESP:
5615                 return (rval);
5616
5617         case ASYNC_CTIO_DONE:
5618         {
5619 #ifdef  ISP_TARGET_MODE
5620                 int handle;
5621                 if (IS_SCSI(isp) || IS_24XX(isp)) {
5622                         isp_prt(isp, ISP_LOGWARN,
5623                             "bad ASYNC_CTIO_DONE for %s cards",
5624                             IS_SCSI(isp)? "SCSI" : "24XX");
5625                         break;
5626                 }
5627                 handle =
5628                     (ISP_READ(isp, OUTMAILBOX2) << 16) |
5629                     (ISP_READ(isp, OUTMAILBOX1));
5630                 if (isp_target_async(isp, handle, mbox)) {
5631                         rval = -1;
5632                 } else {
5633                         /* count it as a fast posting intr */
5634                         isp->isp_fphccmplt++;
5635                 }
5636 #else
5637                 if (IS_SCSI(isp) || IS_24XX(isp)) {
5638                         isp_prt(isp, ISP_LOGWARN,
5639                             "bad ASYNC_CTIO_DONE for %s cards",
5640                             IS_SCSI(isp)? "SCSI" : "24XX");
5641                         break;
5642                 }
5643                 isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
5644                 isp->isp_fphccmplt++;   /* count it as a fast posting intr */
5645 #endif
5646                 break;
5647         }
5648         case ASYNC_LIP_ERROR:
5649         case ASYNC_LIP_F8:
5650         case ASYNC_LIP_OCCURRED:
5651         case ASYNC_PTPMODE:
5652                 if (IS_SCSI(isp)) {
5653                         isp_prt(isp, ISP_LOGWARN,
5654                             "bad LIP event for SCSI cards");
5655                         break;
5656                 }
5657                 /*
5658                  * These are broadcast events that have to be sent across
5659                  * all active channels.
5660                  */
5661                 for (chan = 0; chan < isp->isp_nchan; chan++) {
5662                         fcparam *fcp = FCPARAM(isp, chan);
5663                         int topo = fcp->isp_topo;
5664
5665                         if (fcp->role == ISP_ROLE_NONE) {
5666                                 continue;
5667                         }
5668
5669                         fcp->isp_fwstate = FW_CONFIG_WAIT;
5670                         fcp->isp_loopstate = LOOP_LIP_RCVD;
5671                         ISP_SET_SENDMARKER(isp, chan, 1);
5672                         ISP_MARK_PORTDB(isp, chan, 1);
5673                         isp_async(isp, ISPASYNC_LIP, chan);
5674 #ifdef  ISP_TARGET_MODE
5675                         if (isp_target_async(isp, chan, mbox)) {
5676                                 rval = -1;
5677                         }
5678 #endif
5679                         /*
5680                          * We've had problems with data corruption occuring on
5681                          * commands that complete (with no apparent error) after
5682                          * we receive a LIP. This has been observed mostly on
5683                          * Local Loop topologies. To be safe, let's just mark
5684                          * all active initiator commands as dead.
5685                          */
5686                         if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
5687                                 int i, j;
5688                                 for (i = j = 0; i < isp->isp_maxcmds; i++) {
5689                                         XS_T *xs;
5690                                         isp_hdl_t *hdp;
5691
5692                                         hdp = &isp->isp_xflist[i];
5693                                         if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) {
5694                                                 continue;
5695                                         }
5696                                         xs = hdp->cmd;
5697                                         if (XS_CHANNEL(xs) != chan) {
5698                                                 continue;
5699                                         }
5700                                         j++;
5701                                         XS_SETERR(xs, HBA_BUSRESET);
5702                                 }
5703                                 if (j) {
5704                                         isp_prt(isp, ISP_LOGERR, lipd, chan, j);
5705                                 }
5706                         }
5707                 }
5708                 break;
5709
5710         case ASYNC_LOOP_UP:
5711                 if (IS_SCSI(isp)) {
5712                         isp_prt(isp, ISP_LOGWARN,
5713                             "bad LOOP UP event for SCSI cards");
5714                         break;
5715                 }
5716                 /*
5717                  * This is a broadcast event that has to be sent across
5718                  * all active channels.
5719                  */
5720                 for (chan = 0; chan < isp->isp_nchan; chan++) {
5721                         fcparam *fcp = FCPARAM(isp, chan);
5722
5723                         if (fcp->role == ISP_ROLE_NONE) {
5724                                 continue;
5725                         }
5726
5727                         ISP_SET_SENDMARKER(isp, chan, 1);
5728
5729                         fcp->isp_fwstate = FW_CONFIG_WAIT;
5730                         fcp->isp_loopstate = LOOP_LIP_RCVD;
5731                         ISP_MARK_PORTDB(isp, chan, 1);
5732                         isp_async(isp, ISPASYNC_LOOP_UP, chan);
5733 #ifdef  ISP_TARGET_MODE
5734                         if (isp_target_async(isp, chan, mbox)) {
5735                                 rval = -1;
5736                         }
5737 #endif
5738                 }
5739                 break;
5740
5741         case ASYNC_LOOP_DOWN:
5742                 if (IS_SCSI(isp)) {
5743                         isp_prt(isp, ISP_LOGWARN,
5744                             "bad LOOP DOWN event for SCSI cards");
5745                         break;
5746                 }
5747                 /*
5748                  * This is a broadcast event that has to be sent across
5749                  * all active channels.
5750                  */
5751                 for (chan = 0; chan < isp->isp_nchan; chan++) {
5752                         fcparam *fcp = FCPARAM(isp, chan);
5753
5754                         if (fcp->role == ISP_ROLE_NONE) {
5755                                 continue;
5756                         }
5757
5758                         ISP_SET_SENDMARKER(isp, chan, 1);
5759                         fcp->isp_fwstate = FW_CONFIG_WAIT;
5760                         fcp->isp_loopstate = LOOP_NIL;
5761                         ISP_MARK_PORTDB(isp, chan, 1);
5762                         isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
5763 #ifdef  ISP_TARGET_MODE
5764                         if (isp_target_async(isp, chan, mbox)) {
5765                                 rval = -1;
5766                         }
5767 #endif
5768                 }
5769                 break;
5770
5771         case ASYNC_LOOP_RESET:
5772                 if (IS_SCSI(isp)) {
5773                         isp_prt(isp, ISP_LOGWARN,
5774                             "bad LIP RESET event for SCSI cards");
5775                         break;
5776                 }
5777                 /*
5778                  * This is a broadcast event that has to be sent across
5779                  * all active channels.
5780                  */
5781                 for (chan = 0; chan < isp->isp_nchan; chan++) {
5782                         fcparam *fcp = FCPARAM(isp, chan);
5783
5784                         if (fcp->role == ISP_ROLE_NONE) {
5785                                 continue;
5786                         }
5787
5788                         ISP_SET_SENDMARKER(isp, chan, 1);
5789                         fcp->isp_fwstate = FW_CONFIG_WAIT;
5790                         fcp->isp_loopstate = LOOP_NIL;
5791                         ISP_MARK_PORTDB(isp, chan, 1);
5792                         isp_async(isp, ISPASYNC_LOOP_RESET, chan);
5793 #ifdef  ISP_TARGET_MODE
5794                         if (isp_target_async(isp, chan, mbox)) {
5795                                 rval = -1;
5796                         }
5797 #endif
5798                 }
5799                 break;
5800
5801         case ASYNC_PDB_CHANGED:
5802         {
5803                 int nphdl, nlstate, reason;
5804                 if (IS_SCSI(isp)) {
5805                         isp_prt(isp, ISP_LOGWARN,
5806                             "bad PDB CHANGED event for SCSI cards");
5807                         break;
5808                 }
5809                 /*
5810                  * We *should* get a channel out of the 24XX, but we don't seem
5811                  * to get more than a PDB CHANGED on channel 0, so turn it into
5812                  * a broadcast event.
5813                  */
5814                 if (IS_24XX(isp)) {
5815                         nphdl = ISP_READ(isp, OUTMAILBOX1);
5816                         nlstate = ISP_READ(isp, OUTMAILBOX2);
5817                         reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
5818                 } else {
5819                         nphdl = NIL_HANDLE;
5820                         nlstate = reason = 0;
5821                 }
5822                 for (chan = 0; chan < isp->isp_nchan; chan++) {
5823                         fcparam *fcp = FCPARAM(isp, chan);
5824
5825                         if (fcp->role == ISP_ROLE_NONE) {
5826                                 continue;
5827                         }
5828                         ISP_SET_SENDMARKER(isp, chan, 1);
5829                         fcp->isp_loopstate = LOOP_PDB_RCVD;
5830                         ISP_MARK_PORTDB(isp, chan, 1);
5831                         isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
5832                             ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
5833                 }
5834                 break;
5835         }
5836         case ASYNC_CHANGE_NOTIFY:
5837         {
5838                 int lochan, hichan;
5839
5840                 if (IS_SCSI(isp)) {
5841                         isp_prt(isp, ISP_LOGWARN,
5842                             "bad CHANGE NOTIFY event for SCSI cards");
5843                         break;
5844                 }
5845                 if (ISP_FW_NEWER_THAN(isp, 4, 0, 25) && ISP_CAP_MULTI_ID(isp)) {
5846                         GET_24XX_BUS(isp, chan, "ASYNC_CHANGE_NOTIFY");
5847                         lochan = chan;
5848                         hichan = chan + 1;
5849                 } else {
5850                         lochan = 0;
5851                         hichan = isp->isp_nchan;
5852                 }
5853                 for (chan = lochan; chan < hichan; chan++) {
5854                         fcparam *fcp = FCPARAM(isp, chan);
5855
5856                         if (fcp->role == ISP_ROLE_NONE) {
5857                                 continue;
5858                         }
5859
5860                         if (fcp->isp_topo == TOPO_F_PORT) {
5861                                 fcp->isp_loopstate = LOOP_LSCAN_DONE;
5862                         } else {
5863                                 fcp->isp_loopstate = LOOP_PDB_RCVD;
5864                         }
5865                         ISP_MARK_PORTDB(isp, chan, 1);
5866                         isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
5867                             ISPASYNC_CHANGE_SNS);
5868                 }
5869                 break;
5870         }
5871
5872         case ASYNC_CONNMODE:
5873                 /*
5874                  * This only applies to 2100 amd 2200 cards
5875                  */
5876                 if (!IS_2200(isp) && !IS_2100(isp)) {
5877                         isp_prt(isp, ISP_LOGWARN,
5878                             "bad card for ASYNC_CONNMODE event");
5879                         break;
5880                 }
5881                 chan = 0;
5882                 mbox = ISP_READ(isp, OUTMAILBOX1);
5883                 ISP_MARK_PORTDB(isp, chan, 1);
5884                 switch (mbox) {
5885                 case ISP_CONN_LOOP:
5886                         isp_prt(isp, ISP_LOGINFO,
5887                             "Point-to-Point -> Loop mode");
5888                         break;
5889                 case ISP_CONN_PTP:
5890                         isp_prt(isp, ISP_LOGINFO,
5891                             "Loop -> Point-to-Point mode");
5892                         break;
5893                 case ISP_CONN_BADLIP:
5894                         isp_prt(isp, ISP_LOGWARN,
5895                             "Point-to-Point -> Loop mode (BAD LIP)");
5896                         break;
5897                 case ISP_CONN_FATAL:
5898                         isp->isp_dead = 1;
5899                         isp->isp_state = ISP_CRASHED;
5900                         isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
5901                         isp_async(isp, ISPASYNC_FW_CRASH);
5902                         return (-1);
5903                 case ISP_CONN_LOOPBACK:
5904                         isp_prt(isp, ISP_LOGWARN,
5905                             "Looped Back in Point-to-Point mode");
5906                         break;
5907                 default:
5908                         isp_prt(isp, ISP_LOGWARN,
5909                             "Unknown connection mode (0x%x)", mbox);
5910                         break;
5911                 }
5912                 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
5913                     ISPASYNC_CHANGE_OTHER);
5914                 FCPARAM(isp, chan)->sendmarker = 1;
5915                 FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
5916                 FCPARAM(isp, chan)->isp_loopstate = LOOP_LIP_RCVD;
5917                 break;
5918
5919         case ASYNC_RCV_ERR:
5920                 if (IS_24XX(isp)) {
5921                         isp_prt(isp, ISP_LOGWARN, "Receive Error");
5922                 } else {
5923                         isp_prt(isp, ISP_LOGWARN,
5924                             "Unknown Async Code 0x%x", mbox);
5925                 }
5926                 break;
5927         case ASYNC_RJT_SENT:    /* same as ASYNC_QFULL_SENT */
5928                 if (IS_24XX(isp)) {
5929                         isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
5930                         break;
5931                 } else if (IS_2200(isp)) {
5932                         isp_prt(isp, ISP_LOGTDEBUG0, "QFULL sent");
5933                         break;
5934                 }
5935                 /* FALLTHROUGH */
5936         default:
5937                 isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
5938                 break;
5939         }
5940
5941         if (pattern) {
5942                 int i, nh;
5943                 uint16_t handles[16];
5944
5945                 for (nh = 0, i = 1; i < MAX_MAILBOX(isp); i++) {
5946                         if ((pattern & (1 << i)) == 0) {
5947                                 continue;
5948                         }
5949                         handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
5950                 }
5951                 for (i = 0; i < nh; i++) {
5952                         isp_fastpost_complete(isp, handles[i]);
5953                         isp_prt(isp,  ISP_LOGDEBUG3,
5954                             "fast post completion of %u", handles[i]);
5955                 }
5956                 if (isp->isp_fpcchiwater < nh) {
5957                         isp->isp_fpcchiwater = nh;
5958                 }
5959         } else {
5960                 isp->isp_intoasync++;
5961         }
5962         return (rval);
5963 }
5964
5965 /*
5966  * Handle other response entries. A pointer to the request queue output
5967  * index is here in case we want to eat several entries at once, although
5968  * this is not used currently.
5969  */
5970
5971 static int
5972 isp_handle_other_response(ispsoftc_t *isp, int type,
5973     isphdr_t *hp, uint32_t *optrp)
5974 {
5975         switch (type) {
5976         case RQSTYPE_STATUS_CONT:
5977                 isp_prt(isp, ISP_LOGDEBUG0, "Ignored Continuation Response");
5978                 return (1);
5979         case RQSTYPE_MARKER:
5980                 isp_prt(isp, ISP_LOGDEBUG0, "Marker Response");
5981                 return (1);
5982         case RQSTYPE_ATIO:
5983         case RQSTYPE_CTIO:
5984         case RQSTYPE_ENABLE_LUN:
5985         case RQSTYPE_MODIFY_LUN:
5986         case RQSTYPE_NOTIFY:
5987         case RQSTYPE_NOTIFY_ACK:
5988         case RQSTYPE_CTIO1:
5989         case RQSTYPE_ATIO2:
5990         case RQSTYPE_CTIO2:
5991         case RQSTYPE_CTIO3:
5992         case RQSTYPE_CTIO7:
5993         case RQSTYPE_ABTS_RCVD:
5994         case RQSTYPE_ABTS_RSP:
5995                 isp->isp_rsltccmplt++;  /* count as a response completion */
5996 #ifdef  ISP_TARGET_MODE
5997                 if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
5998                         return (1);
5999                 }
6000 #endif
6001                 /* FALLTHROUGH */
6002         case RQSTYPE_RPT_ID_ACQ:
6003                 if (IS_24XX(isp)) {
6004                         isp_ridacq_t rid;
6005                         isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
6006                         if (rid.ridacq_format == 0) {
6007                         }
6008                         return (1);
6009                 }
6010                 /* FALLTHROUGH */
6011         case RQSTYPE_REQUEST:
6012         default:
6013                 ISP_DELAY(100);
6014                 if (type != isp_get_response_type(isp, hp)) {
6015                         /*
6016                          * This is questionable- we're just papering over
6017                          * something we've seen on SMP linux in target
6018                          * mode- we don't really know what's happening
6019                          * here that causes us to think we've gotten
6020                          * an entry, but that either the entry isn't
6021                          * filled out yet or our CPU read data is stale.
6022                          */
6023                         isp_prt(isp, ISP_LOGINFO,
6024                                 "unstable type in response queue");
6025                         return (-1);
6026                 }
6027                 isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
6028                     isp_get_response_type(isp, hp));
6029                 return (0);
6030         }
6031 }
6032
6033 static void
6034 isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
6035 {
6036         switch (sp->req_completion_status & 0xff) {
6037         case RQCS_COMPLETE:
6038                 if (XS_NOERR(xs)) {
6039                         XS_SETERR(xs, HBA_NOERROR);
6040                 }
6041                 return;
6042
6043         case RQCS_INCOMPLETE:
6044                 if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
6045                         isp_prt(isp, ISP_LOGDEBUG1,
6046                             "Selection Timeout for %d.%d.%d",
6047                             XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6048                         if (XS_NOERR(xs)) {
6049                                 XS_SETERR(xs, HBA_SELTIMEOUT);
6050                                 *rp = XS_XFRLEN(xs);
6051                         }
6052                         return;
6053                 }
6054                 isp_prt(isp, ISP_LOGERR,
6055                     "command incomplete for %d.%d.%d, state 0x%x",
6056                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
6057                     sp->req_state_flags);
6058                 break;
6059
6060         case RQCS_DMA_ERROR:
6061                 isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
6062                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6063                 *rp = XS_XFRLEN(xs);
6064                 break;
6065
6066         case RQCS_TRANSPORT_ERROR:
6067         {
6068                 char buf[172];
6069                 ISP_SNPRINTF(buf, sizeof (buf), "states=>");
6070                 if (sp->req_state_flags & RQSF_GOT_BUS) {
6071                         ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
6072                 }
6073                 if (sp->req_state_flags & RQSF_GOT_TARGET) {
6074                         ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
6075                 }
6076                 if (sp->req_state_flags & RQSF_SENT_CDB) {
6077                         ISP_SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
6078                 }
6079                 if (sp->req_state_flags & RQSF_XFRD_DATA) {
6080                         ISP_SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
6081                 }
6082                 if (sp->req_state_flags & RQSF_GOT_STATUS) {
6083                         ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
6084                 }
6085                 if (sp->req_state_flags & RQSF_GOT_SENSE) {
6086                         ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
6087                 }
6088                 if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
6089                         ISP_SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
6090                 }
6091                 ISP_SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
6092                 if (sp->req_status_flags & RQSTF_DISCONNECT) {
6093                         ISP_SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
6094                 }
6095                 if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
6096                         ISP_SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
6097                 }
6098                 if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
6099                         ISP_SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
6100                 }
6101                 if (sp->req_status_flags & RQSTF_BUS_RESET) {
6102                         ISP_SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
6103                 }
6104                 if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
6105                         ISP_SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
6106                 }
6107                 if (sp->req_status_flags & RQSTF_ABORTED) {
6108                         ISP_SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
6109                 }
6110                 if (sp->req_status_flags & RQSTF_TIMEOUT) {
6111                         ISP_SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
6112                 }
6113                 if (sp->req_status_flags & RQSTF_NEGOTIATION) {
6114                         ISP_SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
6115                 }
6116                 isp_prt(isp, ISP_LOGERR, "%s", buf);
6117                 isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
6118                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
6119                 *rp = XS_XFRLEN(xs);
6120                 break;
6121         }
6122         case RQCS_RESET_OCCURRED:
6123         {
6124                 int chan;
6125                 isp_prt(isp, ISP_LOGWARN,
6126                     "bus reset destroyed command for %d.%d.%d",
6127                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6128                 for (chan = 0; chan < isp->isp_nchan; chan++) {
6129                         FCPARAM(isp, chan)->sendmarker = 1;
6130                 }
6131                 if (XS_NOERR(xs)) {
6132                         XS_SETERR(xs, HBA_BUSRESET);
6133                 }
6134                 *rp = XS_XFRLEN(xs);
6135                 return;
6136         }
6137         case RQCS_ABORTED:
6138                 isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
6139                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6140                 ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
6141                 if (XS_NOERR(xs)) {
6142                         XS_SETERR(xs, HBA_ABORTED);
6143                 }
6144                 return;
6145
6146         case RQCS_TIMEOUT:
6147                 isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
6148                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6149                 /*
6150                  * XXX: Check to see if we logged out of the device.
6151                  */
6152                 if (XS_NOERR(xs)) {
6153                         XS_SETERR(xs, HBA_CMDTIMEOUT);
6154                 }
6155                 return;
6156
6157         case RQCS_DATA_OVERRUN:
6158                 XS_SET_RESID(xs, sp->req_resid);
6159                 isp_prt(isp, ISP_LOGERR, "data overrun (%ld) for command on %d.%d.%d",
6160                     (long) XS_GET_RESID(xs), XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6161                 if (XS_NOERR(xs)) {
6162                         XS_SETERR(xs, HBA_DATAOVR);
6163                 }
6164                 return;
6165
6166         case RQCS_COMMAND_OVERRUN:
6167                 isp_prt(isp, ISP_LOGERR,
6168                     "command overrun for command on %d.%d.%d",
6169                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6170                 break;
6171
6172         case RQCS_STATUS_OVERRUN:
6173                 isp_prt(isp, ISP_LOGERR,
6174                     "status overrun for command on %d.%d.%d",
6175                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6176                 break;
6177
6178         case RQCS_BAD_MESSAGE:
6179                 isp_prt(isp, ISP_LOGERR,
6180                     "msg not COMMAND COMPLETE after status %d.%d.%d",
6181                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6182                 break;
6183
6184         case RQCS_NO_MESSAGE_OUT:
6185                 isp_prt(isp, ISP_LOGERR,
6186                     "No MESSAGE OUT phase after selection on %d.%d.%d",
6187                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6188                 break;
6189
6190         case RQCS_EXT_ID_FAILED:
6191                 isp_prt(isp, ISP_LOGERR, "EXTENDED IDENTIFY failed %d.%d.%d",
6192                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6193                 break;
6194
6195         case RQCS_IDE_MSG_FAILED:
6196                 isp_prt(isp, ISP_LOGERR,
6197                     "INITIATOR DETECTED ERROR rejected by %d.%d.%d",
6198                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6199                 break;
6200
6201         case RQCS_ABORT_MSG_FAILED:
6202                 isp_prt(isp, ISP_LOGERR, "ABORT OPERATION rejected by %d.%d.%d",
6203                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6204                 break;
6205
6206         case RQCS_REJECT_MSG_FAILED:
6207                 isp_prt(isp, ISP_LOGERR, "MESSAGE REJECT rejected by %d.%d.%d",
6208                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6209                 break;
6210
6211         case RQCS_NOP_MSG_FAILED:
6212                 isp_prt(isp, ISP_LOGERR, "NOP rejected by %d.%d.%d",
6213                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6214                 break;
6215
6216         case RQCS_PARITY_ERROR_MSG_FAILED:
6217                 isp_prt(isp, ISP_LOGERR,
6218                     "MESSAGE PARITY ERROR rejected by %d.%d.%d",
6219                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6220                 break;
6221
6222         case RQCS_DEVICE_RESET_MSG_FAILED:
6223                 isp_prt(isp, ISP_LOGWARN,
6224                     "BUS DEVICE RESET rejected by %d.%d.%d",
6225                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6226                 break;
6227
6228         case RQCS_ID_MSG_FAILED:
6229                 isp_prt(isp, ISP_LOGERR, "IDENTIFY rejected by %d.%d.%d",
6230                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6231                 break;
6232
6233         case RQCS_UNEXP_BUS_FREE:
6234                 isp_prt(isp, ISP_LOGERR, "%d.%d.%d had an unexpected bus free",
6235                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6236                 break;
6237
6238         case RQCS_DATA_UNDERRUN:
6239         {
6240                 if (IS_FC(isp)) {
6241                         int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
6242                         if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
6243                                 isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
6244                                     XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
6245                                     (ru_marked)? "marked" : "not marked");
6246                                 if (XS_NOERR(xs)) {
6247                                         XS_SETERR(xs, HBA_BOTCH);
6248                                 }
6249                                 return;
6250                         }
6251                 }
6252                 XS_SET_RESID(xs, sp->req_resid);
6253                 if (XS_NOERR(xs)) {
6254                         XS_SETERR(xs, HBA_NOERROR);
6255                 }
6256                 return;
6257         }
6258
6259         case RQCS_XACT_ERR1:
6260                 isp_prt(isp, ISP_LOGERR, xact1, XS_CHANNEL(xs),
6261                     XS_TGT(xs), XS_LUN(xs));
6262                 break;
6263
6264         case RQCS_XACT_ERR2:
6265                 isp_prt(isp, ISP_LOGERR, xact2,
6266                     XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs));
6267                 break;
6268
6269         case RQCS_XACT_ERR3:
6270                 isp_prt(isp, ISP_LOGERR, xact3,
6271                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6272                 break;
6273
6274         case RQCS_BAD_ENTRY:
6275                 isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
6276                 break;
6277
6278         case RQCS_QUEUE_FULL:
6279                 isp_prt(isp, ISP_LOGDEBUG0,
6280                     "internal queues full for %d.%d.%d status 0x%x",
6281                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), *XS_STSP(xs));
6282
6283                 /*
6284                  * If QFULL or some other status byte is set, then this
6285                  * isn't an error, per se.
6286                  *
6287                  * Unfortunately, some QLogic f/w writers have, in
6288                  * some cases, ommitted to *set* status to QFULL.
6289                  *
6290
6291                 if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
6292                         XS_SETERR(xs, HBA_NOERROR);
6293                         return;
6294                 }
6295
6296                  *
6297                  *
6298                  */
6299
6300                 *XS_STSP(xs) = SCSI_QFULL;
6301                 XS_SETERR(xs, HBA_NOERROR);
6302                 return;
6303
6304         case RQCS_PHASE_SKIPPED:
6305                 isp_prt(isp, ISP_LOGERR, pskip, XS_CHANNEL(xs),
6306                     XS_TGT(xs), XS_LUN(xs));
6307                 break;
6308
6309         case RQCS_ARQS_FAILED:
6310                 isp_prt(isp, ISP_LOGERR,
6311                     "Auto Request Sense failed for %d.%d.%d",
6312                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6313                 if (XS_NOERR(xs)) {
6314                         XS_SETERR(xs, HBA_ARQFAIL);
6315                 }
6316                 return;
6317
6318         case RQCS_WIDE_FAILED:
6319                 isp_prt(isp, ISP_LOGERR,
6320                     "Wide Negotiation failed for %d.%d.%d",
6321                     XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
6322                 if (IS_SCSI(isp)) {
6323                         sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
6324                         sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
6325                         sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
6326                         sdp->update = 1;
6327                 }
6328                 if (XS_NOERR(xs)) {
6329                         XS_SETERR(xs, HBA_NOERROR);
6330                 }
6331                 return;
6332
6333         case RQCS_SYNCXFER_FAILED:
6334                 isp_prt(isp, ISP_LOGERR,
6335                     "SDTR Message failed for target %d.%d.%d",
6336                     XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
6337                 if (IS_SCSI(isp)) {
6338                         sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
6339                         sdp += XS_CHANNEL(xs);
6340                         sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
6341                         sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
6342                         sdp->update = 1;
6343                 }
6344                 break;
6345
6346         case RQCS_LVD_BUSERR:
6347                 isp_prt(isp, ISP_LOGERR,
6348                     "Bad LVD condition while talking to %d.%d.%d",
6349                     XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
6350                 break;
6351
6352         case RQCS_PORT_UNAVAILABLE:
6353                 /*
6354                  * No such port on the loop. Moral equivalent of SELTIMEO
6355                  */
6356         case RQCS_PORT_LOGGED_OUT:
6357         {
6358                 const char *reason;
6359                 uint8_t sts = sp->req_completion_status & 0xff;
6360
6361                 /*
6362                  * It was there (maybe)- treat as a selection timeout.
6363                  */
6364                 if (sts == RQCS_PORT_UNAVAILABLE) {
6365                         reason = "unavailable";
6366                 } else {
6367                         reason = "logout";
6368                 }
6369
6370                 isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
6371                     reason, XS_TGT(xs));
6372
6373                 /*
6374                  * If we're on a local loop, force a LIP (which is overkill)
6375                  * to force a re-login of this unit. If we're on fabric,
6376                  * then we'll have to log in again as a matter of course.
6377                  */
6378                 if (FCPARAM(isp, 0)->isp_topo == TOPO_NL_PORT ||
6379                     FCPARAM(isp, 0)->isp_topo == TOPO_FL_PORT) {
6380                         mbreg_t mbs;
6381                         MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
6382                         if (ISP_CAP_2KLOGIN(isp)) {
6383                                 mbs.ibits = (1 << 10);
6384                         }
6385                         isp_mboxcmd_qnw(isp, &mbs, 1);
6386                 }
6387                 if (XS_NOERR(xs)) {
6388                         XS_SETERR(xs, HBA_SELTIMEOUT);
6389                 }
6390                 return;
6391         }
6392         case RQCS_PORT_CHANGED:
6393                 isp_prt(isp, ISP_LOGWARN,
6394                     "port changed for target %d", XS_TGT(xs));
6395                 if (XS_NOERR(xs)) {
6396                         XS_SETERR(xs, HBA_SELTIMEOUT);
6397                 }
6398                 return;
6399
6400         case RQCS_PORT_BUSY:
6401                 isp_prt(isp, ISP_LOGWARN,
6402                     "port busy for target %d", XS_TGT(xs));
6403                 if (XS_NOERR(xs)) {
6404                         XS_SETERR(xs, HBA_TGTBSY);
6405                 }
6406                 return;
6407
6408         default:
6409                 isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
6410                     sp->req_completion_status);
6411                 break;
6412         }
6413         if (XS_NOERR(xs)) {
6414                 XS_SETERR(xs, HBA_BOTCH);
6415         }
6416 }
6417
6418 static void
6419 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
6420     XS_T *xs, long *rp)
6421 {
6422         int ru_marked, sv_marked;
6423         int chan = XS_CHANNEL(xs);
6424
6425         switch (sp->req_completion_status) {
6426         case RQCS_COMPLETE:
6427                 if (XS_NOERR(xs)) {
6428                         XS_SETERR(xs, HBA_NOERROR);
6429                 }
6430                 return;
6431
6432         case RQCS_DMA_ERROR:
6433                 isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
6434                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6435                 break;
6436
6437         case RQCS_TRANSPORT_ERROR:
6438                 isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d",
6439                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6440                 break;
6441
6442         case RQCS_RESET_OCCURRED:
6443                 isp_prt(isp, ISP_LOGWARN,
6444                     "reset destroyed command for %d.%d.%d",
6445                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6446                 FCPARAM(isp, chan)->sendmarker = 1;
6447                 if (XS_NOERR(xs)) {
6448                         XS_SETERR(xs, HBA_BUSRESET);
6449                 }
6450                 return;
6451
6452         case RQCS_ABORTED:
6453                 isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
6454                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6455                 FCPARAM(isp, chan)->sendmarker = 1;
6456                 if (XS_NOERR(xs)) {
6457                         XS_SETERR(xs, HBA_ABORTED);
6458                 }
6459                 return;
6460
6461         case RQCS_TIMEOUT:
6462                 isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
6463                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6464                 if (XS_NOERR(xs)) {
6465                         XS_SETERR(xs, HBA_CMDTIMEOUT);
6466                 }
6467                 return;
6468
6469         case RQCS_DATA_OVERRUN:
6470                 XS_SET_RESID(xs, sp->req_resid);
6471                 isp_prt(isp, ISP_LOGERR,
6472                     "data overrun for command on %d.%d.%d",
6473                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6474                 if (XS_NOERR(xs)) {
6475                         XS_SETERR(xs, HBA_DATAOVR);
6476                 }
6477                 return;
6478
6479         case RQCS_24XX_DRE:     /* data reassembly error */
6480                 isp_prt(isp, ISP_LOGERR,
6481                     "Chan %d data reassembly error for target %d",
6482                     chan, XS_TGT(xs));
6483                 if (XS_NOERR(xs)) {
6484                         XS_SETERR(xs, HBA_ABORTED);
6485                 }
6486                 *rp = XS_XFRLEN(xs);
6487                 return;
6488
6489         case RQCS_24XX_TABORT:  /* aborted by target */
6490                 isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS",
6491                     chan, XS_TGT(xs));
6492                 if (XS_NOERR(xs)) {
6493                         XS_SETERR(xs, HBA_ABORTED);
6494                 }
6495                 return;
6496
6497         case RQCS_DATA_UNDERRUN:
6498                 ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
6499                 /*
6500                  * We can get an underrun w/o things being marked
6501                  * if we got a non-zero status.
6502                  */
6503                 sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
6504                 if ((ru_marked == 0 && sv_marked == 0) ||
6505                     (sp->req_resid > XS_XFRLEN(xs))) {
6506                         isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
6507                             XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
6508                             (ru_marked)? "marked" : "not marked");
6509                         if (XS_NOERR(xs)) {
6510                                 XS_SETERR(xs, HBA_BOTCH);
6511                         }
6512                         return;
6513                 }
6514                 XS_SET_RESID(xs, sp->req_resid);
6515                 isp_prt(isp, ISP_LOGDEBUG0,
6516                     "%d.%d.%d data underrun (%d) for command 0x%x",
6517                     XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
6518                     sp->req_resid, XS_CDBP(xs)[0] & 0xff);
6519                 if (XS_NOERR(xs)) {
6520                         XS_SETERR(xs, HBA_NOERROR);
6521                 }
6522                 return;
6523
6524         case RQCS_PORT_UNAVAILABLE:
6525                 /*
6526                  * No such port on the loop. Moral equivalent of SELTIMEO
6527                  */
6528         case RQCS_PORT_LOGGED_OUT:
6529         {
6530                 const char *reason;
6531                 uint8_t sts = sp->req_completion_status & 0xff;
6532
6533                 /*
6534                  * It was there (maybe)- treat as a selection timeout.
6535                  */
6536                 if (sts == RQCS_PORT_UNAVAILABLE) {
6537                         reason = "unavailable";
6538                 } else {
6539                         reason = "logout";
6540                 }
6541
6542                 isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d",
6543                     chan, reason, XS_TGT(xs));
6544
6545                 /*
6546                  * There is no MBOX_INIT_LIP for the 24XX.
6547                  */
6548                 if (XS_NOERR(xs)) {
6549                         XS_SETERR(xs, HBA_SELTIMEOUT);
6550                 }
6551                 return;
6552         }
6553         case RQCS_PORT_CHANGED:
6554                 isp_prt(isp, ISP_LOGWARN,
6555                     "port changed for target %d chan %d", XS_TGT(xs), chan);
6556                 if (XS_NOERR(xs)) {
6557                         XS_SETERR(xs, HBA_SELTIMEOUT);
6558                 }
6559                 return;
6560
6561
6562         case RQCS_24XX_ENOMEM:  /* f/w resource unavailable */
6563                 isp_prt(isp, ISP_LOGWARN,
6564                     "f/w resource unavailable for target %d chan %d",
6565                     XS_TGT(xs), chan);
6566                 if (XS_NOERR(xs)) {
6567                         *XS_STSP(xs) = SCSI_BUSY;
6568                         XS_SETERR(xs, HBA_TGTBSY);
6569                 }
6570                 return;
6571
6572         case RQCS_24XX_TMO:     /* task management overrun */
6573                 isp_prt(isp, ISP_LOGWARN,
6574                     "command for target %d overlapped task management for "
6575                     "chan %d", XS_TGT(xs), chan);
6576                 if (XS_NOERR(xs)) {
6577                         *XS_STSP(xs) = SCSI_BUSY;
6578                         XS_SETERR(xs, HBA_TGTBSY);
6579                 }
6580                 return;
6581
6582         default:
6583                 isp_prt(isp, ISP_LOGERR,
6584                     "Unknown Completion Status 0x%x on chan %d",
6585                     sp->req_completion_status, chan);
6586                 break;
6587         }
6588         if (XS_NOERR(xs)) {
6589                 XS_SETERR(xs, HBA_BOTCH);
6590         }
6591 }
6592
6593 static void
6594 isp_fastpost_complete(ispsoftc_t *isp, uint16_t fph)
6595 {
6596         XS_T *xs;
6597
6598         if (fph == 0) {
6599                 return;
6600         }
6601         xs = isp_find_xs(isp, fph);
6602         if (xs == NULL) {
6603                 isp_prt(isp, ISP_LOGWARN,
6604                     "Command for fast post handle 0x%x not found", fph);
6605                 return;
6606         }
6607         isp_destroy_handle(isp, fph);
6608
6609         /*
6610          * Since we don't have a result queue entry item,
6611          * we must believe that SCSI status is zero and
6612          * that all data transferred.
6613          */
6614         XS_SET_RESID(xs, 0);
6615         *XS_STSP(xs) = SCSI_GOOD;
6616         if (XS_XFRLEN(xs)) {
6617                 ISP_DMAFREE(isp, xs, fph);
6618         }
6619         if (isp->isp_nactive) {
6620                 isp->isp_nactive--;
6621         }
6622         isp->isp_fphccmplt++;
6623         isp_done(xs);
6624 }
6625
6626 static int
6627 isp_mbox_continue(ispsoftc_t *isp)
6628 {
6629         mbreg_t mbs;
6630         uint16_t *ptr;
6631         uint32_t offset;
6632
6633         switch (isp->isp_lastmbxcmd) {
6634         case MBOX_WRITE_RAM_WORD:
6635         case MBOX_READ_RAM_WORD:
6636         case MBOX_WRITE_RAM_WORD_EXTENDED:
6637         case MBOX_READ_RAM_WORD_EXTENDED:
6638                 break;
6639         default:
6640                 return (1);
6641         }
6642         if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
6643                 isp->isp_mbxwrk0 = 0;
6644                 return (-1);
6645         }
6646
6647         /*
6648          * Clear the previous interrupt.
6649          */
6650         if (IS_24XX(isp)) {
6651                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
6652         } else {
6653                 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
6654                 ISP_WRITE(isp, BIU_SEMA, 0);
6655         }
6656
6657         /*
6658          * Continue with next word.
6659          */
6660         ISP_MEMZERO(&mbs, sizeof (mbs));
6661         ptr = isp->isp_mbxworkp;
6662         switch (isp->isp_lastmbxcmd) {
6663         case MBOX_WRITE_RAM_WORD:
6664                 mbs.param[1] = isp->isp_mbxwrk1++;
6665                 mbs.param[2] = *ptr++;
6666                 break;
6667         case MBOX_READ_RAM_WORD:
6668                 *ptr++ = isp->isp_mboxtmp[2];
6669                 mbs.param[1] = isp->isp_mbxwrk1++;
6670                 break;
6671         case MBOX_WRITE_RAM_WORD_EXTENDED:
6672                 offset = isp->isp_mbxwrk1;
6673                 offset |= isp->isp_mbxwrk8 << 16;
6674
6675                 mbs.param[2] = *ptr++;
6676                 mbs.param[1] = offset;
6677                 mbs.param[8] = offset >> 16;
6678                 isp->isp_mbxwrk1 = ++offset;
6679                 isp->isp_mbxwrk8 = offset >> 16;
6680                 break;
6681         case MBOX_READ_RAM_WORD_EXTENDED:
6682                 offset = isp->isp_mbxwrk1;
6683                 offset |= isp->isp_mbxwrk8 << 16;
6684
6685                 *ptr++ = isp->isp_mboxtmp[2];
6686                 mbs.param[1] = offset;
6687                 mbs.param[8] = offset >> 16;
6688                 isp->isp_mbxwrk1 = ++offset;
6689                 isp->isp_mbxwrk8 = offset >> 16;
6690                 break;
6691         }
6692         isp->isp_mbxworkp = ptr;
6693         isp->isp_mbxwrk0--;
6694         mbs.param[0] = isp->isp_lastmbxcmd;
6695         mbs.logval = MBLOGALL;
6696         isp_mboxcmd_qnw(isp, &mbs, 0);
6697         return (0);
6698 }
6699
6700 #define HIWRD(x)                        ((x) >> 16)
6701 #define LOWRD(x)                        ((x)  & 0xffff)
6702 #define ISPOPMAP(a, b)                  (((a) << 16) | (b))
6703 static const uint32_t mbpscsi[] = {
6704         ISPOPMAP(0x01, 0x01),   /* 0x00: MBOX_NO_OP */
6705         ISPOPMAP(0x1f, 0x01),   /* 0x01: MBOX_LOAD_RAM */
6706         ISPOPMAP(0x03, 0x01),   /* 0x02: MBOX_EXEC_FIRMWARE */
6707         ISPOPMAP(0x1f, 0x01),   /* 0x03: MBOX_DUMP_RAM */
6708         ISPOPMAP(0x07, 0x07),   /* 0x04: MBOX_WRITE_RAM_WORD */
6709         ISPOPMAP(0x03, 0x07),   /* 0x05: MBOX_READ_RAM_WORD */
6710         ISPOPMAP(0x3f, 0x3f),   /* 0x06: MBOX_MAILBOX_REG_TEST */
6711         ISPOPMAP(0x07, 0x07),   /* 0x07: MBOX_VERIFY_CHECKSUM   */
6712         ISPOPMAP(0x01, 0x0f),   /* 0x08: MBOX_ABOUT_FIRMWARE */
6713         ISPOPMAP(0x00, 0x00),   /* 0x09: */
6714         ISPOPMAP(0x00, 0x00),   /* 0x0a: */
6715         ISPOPMAP(0x00, 0x00),   /* 0x0b: */
6716         ISPOPMAP(0x00, 0x00),   /* 0x0c: */
6717         ISPOPMAP(0x00, 0x00),   /* 0x0d: */
6718         ISPOPMAP(0x01, 0x05),   /* 0x0e: MBOX_CHECK_FIRMWARE */
6719         ISPOPMAP(0x00, 0x00),   /* 0x0f: */
6720         ISPOPMAP(0x1f, 0x1f),   /* 0x10: MBOX_INIT_REQ_QUEUE */
6721         ISPOPMAP(0x3f, 0x3f),   /* 0x11: MBOX_INIT_RES_QUEUE */
6722         ISPOPMAP(0x0f, 0x0f),   /* 0x12: MBOX_EXECUTE_IOCB */
6723         ISPOPMAP(0x03, 0x03),   /* 0x13: MBOX_WAKE_UP   */
6724         ISPOPMAP(0x01, 0x3f),   /* 0x14: MBOX_STOP_FIRMWARE */
6725         ISPOPMAP(0x0f, 0x0f),   /* 0x15: MBOX_ABORT */
6726         ISPOPMAP(0x03, 0x03),   /* 0x16: MBOX_ABORT_DEVICE */
6727         ISPOPMAP(0x07, 0x07),   /* 0x17: MBOX_ABORT_TARGET */
6728         ISPOPMAP(0x07, 0x07),   /* 0x18: MBOX_BUS_RESET */
6729         ISPOPMAP(0x03, 0x07),   /* 0x19: MBOX_STOP_QUEUE */
6730         ISPOPMAP(0x03, 0x07),   /* 0x1a: MBOX_START_QUEUE */
6731         ISPOPMAP(0x03, 0x07),   /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6732         ISPOPMAP(0x03, 0x07),   /* 0x1c: MBOX_ABORT_QUEUE */
6733         ISPOPMAP(0x03, 0x4f),   /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6734         ISPOPMAP(0x00, 0x00),   /* 0x1e: */
6735         ISPOPMAP(0x01, 0x07),   /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6736         ISPOPMAP(0x01, 0x07),   /* 0x20: MBOX_GET_INIT_SCSI_ID */
6737         ISPOPMAP(0x01, 0x07),   /* 0x21: MBOX_GET_SELECT_TIMEOUT */
6738         ISPOPMAP(0x01, 0xc7),   /* 0x22: MBOX_GET_RETRY_COUNT   */
6739         ISPOPMAP(0x01, 0x07),   /* 0x23: MBOX_GET_TAG_AGE_LIMIT */
6740         ISPOPMAP(0x01, 0x03),   /* 0x24: MBOX_GET_CLOCK_RATE */
6741         ISPOPMAP(0x01, 0x07),   /* 0x25: MBOX_GET_ACT_NEG_STATE */
6742         ISPOPMAP(0x01, 0x07),   /* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
6743         ISPOPMAP(0x01, 0x07),   /* 0x27: MBOX_GET_PCI_PARAMS */
6744         ISPOPMAP(0x03, 0x4f),   /* 0x28: MBOX_GET_TARGET_PARAMS */
6745         ISPOPMAP(0x03, 0x0f),   /* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
6746         ISPOPMAP(0x01, 0x07),   /* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
6747         ISPOPMAP(0x00, 0x00),   /* 0x2b: */
6748         ISPOPMAP(0x00, 0x00),   /* 0x2c: */
6749         ISPOPMAP(0x00, 0x00),   /* 0x2d: */
6750         ISPOPMAP(0x00, 0x00),   /* 0x2e: */
6751         ISPOPMAP(0x00, 0x00),   /* 0x2f: */
6752         ISPOPMAP(0x03, 0x03),   /* 0x30: MBOX_SET_INIT_SCSI_ID */
6753         ISPOPMAP(0x07, 0x07),   /* 0x31: MBOX_SET_SELECT_TIMEOUT */
6754         ISPOPMAP(0xc7, 0xc7),   /* 0x32: MBOX_SET_RETRY_COUNT   */
6755         ISPOPMAP(0x07, 0x07),   /* 0x33: MBOX_SET_TAG_AGE_LIMIT */
6756         ISPOPMAP(0x03, 0x03),   /* 0x34: MBOX_SET_CLOCK_RATE */
6757         ISPOPMAP(0x07, 0x07),   /* 0x35: MBOX_SET_ACT_NEG_STATE */
6758         ISPOPMAP(0x07, 0x07),   /* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
6759         ISPOPMAP(0x07, 0x07),   /* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
6760         ISPOPMAP(0x4f, 0x4f),   /* 0x38: MBOX_SET_TARGET_PARAMS */
6761         ISPOPMAP(0x0f, 0x0f),   /* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
6762         ISPOPMAP(0x07, 0x07),   /* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
6763         ISPOPMAP(0x00, 0x00),   /* 0x3b: */
6764         ISPOPMAP(0x00, 0x00),   /* 0x3c: */
6765         ISPOPMAP(0x00, 0x00),   /* 0x3d: */
6766         ISPOPMAP(0x00, 0x00),   /* 0x3e: */
6767         ISPOPMAP(0x00, 0x00),   /* 0x3f: */
6768         ISPOPMAP(0x01, 0x03),   /* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
6769         ISPOPMAP(0x3f, 0x01),   /* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
6770         ISPOPMAP(0x03, 0x07),   /* 0x42: MBOX_EXEC_BIOS_IOCB */
6771         ISPOPMAP(0x00, 0x00),   /* 0x43: */
6772         ISPOPMAP(0x00, 0x00),   /* 0x44: */
6773         ISPOPMAP(0x03, 0x03),   /* 0x45: SET SYSTEM PARAMETER */
6774         ISPOPMAP(0x01, 0x03),   /* 0x46: GET SYSTEM PARAMETER */
6775         ISPOPMAP(0x00, 0x00),   /* 0x47: */
6776         ISPOPMAP(0x01, 0xcf),   /* 0x48: GET SCAM CONFIGURATION */
6777         ISPOPMAP(0xcf, 0xcf),   /* 0x49: SET SCAM CONFIGURATION */
6778         ISPOPMAP(0x03, 0x03),   /* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
6779         ISPOPMAP(0x01, 0x03),   /* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
6780         ISPOPMAP(0x00, 0x00),   /* 0x4c: */
6781         ISPOPMAP(0x00, 0x00),   /* 0x4d: */
6782         ISPOPMAP(0x00, 0x00),   /* 0x4e: */
6783         ISPOPMAP(0x00, 0x00),   /* 0x4f: */
6784         ISPOPMAP(0xdf, 0xdf),   /* 0x50: LOAD RAM A64 */
6785         ISPOPMAP(0xdf, 0xdf),   /* 0x51: DUMP RAM A64 */
6786         ISPOPMAP(0xdf, 0xff),   /* 0x52: INITIALIZE REQUEST QUEUE A64 */
6787         ISPOPMAP(0xef, 0xff),   /* 0x53: INITIALIZE RESPONSE QUEUE A64 */
6788         ISPOPMAP(0xcf, 0x01),   /* 0x54: EXECUCUTE COMMAND IOCB A64 */
6789         ISPOPMAP(0x07, 0x01),   /* 0x55: ENABLE TARGET MODE */
6790         ISPOPMAP(0x03, 0x0f),   /* 0x56: GET TARGET STATUS */
6791         ISPOPMAP(0x00, 0x00),   /* 0x57: */
6792         ISPOPMAP(0x00, 0x00),   /* 0x58: */
6793         ISPOPMAP(0x00, 0x00),   /* 0x59: */
6794         ISPOPMAP(0x03, 0x03),   /* 0x5a: SET DATA OVERRUN RECOVERY MODE */
6795         ISPOPMAP(0x01, 0x03),   /* 0x5b: GET DATA OVERRUN RECOVERY MODE */
6796         ISPOPMAP(0x0f, 0x0f),   /* 0x5c: SET HOST DATA */
6797         ISPOPMAP(0x01, 0x01)    /* 0x5d: GET NOST DATA */
6798 };
6799
6800 static const char *scsi_mbcmd_names[] = {
6801         "NO-OP",
6802         "LOAD RAM",
6803         "EXEC FIRMWARE",
6804         "DUMP RAM",
6805         "WRITE RAM WORD",
6806         "READ RAM WORD",
6807         "MAILBOX REG TEST",
6808         "VERIFY CHECKSUM",
6809         "ABOUT FIRMWARE",
6810         NULL,
6811         NULL,
6812         NULL,
6813         NULL,
6814         NULL,
6815         "CHECK FIRMWARE",
6816         NULL,
6817         "INIT REQUEST QUEUE",
6818         "INIT RESULT QUEUE",
6819         "EXECUTE IOCB",
6820         "WAKE UP",
6821         "STOP FIRMWARE",
6822         "ABORT",
6823         "ABORT DEVICE",
6824         "ABORT TARGET",
6825         "BUS RESET",
6826         "STOP QUEUE",
6827         "START QUEUE",
6828         "SINGLE STEP QUEUE",
6829         "ABORT QUEUE",
6830         "GET DEV QUEUE STATUS",
6831         NULL,
6832         "GET FIRMWARE STATUS",
6833         "GET INIT SCSI ID",
6834         "GET SELECT TIMEOUT",
6835         "GET RETRY COUNT",
6836         "GET TAG AGE LIMIT",
6837         "GET CLOCK RATE",
6838         "GET ACT NEG STATE",
6839         "GET ASYNC DATA SETUP TIME",
6840         "GET PCI PARAMS",
6841         "GET TARGET PARAMS",
6842         "GET DEV QUEUE PARAMS",
6843         "GET RESET DELAY PARAMS",
6844         NULL,
6845         NULL,
6846         NULL,
6847         NULL,
6848         NULL,
6849         "SET INIT SCSI ID",
6850         "SET SELECT TIMEOUT",
6851         "SET RETRY COUNT",
6852         "SET TAG AGE LIMIT",
6853         "SET CLOCK RATE",
6854         "SET ACT NEG STATE",
6855         "SET ASYNC DATA SETUP TIME",
6856         "SET PCI CONTROL PARAMS",
6857         "SET TARGET PARAMS",
6858         "SET DEV QUEUE PARAMS",
6859         "SET RESET DELAY PARAMS",
6860         NULL,
6861         NULL,
6862         NULL,
6863         NULL,
6864         NULL,
6865         "RETURN BIOS BLOCK ADDR",
6866         "WRITE FOUR RAM WORDS",
6867         "EXEC BIOS IOCB",
6868         NULL,
6869         NULL,
6870         "SET SYSTEM PARAMETER",
6871         "GET SYSTEM PARAMETER",
6872         NULL,
6873         "GET SCAM CONFIGURATION",
6874         "SET SCAM CONFIGURATION",
6875         "SET FIRMWARE FEATURES",
6876         "GET FIRMWARE FEATURES",
6877         NULL,
6878         NULL,
6879         NULL,
6880         NULL,
6881         "LOAD RAM A64",
6882         "DUMP RAM A64",
6883         "INITIALIZE REQUEST QUEUE A64",
6884         "INITIALIZE RESPONSE QUEUE A64",
6885         "EXECUTE IOCB A64",
6886         "ENABLE TARGET MODE",
6887         "GET TARGET MODE STATE",
6888         NULL,
6889         NULL,
6890         NULL,
6891         "SET DATA OVERRUN RECOVERY MODE",
6892         "GET DATA OVERRUN RECOVERY MODE",
6893         "SET HOST DATA",
6894         "GET NOST DATA",
6895 };
6896
6897 static const uint32_t mbpfc[] = {
6898         ISPOPMAP(0x01, 0x01),   /* 0x00: MBOX_NO_OP */
6899         ISPOPMAP(0x1f, 0x01),   /* 0x01: MBOX_LOAD_RAM */
6900         ISPOPMAP(0x0f, 0x01),   /* 0x02: MBOX_EXEC_FIRMWARE */
6901         ISPOPMAP(0xdf, 0x01),   /* 0x03: MBOX_DUMP_RAM */
6902         ISPOPMAP(0x07, 0x07),   /* 0x04: MBOX_WRITE_RAM_WORD */
6903         ISPOPMAP(0x03, 0x07),   /* 0x05: MBOX_READ_RAM_WORD */
6904         ISPOPMAP(0xff, 0xff),   /* 0x06: MBOX_MAILBOX_REG_TEST */
6905         ISPOPMAP(0x07, 0x07),   /* 0x07: MBOX_VERIFY_CHECKSUM   */
6906         ISPOPMAP(0x01, 0x4f),   /* 0x08: MBOX_ABOUT_FIRMWARE */
6907         ISPOPMAP(0xdf, 0x01),   /* 0x09: MBOX_LOAD_RISC_RAM_2100 */
6908         ISPOPMAP(0xdf, 0x01),   /* 0x0a: DUMP RAM */
6909         ISPOPMAP(0x1ff, 0x01),  /* 0x0b: MBOX_LOAD_RISC_RAM */
6910         ISPOPMAP(0x00, 0x00),   /* 0x0c: */
6911         ISPOPMAP(0x10f, 0x01),  /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
6912         ISPOPMAP(0x01, 0x05),   /* 0x0e: MBOX_CHECK_FIRMWARE */
6913         ISPOPMAP(0x10f, 0x05),  /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
6914         ISPOPMAP(0x1f, 0x11),   /* 0x10: MBOX_INIT_REQ_QUEUE */
6915         ISPOPMAP(0x2f, 0x21),   /* 0x11: MBOX_INIT_RES_QUEUE */
6916         ISPOPMAP(0x0f, 0x01),   /* 0x12: MBOX_EXECUTE_IOCB */
6917         ISPOPMAP(0x03, 0x03),   /* 0x13: MBOX_WAKE_UP   */
6918         ISPOPMAP(0x01, 0xff),   /* 0x14: MBOX_STOP_FIRMWARE */
6919         ISPOPMAP(0x4f, 0x01),   /* 0x15: MBOX_ABORT */
6920         ISPOPMAP(0x07, 0x01),   /* 0x16: MBOX_ABORT_DEVICE */
6921         ISPOPMAP(0x07, 0x01),   /* 0x17: MBOX_ABORT_TARGET */
6922         ISPOPMAP(0x03, 0x03),   /* 0x18: MBOX_BUS_RESET */
6923         ISPOPMAP(0x07, 0x05),   /* 0x19: MBOX_STOP_QUEUE */
6924         ISPOPMAP(0x07, 0x05),   /* 0x1a: MBOX_START_QUEUE */
6925         ISPOPMAP(0x07, 0x05),   /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6926         ISPOPMAP(0x07, 0x05),   /* 0x1c: MBOX_ABORT_QUEUE */
6927         ISPOPMAP(0x07, 0x03),   /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6928         ISPOPMAP(0x00, 0x00),   /* 0x1e: */
6929         ISPOPMAP(0x01, 0x07),   /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6930         ISPOPMAP(0x01, 0x4f),   /* 0x20: MBOX_GET_LOOP_ID */
6931         ISPOPMAP(0x00, 0x00),   /* 0x21: */
6932         ISPOPMAP(0x01, 0x07),   /* 0x22: MBOX_GET_RETRY_COUNT   */
6933         ISPOPMAP(0x00, 0x00),   /* 0x23: */
6934         ISPOPMAP(0x00, 0x00),   /* 0x24: */
6935         ISPOPMAP(0x00, 0x00),   /* 0x25: */
6936         ISPOPMAP(0x00, 0x00),   /* 0x26: */
6937         ISPOPMAP(0x00, 0x00),   /* 0x27: */
6938         ISPOPMAP(0x01, 0x03),   /* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
6939         ISPOPMAP(0x03, 0x07),   /* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
6940         ISPOPMAP(0x00, 0x00),   /* 0x2a: */
6941         ISPOPMAP(0x00, 0x00),   /* 0x2b: */
6942         ISPOPMAP(0x00, 0x00),   /* 0x2c: */
6943         ISPOPMAP(0x00, 0x00),   /* 0x2d: */
6944         ISPOPMAP(0x00, 0x00),   /* 0x2e: */
6945         ISPOPMAP(0x00, 0x00),   /* 0x2f: */
6946         ISPOPMAP(0x00, 0x00),   /* 0x30: */
6947         ISPOPMAP(0x00, 0x00),   /* 0x31: */
6948         ISPOPMAP(0x07, 0x07),   /* 0x32: MBOX_SET_RETRY_COUNT   */
6949         ISPOPMAP(0x00, 0x00),   /* 0x33: */
6950         ISPOPMAP(0x00, 0x00),   /* 0x34: */
6951         ISPOPMAP(0x00, 0x00),   /* 0x35: */
6952         ISPOPMAP(0x00, 0x00),   /* 0x36: */
6953         ISPOPMAP(0x00, 0x00),   /* 0x37: */
6954         ISPOPMAP(0x0f, 0x01),   /* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
6955         ISPOPMAP(0x0f, 0x07),   /* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
6956         ISPOPMAP(0x00, 0x00),   /* 0x3a: */
6957         ISPOPMAP(0x00, 0x00),   /* 0x3b: */
6958         ISPOPMAP(0x00, 0x00),   /* 0x3c: */
6959         ISPOPMAP(0x00, 0x00),   /* 0x3d: */
6960         ISPOPMAP(0x00, 0x00),   /* 0x3e: */
6961         ISPOPMAP(0x00, 0x00),   /* 0x3f: */
6962         ISPOPMAP(0x03, 0x01),   /* 0x40: MBOX_LOOP_PORT_BYPASS */
6963         ISPOPMAP(0x03, 0x01),   /* 0x41: MBOX_LOOP_PORT_ENABLE */
6964         ISPOPMAP(0x03, 0x07),   /* 0x42: MBOX_GET_RESOURCE_COUNT */
6965         ISPOPMAP(0x01, 0x01),   /* 0x43: MBOX_REQUEST_OFFLINE_MODE */
6966         ISPOPMAP(0x00, 0x00),   /* 0x44: */
6967         ISPOPMAP(0x00, 0x00),   /* 0x45: */
6968         ISPOPMAP(0x00, 0x00),   /* 0x46: */
6969         ISPOPMAP(0xcf, 0x03),   /* 0x47: GET PORT_DATABASE ENHANCED */
6970         ISPOPMAP(0xcd, 0x01),   /* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */
6971         ISPOPMAP(0xcd, 0x01),   /* 0x49: MBOX_GET_VP_DATABASE */
6972         ISPOPMAP(0x2cd, 0x01),  /* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */
6973         ISPOPMAP(0x00, 0x00),   /* 0x4b: */
6974         ISPOPMAP(0x00, 0x00),   /* 0x4c: */
6975         ISPOPMAP(0x00, 0x00),   /* 0x4d: */
6976         ISPOPMAP(0x00, 0x00),   /* 0x4e: */
6977         ISPOPMAP(0x00, 0x00),   /* 0x4f: */
6978         ISPOPMAP(0x00, 0x00),   /* 0x50: */
6979         ISPOPMAP(0x00, 0x00),   /* 0x51: */
6980         ISPOPMAP(0x00, 0x00),   /* 0x52: */
6981         ISPOPMAP(0x00, 0x00),   /* 0x53: */
6982         ISPOPMAP(0xcf, 0x01),   /* 0x54: EXECUTE IOCB A64 */
6983         ISPOPMAP(0x00, 0x00),   /* 0x55: */
6984         ISPOPMAP(0x00, 0x00),   /* 0x56: */
6985         ISPOPMAP(0x00, 0x00),   /* 0x57: */
6986         ISPOPMAP(0x00, 0x00),   /* 0x58: */
6987         ISPOPMAP(0x00, 0x00),   /* 0x59: */
6988         ISPOPMAP(0x00, 0x00),   /* 0x5a: */
6989         ISPOPMAP(0x03, 0x01),   /* 0x5b: MBOX_DRIVER_HEARTBEAT */
6990         ISPOPMAP(0xcf, 0x01),   /* 0x5c: MBOX_FW_HEARTBEAT */
6991         ISPOPMAP(0x07, 0x03),   /* 0x5d: MBOX_GET_SET_DATA_RATE */
6992         ISPOPMAP(0x00, 0x00),   /* 0x5e: */
6993         ISPOPMAP(0x00, 0x00),   /* 0x5f: */
6994         ISPOPMAP(0xcd, 0x01),   /* 0x60: MBOX_INIT_FIRMWARE */
6995         ISPOPMAP(0x00, 0x00),   /* 0x61: */
6996         ISPOPMAP(0x01, 0x01),   /* 0x62: MBOX_INIT_LIP */
6997         ISPOPMAP(0xcd, 0x03),   /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
6998         ISPOPMAP(0xcf, 0x01),   /* 0x64: MBOX_GET_PORT_DB */
6999         ISPOPMAP(0x07, 0x01),   /* 0x65: MBOX_CLEAR_ACA */
7000         ISPOPMAP(0x07, 0x01),   /* 0x66: MBOX_TARGET_RESET */
7001         ISPOPMAP(0x07, 0x01),   /* 0x67: MBOX_CLEAR_TASK_SET */
7002         ISPOPMAP(0x07, 0x01),   /* 0x68: MBOX_ABORT_TASK_SET */
7003         ISPOPMAP(0x01, 0x07),   /* 0x69: MBOX_GET_FW_STATE */
7004         ISPOPMAP(0x03, 0xcf),   /* 0x6a: MBOX_GET_PORT_NAME */
7005         ISPOPMAP(0xcf, 0x01),   /* 0x6b: MBOX_GET_LINK_STATUS */
7006         ISPOPMAP(0x0f, 0x01),   /* 0x6c: MBOX_INIT_LIP_RESET */
7007         ISPOPMAP(0x00, 0x00),   /* 0x6d: */
7008         ISPOPMAP(0xcf, 0x03),   /* 0x6e: MBOX_SEND_SNS */
7009         ISPOPMAP(0x0f, 0x07),   /* 0x6f: MBOX_FABRIC_LOGIN */
7010         ISPOPMAP(0x03, 0x01),   /* 0x70: MBOX_SEND_CHANGE_REQUEST */
7011         ISPOPMAP(0x03, 0x03),   /* 0x71: MBOX_FABRIC_LOGOUT */
7012         ISPOPMAP(0x0f, 0x0f),   /* 0x72: MBOX_INIT_LIP_LOGIN */
7013         ISPOPMAP(0x00, 0x00),   /* 0x73: */
7014         ISPOPMAP(0x07, 0x01),   /* 0x74: LOGIN LOOP PORT */
7015         ISPOPMAP(0xcf, 0x03),   /* 0x75: GET PORT/NODE NAME LIST */
7016         ISPOPMAP(0x4f, 0x01),   /* 0x76: SET VENDOR ID */
7017         ISPOPMAP(0xcd, 0x01),   /* 0x77: INITIALIZE IP MAILBOX */
7018         ISPOPMAP(0x00, 0x00),   /* 0x78: */
7019         ISPOPMAP(0x00, 0x00),   /* 0x79: */
7020         ISPOPMAP(0x00, 0x00),   /* 0x7a: */
7021         ISPOPMAP(0x00, 0x00),   /* 0x7b: */
7022         ISPOPMAP(0x4f, 0x03),   /* 0x7c: Get ID List */
7023         ISPOPMAP(0xcf, 0x01),   /* 0x7d: SEND LFA */
7024         ISPOPMAP(0x0f, 0x01)    /* 0x7e: LUN RESET */
7025 };
7026 /*
7027  * Footnotes
7028  *
7029  * (1): this sets bits 21..16 in mailbox register #8, which we nominally
7030  *      do not access at this time in the core driver. The caller is
7031  *      responsible for setting this register first (Gross!). The assumption
7032  *      is that we won't overflow.
7033  */
7034
7035 static const char *fc_mbcmd_names[] = {
7036         "NO-OP",
7037         "LOAD RAM",
7038         "EXEC FIRMWARE",
7039         "DUMP RAM",
7040         "WRITE RAM WORD",
7041         "READ RAM WORD",
7042         "MAILBOX REG TEST",
7043         "VERIFY CHECKSUM",
7044         "ABOUT FIRMWARE",
7045         "LOAD RAM",
7046         "DUMP RAM",
7047         "WRITE RAM WORD EXTENDED",
7048         NULL,
7049         "READ RAM WORD EXTENDED",
7050         "CHECK FIRMWARE",
7051         NULL,
7052         "INIT REQUEST QUEUE",
7053         "INIT RESULT QUEUE",
7054         "EXECUTE IOCB",
7055         "WAKE UP",
7056         "STOP FIRMWARE",
7057         "ABORT",
7058         "ABORT DEVICE",
7059         "ABORT TARGET",
7060         "BUS RESET",
7061         "STOP QUEUE",
7062         "START QUEUE",
7063         "SINGLE STEP QUEUE",
7064         "ABORT QUEUE",
7065         "GET DEV QUEUE STATUS",
7066         NULL,
7067         "GET FIRMWARE STATUS",
7068         "GET LOOP ID",
7069         NULL,
7070         "GET RETRY COUNT",
7071         NULL,
7072         NULL,
7073         NULL,
7074         NULL,
7075         NULL,
7076         "GET FIRMWARE OPTIONS",
7077         "GET PORT QUEUE PARAMS",
7078         NULL,
7079         NULL,
7080         NULL,
7081         NULL,
7082         NULL,
7083         NULL,
7084         NULL,
7085         NULL,
7086         "SET RETRY COUNT",
7087         NULL,
7088         NULL,
7089         NULL,
7090         NULL,
7091         NULL,
7092         "SET FIRMWARE OPTIONS",
7093         "SET PORT QUEUE PARAMS",
7094         NULL,
7095         NULL,
7096         NULL,
7097         NULL,
7098         NULL,
7099         NULL,
7100         "LOOP PORT BYPASS",
7101         "LOOP PORT ENABLE",
7102         "GET RESOURCE COUNT",
7103         "REQUEST NON PARTICIPATING MODE",
7104         NULL,
7105         NULL,
7106         NULL,
7107         "GET PORT DATABASE ENHANCED",
7108         "INIT FIRMWARE MULTI ID",
7109         "GET VP DATABASE",
7110         "GET VP DATABASE ENTRY",
7111         NULL,
7112         NULL,
7113         NULL,
7114         NULL,
7115         NULL,
7116         NULL,
7117         NULL,
7118         NULL,
7119         NULL,
7120         "EXECUTE IOCB A64",
7121         NULL,
7122         NULL,
7123         NULL,
7124         NULL,
7125         NULL,
7126         NULL,
7127         "DRIVER HEARTBEAT",
7128         NULL,
7129         "GET/SET DATA RATE",
7130         NULL,
7131         NULL,
7132         "INIT FIRMWARE",
7133         NULL,
7134         "INIT LIP",
7135         "GET FC-AL POSITION MAP",
7136         "GET PORT DATABASE",
7137         "CLEAR ACA",
7138         "TARGET RESET",
7139         "CLEAR TASK SET",
7140         "ABORT TASK SET",
7141         "GET FW STATE",
7142         "GET PORT NAME",
7143         "GET LINK STATUS",
7144         "INIT LIP RESET",
7145         NULL,
7146         "SEND SNS",
7147         "FABRIC LOGIN",
7148         "SEND CHANGE REQUEST",
7149         "FABRIC LOGOUT",
7150         "INIT LIP LOGIN",
7151         NULL,
7152         "LOGIN LOOP PORT",
7153         "GET PORT/NODE NAME LIST",
7154         "SET VENDOR ID",
7155         "INITIALIZE IP MAILBOX",
7156         NULL,
7157         NULL,
7158         NULL,
7159         NULL,
7160         "Get ID List",
7161         "SEND LFA",
7162         "Lun RESET"
7163 };
7164
7165 static void
7166 isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay)
7167 {
7168         unsigned int ibits, obits, box, opcode;
7169         const uint32_t *mcp;
7170
7171         if (IS_FC(isp)) {
7172                 mcp = mbpfc;
7173         } else {
7174                 mcp = mbpscsi;
7175         }
7176         opcode = mbp->param[0];
7177         ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7178         obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7179         ibits |= mbp->ibits;
7180         obits |= mbp->obits;
7181         for (box = 0; box < MAX_MAILBOX(isp); box++) {
7182                 if (ibits & (1 << box)) {
7183                         ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
7184                 }
7185                 if (nodelay == 0) {
7186                         isp->isp_mboxtmp[box] = mbp->param[box] = 0;
7187                 }
7188         }
7189         if (nodelay == 0) {
7190                 isp->isp_lastmbxcmd = opcode;
7191                 isp->isp_obits = obits;
7192                 isp->isp_mboxbsy = 1;
7193         }
7194         if (IS_24XX(isp)) {
7195                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
7196         } else {
7197                 ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
7198         }
7199         /*
7200          * Oddly enough, if we're not delaying for an answer,
7201          * delay a bit to give the f/w a chance to pick up the
7202          * command.
7203          */
7204         if (nodelay) {
7205                 ISP_DELAY(1000);
7206         }
7207 }
7208
7209 static void
7210 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
7211 {
7212         const char *cname, *xname;
7213         char tname[16], mname[16];
7214         unsigned int lim, ibits, obits, box, opcode;
7215         const uint32_t *mcp;
7216
7217         if (IS_FC(isp)) {
7218                 mcp = mbpfc;
7219                 lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
7220         } else {
7221                 mcp = mbpscsi;
7222                 lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
7223         }
7224
7225         if ((opcode = mbp->param[0]) >= lim) {
7226                 mbp->param[0] = MBOX_INVALID_COMMAND;
7227                 isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
7228                 return;
7229         }
7230
7231         ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7232         obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7233
7234         /*
7235          * Pick up any additional bits that the caller might have set.
7236          */
7237         ibits |= mbp->ibits;
7238         obits |= mbp->obits;
7239
7240         if (ibits == 0 && obits == 0) {
7241                 mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
7242                 isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
7243                 return;
7244         }
7245
7246         /*
7247          * Get exclusive usage of mailbox registers.
7248          */
7249         if (MBOX_ACQUIRE(isp)) {
7250                 mbp->param[0] = MBOX_REGS_BUSY;
7251                 goto out;
7252         }
7253
7254         for (box = 0; box < MAX_MAILBOX(isp); box++) {
7255                 if (ibits & (1 << box)) {
7256                         isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box,
7257                             mbp->param[box]);
7258                         ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
7259                 }
7260                 isp->isp_mboxtmp[box] = mbp->param[box] = 0;
7261         }
7262
7263         isp->isp_lastmbxcmd = opcode;
7264
7265         /*
7266          * We assume that we can't overwrite a previous command.
7267          */
7268         isp->isp_obits = obits;
7269         isp->isp_mboxbsy = 1;
7270
7271         /*
7272          * Set Host Interrupt condition so that RISC will pick up mailbox regs.
7273          */
7274         if (IS_24XX(isp)) {
7275                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
7276         } else {
7277                 ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
7278         }
7279
7280         /*
7281          * While we haven't finished the command, spin our wheels here.
7282          */
7283         MBOX_WAIT_COMPLETE(isp, mbp);
7284
7285         /*
7286          * Did the command time out?
7287          */
7288         if (mbp->param[0] == MBOX_TIMEOUT) {
7289                 isp->isp_mboxbsy = 0;
7290                 MBOX_RELEASE(isp);
7291                 goto out;
7292         }
7293
7294         /*
7295          * Copy back output registers.
7296          */
7297         for (box = 0; box < MAX_MAILBOX(isp); box++) {
7298                 if (obits & (1 << box)) {
7299                         mbp->param[box] = isp->isp_mboxtmp[box];
7300                         isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box,
7301                             mbp->param[box]);
7302                 }
7303         }
7304
7305         isp->isp_mboxbsy = 0;
7306         MBOX_RELEASE(isp);
7307  out:
7308         if (mbp->logval == 0 || opcode == MBOX_EXEC_FIRMWARE) {
7309                 return;
7310         }
7311         cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
7312         if (cname == NULL) {
7313                 cname = tname;
7314                 ISP_SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
7315         }
7316
7317         /*
7318          * Just to be chatty here...
7319          */
7320         xname = NULL;
7321         switch (mbp->param[0]) {
7322         case MBOX_COMMAND_COMPLETE:
7323                 break;
7324         case MBOX_INVALID_COMMAND:
7325                 if (mbp->logval & MBLOGMASK(MBOX_COMMAND_COMPLETE)) {
7326                         xname = "INVALID COMMAND";
7327                 }
7328                 break;
7329         case MBOX_HOST_INTERFACE_ERROR:
7330                 if (mbp->logval & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR)) {
7331                         xname = "HOST INTERFACE ERROR";
7332                 }
7333                 break;
7334         case MBOX_TEST_FAILED:
7335                 if (mbp->logval & MBLOGMASK(MBOX_TEST_FAILED)) {
7336                         xname = "TEST FAILED";
7337                 }
7338                 break;
7339         case MBOX_COMMAND_ERROR:
7340                 if (mbp->logval & MBLOGMASK(MBOX_COMMAND_ERROR)) {
7341                         xname = "COMMAND ERROR";
7342                 }
7343                 break;
7344         case MBOX_COMMAND_PARAM_ERROR:
7345                 if (mbp->logval & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR)) {
7346                         xname = "COMMAND PARAMETER ERROR";
7347                 }
7348                 break;
7349         case MBOX_LOOP_ID_USED:
7350                 if (mbp->logval & MBLOGMASK(MBOX_LOOP_ID_USED)) {
7351                         xname = "LOOP ID ALREADY IN USE";
7352                 }
7353                 break;
7354         case MBOX_PORT_ID_USED:
7355                 if (mbp->logval & MBLOGMASK(MBOX_PORT_ID_USED)) {
7356                         xname = "PORT ID ALREADY IN USE";
7357                 }
7358                 break;
7359         case MBOX_ALL_IDS_USED:
7360                 if (mbp->logval & MBLOGMASK(MBOX_ALL_IDS_USED)) {
7361                         xname = "ALL LOOP IDS IN USE";
7362                 }
7363                 break;
7364         case MBOX_REGS_BUSY:
7365                 xname = "REGISTERS BUSY";
7366                 break;
7367         case MBOX_TIMEOUT:
7368                 xname = "TIMEOUT";
7369                 break;
7370         default:
7371                 ISP_SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
7372                 xname = mname;
7373                 break;
7374         }
7375         if (xname) {
7376                 isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
7377                     cname, xname);
7378         }
7379 }
7380
7381 static void
7382 isp_fw_state(ispsoftc_t *isp, int chan)
7383 {
7384         if (IS_FC(isp)) {
7385                 mbreg_t mbs;
7386                 fcparam *fcp = FCPARAM(isp, chan);
7387
7388                 MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0);
7389                 isp_mboxcmd(isp, &mbs);
7390                 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
7391                         fcp->isp_fwstate = mbs.param[1];
7392                 }
7393         }
7394 }
7395
7396 static void
7397 isp_spi_update(ispsoftc_t *isp, int chan)
7398 {
7399         int tgt;
7400         mbreg_t mbs;
7401         sdparam *sdp;
7402
7403         if (IS_FC(isp)) {
7404                 /*
7405                  * There are no 'per-bus' settings for Fibre Channel.
7406                  */
7407                 return;
7408         }
7409         sdp = SDPARAM(isp, chan);
7410         sdp->update = 0;
7411
7412         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7413                 uint16_t flags, period, offset;
7414                 int get;
7415
7416                 if (sdp->isp_devparam[tgt].dev_enable == 0) {
7417                         sdp->isp_devparam[tgt].dev_update = 0;
7418                         sdp->isp_devparam[tgt].dev_refresh = 0;
7419                         isp_prt(isp, ISP_LOGDEBUG0,
7420                             "skipping target %d bus %d update", tgt, chan);
7421                         continue;
7422                 }
7423                 /*
7424                  * If the goal is to update the status of the device,
7425                  * take what's in goal_flags and try and set the device
7426                  * toward that. Otherwise, if we're just refreshing the
7427                  * current device state, get the current parameters.
7428                  */
7429
7430                 MBSINIT(&mbs, 0, MBLOGALL, 0);
7431
7432                 /*
7433                  * Refresh overrides set
7434                  */
7435                 if (sdp->isp_devparam[tgt].dev_refresh) {
7436                         mbs.param[0] = MBOX_GET_TARGET_PARAMS;
7437                         get = 1;
7438                 } else if (sdp->isp_devparam[tgt].dev_update) {
7439                         mbs.param[0] = MBOX_SET_TARGET_PARAMS;
7440
7441                         /*
7442                          * Make sure goal_flags has "Renegotiate on Error"
7443                          * on and "Freeze Queue on Error" off.
7444                          */
7445                         sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
7446                         sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
7447                         mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
7448
7449                         /*
7450                          * Insist that PARITY must be enabled
7451                          * if SYNC or WIDE is enabled.
7452                          */
7453                         if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
7454                                 mbs.param[2] |= DPARM_PARITY;
7455                         }
7456
7457                         if (mbs.param[2] & DPARM_SYNC) {
7458                                 mbs.param[3] =
7459                                     (sdp->isp_devparam[tgt].goal_offset << 8) |
7460                                     (sdp->isp_devparam[tgt].goal_period);
7461                         }
7462                         /*
7463                          * A command completion later that has
7464                          * RQSTF_NEGOTIATION set can cause
7465                          * the dev_refresh/announce cycle also.
7466                          *
7467                          * Note: It is really important to update our current
7468                          * flags with at least the state of TAG capabilities-
7469                          * otherwise we might try and send a tagged command
7470                          * when we have it all turned off. So change it here
7471                          * to say that current already matches goal.
7472                          */
7473                         sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
7474                         sdp->isp_devparam[tgt].actv_flags |=
7475                             (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
7476                         isp_prt(isp, ISP_LOGDEBUG0,
7477                             "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
7478                             chan, tgt, mbs.param[2], mbs.param[3] >> 8,
7479                             mbs.param[3] & 0xff);
7480                         get = 0;
7481                 } else {
7482                         continue;
7483                 }
7484                 mbs.param[1] = (chan << 15) | (tgt << 8);
7485                 isp_mboxcmd(isp, &mbs);
7486                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7487                         continue;
7488                 }
7489                 if (get == 0) {
7490                         sdp->sendmarker = 1;
7491                         sdp->isp_devparam[tgt].dev_update = 0;
7492                         sdp->isp_devparam[tgt].dev_refresh = 1;
7493                 } else {
7494                         sdp->isp_devparam[tgt].dev_refresh = 0;
7495                         flags = mbs.param[2];
7496                         period = mbs.param[3] & 0xff;
7497                         offset = mbs.param[3] >> 8;
7498                         sdp->isp_devparam[tgt].actv_flags = flags;
7499                         sdp->isp_devparam[tgt].actv_period = period;
7500                         sdp->isp_devparam[tgt].actv_offset = offset;
7501                         isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, chan, tgt);
7502                 }
7503         }
7504
7505         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7506                 if (sdp->isp_devparam[tgt].dev_update ||
7507                     sdp->isp_devparam[tgt].dev_refresh) {
7508                         sdp->update = 1;
7509                         break;
7510                 }
7511         }
7512 }
7513
7514 static void
7515 isp_setdfltsdparm(ispsoftc_t *isp)
7516 {
7517         int tgt;
7518         sdparam *sdp, *sdp1;
7519
7520         sdp = SDPARAM(isp, 0);
7521         sdp->role = GET_DEFAULT_ROLE(isp, 0);
7522         if (IS_DUALBUS(isp)) {
7523                 sdp1 = sdp + 1;
7524                 sdp1->role = GET_DEFAULT_ROLE(isp, 1);
7525         } else {
7526                 sdp1 = NULL;
7527         }
7528
7529         /*
7530          * Establish some default parameters.
7531          */
7532         sdp->isp_cmd_dma_burst_enable = 0;
7533         sdp->isp_data_dma_burst_enabl = 1;
7534         sdp->isp_fifo_threshold = 0;
7535         sdp->isp_initiator_id = DEFAULT_IID(isp, 0);
7536         if (isp->isp_type >= ISP_HA_SCSI_1040) {
7537                 sdp->isp_async_data_setup = 9;
7538         } else {
7539                 sdp->isp_async_data_setup = 6;
7540         }
7541         sdp->isp_selection_timeout = 250;
7542         sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
7543         sdp->isp_tag_aging = 8;
7544         sdp->isp_bus_reset_delay = 5;
7545         /*
7546          * Don't retry selection, busy or queue full automatically- reflect
7547          * these back to us.
7548          */
7549         sdp->isp_retry_count = 0;
7550         sdp->isp_retry_delay = 0;
7551
7552         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7553                 sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
7554                 sdp->isp_devparam[tgt].dev_enable = 1;
7555         }
7556
7557         /*
7558          * The trick here is to establish a default for the default (honk!)
7559          * state (goal_flags). Then try and get the current status from
7560          * the card to fill in the current state. We don't, in fact, set
7561          * the default to the SAFE default state- that's not the goal state.
7562          */
7563         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7564                 uint8_t off, per;
7565                 sdp->isp_devparam[tgt].actv_offset = 0;
7566                 sdp->isp_devparam[tgt].actv_period = 0;
7567                 sdp->isp_devparam[tgt].actv_flags = 0;
7568
7569                 sdp->isp_devparam[tgt].goal_flags =
7570                     sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
7571
7572                 /*
7573                  * We default to Wide/Fast for versions less than a 1040
7574                  * (unless it's SBus).
7575                  */
7576                 if (IS_ULTRA3(isp)) {
7577                         off = ISP_80M_SYNCPARMS >> 8;
7578                         per = ISP_80M_SYNCPARMS & 0xff;
7579                 } else if (IS_ULTRA2(isp)) {
7580                         off = ISP_40M_SYNCPARMS >> 8;
7581                         per = ISP_40M_SYNCPARMS & 0xff;
7582                 } else if (IS_1240(isp)) {
7583                         off = ISP_20M_SYNCPARMS >> 8;
7584                         per = ISP_20M_SYNCPARMS & 0xff;
7585                 } else if ((isp->isp_bustype == ISP_BT_SBUS &&
7586                     isp->isp_type < ISP_HA_SCSI_1020A) ||
7587                     (isp->isp_bustype == ISP_BT_PCI &&
7588                     isp->isp_type < ISP_HA_SCSI_1040) ||
7589                     (isp->isp_clock && isp->isp_clock < 60) ||
7590                     (sdp->isp_ultramode == 0)) {
7591                         off = ISP_10M_SYNCPARMS >> 8;
7592                         per = ISP_10M_SYNCPARMS & 0xff;
7593                 } else {
7594                         off = ISP_20M_SYNCPARMS_1040 >> 8;
7595                         per = ISP_20M_SYNCPARMS_1040 & 0xff;
7596                 }
7597                 sdp->isp_devparam[tgt].goal_offset =
7598                     sdp->isp_devparam[tgt].nvrm_offset = off;
7599                 sdp->isp_devparam[tgt].goal_period =
7600                     sdp->isp_devparam[tgt].nvrm_period = per;
7601
7602         }
7603
7604         /*
7605          * If we're a dual bus card, just copy the data over
7606          */
7607         if (sdp1) {
7608                 *sdp1 = *sdp;
7609                 sdp1->isp_initiator_id = DEFAULT_IID(isp, 1);
7610         }
7611
7612         /*
7613          * If we've not been told to avoid reading NVRAM, try and read it.
7614          * If we're successful reading it, we can then return because NVRAM
7615          * will tell us what the desired settings are. Otherwise, we establish
7616          * some reasonable 'fake' nvram and goal defaults.
7617          */
7618         if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7619                 mbreg_t mbs;
7620
7621                 if (isp_read_nvram(isp, 0) == 0) {
7622                         if (IS_DUALBUS(isp)) {
7623                                 if (isp_read_nvram(isp, 1) == 0) {
7624                                         return;
7625                                 }
7626                         }
7627                 }
7628                 MBSINIT(&mbs, MBOX_GET_ACT_NEG_STATE, MBLOGNONE, 0);
7629                 isp_mboxcmd(isp, &mbs);
7630                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7631                         sdp->isp_req_ack_active_neg = 1;
7632                         sdp->isp_data_line_active_neg = 1;
7633                         if (sdp1) {
7634                                 sdp1->isp_req_ack_active_neg = 1;
7635                                 sdp1->isp_data_line_active_neg = 1;
7636                         }
7637                 } else {
7638                         sdp->isp_req_ack_active_neg =
7639                             (mbs.param[1] >> 4) & 0x1;
7640                         sdp->isp_data_line_active_neg =
7641                             (mbs.param[1] >> 5) & 0x1;
7642                         if (sdp1) {
7643                                 sdp1->isp_req_ack_active_neg =
7644                                     (mbs.param[2] >> 4) & 0x1;
7645                                 sdp1->isp_data_line_active_neg =
7646                                     (mbs.param[2] >> 5) & 0x1;
7647                         }
7648                 }
7649         }
7650
7651 }
7652
7653 static void
7654 isp_setdfltfcparm(ispsoftc_t *isp, int chan)
7655 {
7656         fcparam *fcp = FCPARAM(isp, chan);
7657
7658         /*
7659          * Establish some default parameters.
7660          */
7661         fcp->role = GET_DEFAULT_ROLE(isp, chan);
7662         fcp->isp_maxalloc = ICB_DFLT_ALLOC;
7663         fcp->isp_retry_delay = ICB_DFLT_RDELAY;
7664         fcp->isp_retry_count = ICB_DFLT_RCOUNT;
7665         fcp->isp_loopid = DEFAULT_LOOPID(isp, chan);
7666         fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
7667         fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
7668         fcp->isp_fwoptions = 0;
7669         fcp->isp_lasthdl = NIL_HANDLE;
7670
7671         if (IS_24XX(isp)) {
7672                 fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS;
7673                 fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS;
7674                 if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
7675                         fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
7676                 }
7677                 fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
7678         } else {
7679                 fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
7680                 fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
7681                 fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
7682                 fcp->isp_fwoptions |= ICBOPT_FAST_POST;
7683                 if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
7684                         fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
7685                 }
7686                 /*
7687                  * Make sure this is turned off now until we get
7688                  * extended options from NVRAM
7689                  */
7690                 fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
7691         }
7692
7693
7694         /*
7695          * Now try and read NVRAM unless told to not do so.
7696          * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
7697          */
7698         if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7699                 int i, j = 0;
7700                 /*
7701                  * Give a couple of tries at reading NVRAM.
7702                  */
7703                 for (i = 0; i < 2; i++) {
7704                         j = isp_read_nvram(isp, chan);
7705                         if (j == 0) {
7706                                 break;
7707                         }
7708                 }
7709                 if (j) {
7710                         isp->isp_confopts |= ISP_CFG_NONVRAM;
7711                 }
7712         }
7713
7714         fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan);
7715         fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan);
7716         isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s",
7717             chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn),
7718             (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn),
7719             isp_class3_roles[fcp->role]);
7720 }
7721
7722 /*
7723  * Re-initialize the ISP and complete all orphaned commands
7724  * with a 'botched' notice. The reset/init routines should
7725  * not disturb an already active list of commands.
7726  */
7727
7728 void
7729 isp_reinit(ispsoftc_t *isp, int do_load_defaults)
7730 {
7731         int i;
7732
7733         isp_reset(isp, do_load_defaults);
7734
7735         if (isp->isp_state != ISP_RESETSTATE) {
7736                 isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
7737                 ISP_DISABLE_INTS(isp);
7738                 goto cleanup;
7739         }
7740
7741         isp_init(isp);
7742
7743         if (isp->isp_state == ISP_INITSTATE) {
7744                 isp->isp_state = ISP_RUNSTATE;
7745         }
7746
7747         if (isp->isp_state != ISP_RUNSTATE) {
7748 #ifndef ISP_TARGET_MODE
7749                 isp_prt(isp, ISP_LOGWARN, "%s: not at runstate", __func__);
7750 #endif
7751                 ISP_DISABLE_INTS(isp);
7752                 if (IS_FC(isp)) {
7753                         /*
7754                          * If we're in ISP_ROLE_NONE, turn off the lasers.
7755                          */
7756                         if (!IS_24XX(isp)) {
7757                                 ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
7758                                 ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
7759                                 ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
7760                                 ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
7761                                 ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
7762                         }
7763                 }
7764         }
7765
7766  cleanup:
7767
7768         isp->isp_nactive = 0;
7769
7770         isp_clear_commands(isp);
7771         if (IS_FC(isp)) {
7772                 for (i = 0; i < isp->isp_nchan; i++) {
7773                         ISP_MARK_PORTDB(isp, i, -1);
7774                 }
7775         }
7776 }
7777
7778 /*
7779  * NVRAM Routines
7780  */
7781 static int
7782 isp_read_nvram(ispsoftc_t *isp, int bus)
7783 {
7784         int i, amt, retval;
7785         uint8_t csum, minversion;
7786         union {
7787                 uint8_t _x[ISP2400_NVRAM_SIZE];
7788                 uint16_t _s[ISP2400_NVRAM_SIZE>>1];
7789         } _n;
7790 #define nvram_data      _n._x
7791 #define nvram_words     _n._s
7792
7793         if (IS_24XX(isp)) {
7794                 return (isp_read_nvram_2400(isp, nvram_data));
7795         } else if (IS_FC(isp)) {
7796                 amt = ISP2100_NVRAM_SIZE;
7797                 minversion = 1;
7798         } else if (IS_ULTRA2(isp)) {
7799                 amt = ISP1080_NVRAM_SIZE;
7800                 minversion = 0;
7801         } else {
7802                 amt = ISP_NVRAM_SIZE;
7803                 minversion = 2;
7804         }
7805
7806         for (i = 0; i < amt>>1; i++) {
7807                 isp_rdnvram_word(isp, i, &nvram_words[i]);
7808         }
7809
7810         if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7811             nvram_data[2] != 'P') {
7812                 if (isp->isp_bustype != ISP_BT_SBUS) {
7813                         isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
7814                         isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
7815                             nvram_data[0], nvram_data[1], nvram_data[2]);
7816                 }
7817                 retval = -1;
7818                 goto out;
7819         }
7820
7821         for (csum = 0, i = 0; i < amt; i++) {
7822                 csum += nvram_data[i];
7823         }
7824         if (csum != 0) {
7825                 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7826                 retval = -1;
7827                 goto out;
7828         }
7829
7830         if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
7831                 isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
7832                     ISP_NVRAM_VERSION(nvram_data));
7833                 retval = -1;
7834                 goto out;
7835         }
7836
7837         if (IS_ULTRA3(isp)) {
7838                 isp_parse_nvram_12160(isp, bus, nvram_data);
7839         } else if (IS_1080(isp)) {
7840                 isp_parse_nvram_1080(isp, bus, nvram_data);
7841         } else if (IS_1280(isp) || IS_1240(isp)) {
7842                 isp_parse_nvram_1080(isp, bus, nvram_data);
7843         } else if (IS_SCSI(isp)) {
7844                 isp_parse_nvram_1020(isp, nvram_data);
7845         } else {
7846                 isp_parse_nvram_2100(isp, nvram_data);
7847         }
7848         retval = 0;
7849 out:
7850         return (retval);
7851 #undef  nvram_data
7852 #undef  nvram_words
7853 }
7854
7855 static int
7856 isp_read_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
7857 {
7858         int retval = 0;
7859         uint32_t addr, csum, lwrds, *dptr;
7860
7861         if (isp->isp_port) {
7862                 addr = ISP2400_NVRAM_PORT1_ADDR;
7863         } else {
7864                 addr = ISP2400_NVRAM_PORT0_ADDR;
7865         }
7866
7867         dptr = (uint32_t *) nvram_data;
7868         for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7869                 isp_rd_2400_nvram(isp, addr++, dptr++);
7870         }
7871         if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7872             nvram_data[2] != 'P') {
7873                 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
7874                     nvram_data[0], nvram_data[1], nvram_data[2]);
7875                 retval = -1;
7876                 goto out;
7877         }
7878         dptr = (uint32_t *) nvram_data;
7879         for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7880                 uint32_t tmp;
7881                 ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
7882                 csum += tmp;
7883         }
7884         if (csum != 0) {
7885                 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7886                 retval = -1;
7887                 goto out;
7888         }
7889         isp_parse_nvram_2400(isp, nvram_data);
7890 out:
7891         return (retval);
7892 }
7893
7894 static void
7895 isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
7896 {
7897         int i, cbits;
7898         uint16_t bit, rqst, junk;
7899
7900         ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7901         ISP_DELAY(10);
7902         ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7903         ISP_DELAY(10);
7904
7905         if (IS_FC(isp)) {
7906                 wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
7907                 if (IS_2312(isp) && isp->isp_port) {
7908                         wo += 128;
7909                 }
7910                 rqst = (ISP_NVRAM_READ << 8) | wo;
7911                 cbits = 10;
7912         } else if (IS_ULTRA2(isp)) {
7913                 wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
7914                 rqst = (ISP_NVRAM_READ << 8) | wo;
7915                 cbits = 10;
7916         } else {
7917                 wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
7918                 rqst = (ISP_NVRAM_READ << 6) | wo;
7919                 cbits = 8;
7920         }
7921
7922         /*
7923          * Clock the word select request out...
7924          */
7925         for (i = cbits; i >= 0; i--) {
7926                 if ((rqst >> i) & 1) {
7927                         bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
7928                 } else {
7929                         bit = BIU_NVRAM_SELECT;
7930                 }
7931                 ISP_WRITE(isp, BIU_NVRAM, bit);
7932                 ISP_DELAY(10);
7933                 junk = ISP_READ(isp, BIU_NVRAM);        /* force PCI flush */
7934                 ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
7935                 ISP_DELAY(10);
7936                 junk = ISP_READ(isp, BIU_NVRAM);        /* force PCI flush */
7937                 ISP_WRITE(isp, BIU_NVRAM, bit);
7938                 ISP_DELAY(10);
7939                 junk = ISP_READ(isp, BIU_NVRAM);        /* force PCI flush */
7940         }
7941         /*
7942          * Now read the result back in (bits come back in MSB format).
7943          */
7944         *rp = 0;
7945         for (i = 0; i < 16; i++) {
7946                 uint16_t rv;
7947                 *rp <<= 1;
7948                 ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7949                 ISP_DELAY(10);
7950                 rv = ISP_READ(isp, BIU_NVRAM);
7951                 if (rv & BIU_NVRAM_DATAIN) {
7952                         *rp |= 1;
7953                 }
7954                 ISP_DELAY(10);
7955                 ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7956                 ISP_DELAY(10);
7957                 junk = ISP_READ(isp, BIU_NVRAM);        /* force PCI flush */
7958         }
7959         ISP_WRITE(isp, BIU_NVRAM, 0);
7960         ISP_DELAY(10);
7961         junk = ISP_READ(isp, BIU_NVRAM);        /* force PCI flush */
7962         ISP_SWIZZLE_NVRAM_WORD(isp, rp);
7963 }
7964
7965 static void
7966 isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
7967 {
7968         int loops = 0;
7969         uint32_t base = 0x7ffe0000;
7970         uint32_t tmp = 0;
7971
7972         if (IS_25XX(isp)) {
7973                 base = 0x7ff00000 | 0x48000;
7974         }
7975         ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
7976         for (loops = 0; loops < 5000; loops++) {
7977                 ISP_DELAY(10);
7978                 tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
7979                 if ((tmp & (1U << 31)) != 0) {
7980                         break;
7981                 }
7982         }
7983         if (tmp & (1U << 31)) {
7984                 *rp = ISP_READ(isp, BIU2400_FLASH_DATA);
7985                 ISP_SWIZZLE_NVRAM_LONG(isp, rp);
7986         } else {
7987                 *rp = 0xffffffff;
7988         }
7989 }
7990
7991 static void
7992 isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
7993 {
7994         sdparam *sdp = SDPARAM(isp, 0);
7995         int tgt;
7996
7997         sdp->isp_fifo_threshold =
7998                 ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
7999                 (ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
8000
8001         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
8002                 sdp->isp_initiator_id =
8003                         ISP_NVRAM_INITIATOR_ID(nvram_data);
8004
8005         sdp->isp_bus_reset_delay =
8006                 ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
8007
8008         sdp->isp_retry_count =
8009                 ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
8010
8011         sdp->isp_retry_delay =
8012                 ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
8013
8014         sdp->isp_async_data_setup =
8015                 ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
8016
8017         if (isp->isp_type >= ISP_HA_SCSI_1040) {
8018                 if (sdp->isp_async_data_setup < 9) {
8019                         sdp->isp_async_data_setup = 9;
8020                 }
8021         } else {
8022                 if (sdp->isp_async_data_setup != 6) {
8023                         sdp->isp_async_data_setup = 6;
8024                 }
8025         }
8026
8027         sdp->isp_req_ack_active_neg =
8028                 ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
8029
8030         sdp->isp_data_line_active_neg =
8031                 ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
8032
8033         sdp->isp_data_dma_burst_enabl =
8034                 ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
8035
8036         sdp->isp_cmd_dma_burst_enable =
8037                 ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
8038
8039         sdp->isp_tag_aging =
8040                 ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
8041
8042         sdp->isp_selection_timeout =
8043                 ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
8044
8045         sdp->isp_max_queue_depth =
8046                 ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
8047
8048         sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
8049
8050         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8051                 sdp->isp_devparam[tgt].dev_enable =
8052                         ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
8053                 sdp->isp_devparam[tgt].exc_throttle =
8054                         ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
8055                 sdp->isp_devparam[tgt].nvrm_offset =
8056                         ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
8057                 sdp->isp_devparam[tgt].nvrm_period =
8058                         ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
8059                 /*
8060                  * We probably shouldn't lie about this, but it
8061                  * it makes it much safer if we limit NVRAM values
8062                  * to sanity.
8063                  */
8064                 if (isp->isp_type < ISP_HA_SCSI_1040) {
8065                         /*
8066                          * If we're not ultra, we can't possibly
8067                          * be a shorter period than this.
8068                          */
8069                         if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
8070                                 sdp->isp_devparam[tgt].nvrm_period = 0x19;
8071                         }
8072                         if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
8073                                 sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
8074                         }
8075                 } else {
8076                         if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
8077                                 sdp->isp_devparam[tgt].nvrm_offset = 0x8;
8078                         }
8079                 }
8080                 sdp->isp_devparam[tgt].nvrm_flags = 0;
8081                 if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
8082                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8083                 sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8084                 if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
8085                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8086                 if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
8087                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8088                 if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
8089                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8090                 if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
8091                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8092                 if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
8093                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8094                 sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
8095                 sdp->isp_devparam[tgt].goal_offset =
8096                     sdp->isp_devparam[tgt].nvrm_offset;
8097                 sdp->isp_devparam[tgt].goal_period =
8098                     sdp->isp_devparam[tgt].nvrm_period;
8099                 sdp->isp_devparam[tgt].goal_flags =
8100                     sdp->isp_devparam[tgt].nvrm_flags;
8101         }
8102 }
8103
8104 static void
8105 isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
8106 {
8107         sdparam *sdp = SDPARAM(isp, bus);
8108         int tgt;
8109
8110         sdp->isp_fifo_threshold =
8111             ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
8112
8113         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
8114                 sdp->isp_initiator_id =
8115                     ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
8116
8117         sdp->isp_bus_reset_delay =
8118             ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
8119
8120         sdp->isp_retry_count =
8121             ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
8122
8123         sdp->isp_retry_delay =
8124             ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
8125
8126         sdp->isp_async_data_setup =
8127             ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
8128
8129         sdp->isp_req_ack_active_neg =
8130             ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
8131
8132         sdp->isp_data_line_active_neg =
8133             ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
8134
8135         sdp->isp_data_dma_burst_enabl =
8136             ISP1080_NVRAM_BURST_ENABLE(nvram_data);
8137
8138         sdp->isp_cmd_dma_burst_enable =
8139             ISP1080_NVRAM_BURST_ENABLE(nvram_data);
8140
8141         sdp->isp_selection_timeout =
8142             ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
8143
8144         sdp->isp_max_queue_depth =
8145              ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
8146
8147         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8148                 sdp->isp_devparam[tgt].dev_enable =
8149                     ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
8150                 sdp->isp_devparam[tgt].exc_throttle =
8151                         ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
8152                 sdp->isp_devparam[tgt].nvrm_offset =
8153                         ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
8154                 sdp->isp_devparam[tgt].nvrm_period =
8155                         ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
8156                 sdp->isp_devparam[tgt].nvrm_flags = 0;
8157                 if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
8158                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8159                 sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8160                 if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
8161                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8162                 if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
8163                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8164                 if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
8165                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8166                 if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
8167                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8168                 if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
8169                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8170                 sdp->isp_devparam[tgt].actv_flags = 0;
8171                 sdp->isp_devparam[tgt].goal_offset =
8172                     sdp->isp_devparam[tgt].nvrm_offset;
8173                 sdp->isp_devparam[tgt].goal_period =
8174                     sdp->isp_devparam[tgt].nvrm_period;
8175                 sdp->isp_devparam[tgt].goal_flags =
8176                     sdp->isp_devparam[tgt].nvrm_flags;
8177         }
8178 }
8179
8180 static void
8181 isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
8182 {
8183         sdparam *sdp = SDPARAM(isp, bus);
8184         int tgt;
8185
8186         sdp->isp_fifo_threshold =
8187             ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
8188
8189         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
8190                 sdp->isp_initiator_id =
8191                     ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
8192
8193         sdp->isp_bus_reset_delay =
8194             ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
8195
8196         sdp->isp_retry_count =
8197             ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
8198
8199         sdp->isp_retry_delay =
8200             ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
8201
8202         sdp->isp_async_data_setup =
8203             ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
8204
8205         sdp->isp_req_ack_active_neg =
8206             ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
8207
8208         sdp->isp_data_line_active_neg =
8209             ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
8210
8211         sdp->isp_data_dma_burst_enabl =
8212             ISP12160_NVRAM_BURST_ENABLE(nvram_data);
8213
8214         sdp->isp_cmd_dma_burst_enable =
8215             ISP12160_NVRAM_BURST_ENABLE(nvram_data);
8216
8217         sdp->isp_selection_timeout =
8218             ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
8219
8220         sdp->isp_max_queue_depth =
8221              ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
8222
8223         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8224                 sdp->isp_devparam[tgt].dev_enable =
8225                     ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
8226                 sdp->isp_devparam[tgt].exc_throttle =
8227                         ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
8228                 sdp->isp_devparam[tgt].nvrm_offset =
8229                         ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
8230                 sdp->isp_devparam[tgt].nvrm_period =
8231                         ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
8232                 sdp->isp_devparam[tgt].nvrm_flags = 0;
8233                 if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
8234                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8235                 sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8236                 if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
8237                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8238                 if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
8239                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8240                 if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
8241                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8242                 if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
8243                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8244                 if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
8245                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8246                 sdp->isp_devparam[tgt].actv_flags = 0;
8247                 sdp->isp_devparam[tgt].goal_offset =
8248                     sdp->isp_devparam[tgt].nvrm_offset;
8249                 sdp->isp_devparam[tgt].goal_period =
8250                     sdp->isp_devparam[tgt].nvrm_period;
8251                 sdp->isp_devparam[tgt].goal_flags =
8252                     sdp->isp_devparam[tgt].nvrm_flags;
8253         }
8254 }
8255
8256 static void
8257 isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
8258 {
8259         fcparam *fcp = FCPARAM(isp, 0);
8260         uint64_t wwn;
8261
8262         /*
8263          * There is NVRAM storage for both Port and Node entities-
8264          * but the Node entity appears to be unused on all the cards
8265          * I can find. However, we should account for this being set
8266          * at some point in the future.
8267          *
8268          * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
8269          * bits 48..60. In the case of the 2202, it appears that they do
8270          * use bit 48 to distinguish between the two instances on the card.
8271          * The 2204, which I've never seen, *probably* extends this method.
8272          */
8273         wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
8274         if (wwn) {
8275                 isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
8276                     (uint32_t) (wwn >> 32), (uint32_t) (wwn));
8277                 if ((wwn >> 60) == 0) {
8278                         wwn |= (((uint64_t) 2)<< 60);
8279                 }
8280         }
8281         fcp->isp_wwpn_nvram = wwn;
8282         if (IS_2200(isp) || IS_23XX(isp)) {
8283                 wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
8284                 if (wwn) {
8285                         isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
8286                             (uint32_t) (wwn >> 32),
8287                             (uint32_t) (wwn));
8288                         if ((wwn >> 60) == 0) {
8289                                 wwn |= (((uint64_t) 2)<< 60);
8290                         }
8291                 } else {
8292                         wwn = fcp->isp_wwpn_nvram & ~((uint64_t) 0xfff << 48);
8293                 }
8294         } else {
8295                 wwn &= ~((uint64_t) 0xfff << 48);
8296         }
8297         fcp->isp_wwnn_nvram = wwn;
8298
8299         fcp->isp_maxalloc = ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
8300         if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
8301                 DEFAULT_FRAMESIZE(isp) =
8302                     ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
8303         }
8304         fcp->isp_retry_delay = ISP2100_NVRAM_RETRY_DELAY(nvram_data);
8305         fcp->isp_retry_count = ISP2100_NVRAM_RETRY_COUNT(nvram_data);
8306         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
8307                 fcp->isp_loopid = ISP2100_NVRAM_HARDLOOPID(nvram_data);
8308         }
8309         if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
8310                 DEFAULT_EXEC_THROTTLE(isp) =
8311                         ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
8312         }
8313         fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
8314         isp_prt(isp, ISP_LOGDEBUG0,
8315             "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d",
8316             (uint32_t) (fcp->isp_wwnn_nvram >> 32),
8317             (uint32_t) fcp->isp_wwnn_nvram,
8318             (uint32_t) (fcp->isp_wwpn_nvram >> 32),
8319             (uint32_t) fcp->isp_wwpn_nvram,
8320             ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data),
8321             ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data));
8322         isp_prt(isp, ISP_LOGDEBUG0,
8323             "execthrottle %d fwoptions 0x%x hardloop %d tov %d",
8324             ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
8325             ISP2100_NVRAM_OPTIONS(nvram_data),
8326             ISP2100_NVRAM_HARDLOOPID(nvram_data),
8327             ISP2100_NVRAM_TOV(nvram_data));
8328         fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data);
8329         fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data);
8330         isp_prt(isp, ISP_LOGDEBUG0,
8331             "xfwoptions 0x%x zfw options 0x%x",
8332             ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data));
8333 }
8334
8335 static void
8336 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
8337 {
8338         fcparam *fcp = FCPARAM(isp, 0);
8339         uint64_t wwn;
8340
8341         isp_prt(isp, ISP_LOGDEBUG0,
8342             "NVRAM 0x%08x%08x 0x%08x%08x exchg_cnt %d maxframelen %d",
8343             (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
8344             (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
8345             (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
8346             (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
8347             ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data),
8348             ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
8349         isp_prt(isp, ISP_LOGDEBUG0,
8350             "NVRAM execthr %d loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
8351             ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data),
8352             ISP2400_NVRAM_HARDLOOPID(nvram_data),
8353             ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
8354             ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
8355             ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
8356
8357         wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
8358         fcp->isp_wwpn_nvram = wwn;
8359
8360         wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
8361         if (wwn) {
8362                 if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
8363                         wwn = 0;
8364                 }
8365         }
8366         if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
8367                 wwn = fcp->isp_wwpn_nvram;
8368                 wwn &= ~((uint64_t) 0xfff << 48);
8369         }
8370         fcp->isp_wwnn_nvram = wwn;
8371
8372         if (ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data)) {
8373                 fcp->isp_maxalloc = ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data);
8374         }
8375         if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
8376                 DEFAULT_FRAMESIZE(isp) =
8377                     ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
8378         }
8379         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
8380                 fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
8381         }
8382         if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
8383                 DEFAULT_EXEC_THROTTLE(isp) =
8384                         ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data);
8385         }
8386         fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
8387         fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
8388         fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
8389 }