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