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