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