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