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