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