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