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