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