isp(4): Fix a typo in a message.
[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, lev;
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         lev = ISP_LOGERR;
2168         msg = NULL;
2169
2170         switch (sst) {
2171         case PLOGX_IOCBERR_NOLINK:
2172                 msg = "no link";
2173                 break;
2174         case PLOGX_IOCBERR_NOIOCB:
2175                 msg = "no IOCB buffer";
2176                 break;
2177         case PLOGX_IOCBERR_NOXGHG:
2178                 msg = "no Exchange Control Block";
2179                 break;
2180         case PLOGX_IOCBERR_FAILED:
2181                 ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff);
2182                 msg = buf;
2183                 break;
2184         case PLOGX_IOCBERR_NOFABRIC:
2185                 msg = "no fabric";
2186                 break;
2187         case PLOGX_IOCBERR_NOTREADY:
2188                 msg = "firmware not ready";
2189                 break;
2190         case PLOGX_IOCBERR_NOLOGIN:
2191                 ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1);
2192                 msg = buf;
2193                 rval = MBOX_NOT_LOGGED_IN;
2194                 break;
2195         case PLOGX_IOCBERR_REJECT:
2196                 ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1);
2197                 msg = buf;
2198                 break;
2199         case PLOGX_IOCBERR_NOPCB:
2200                 msg = "no PCB allocated";
2201                 break;
2202         case PLOGX_IOCBERR_EINVAL:
2203                 ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1);
2204                 msg = buf;
2205                 break;
2206         case PLOGX_IOCBERR_PORTUSED:
2207                 lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
2208                 ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1);
2209                 msg = buf;
2210                 rval = MBOX_PORT_ID_USED | (parm1 << 16);
2211                 break;
2212         case PLOGX_IOCBERR_HNDLUSED:
2213                 lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
2214                 ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1);
2215                 msg = buf;
2216                 rval = MBOX_LOOP_ID_USED;
2217                 break;
2218         case PLOGX_IOCBERR_NOHANDLE:
2219                 msg = "no handle allocated";
2220                 break;
2221         case PLOGX_IOCBERR_NOFLOGI:
2222                 msg = "no FLOGI_ACC";
2223                 break;
2224         default:
2225                 ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", plp->plogx_status, flags);
2226                 msg = buf;
2227                 break;
2228         }
2229         if (msg) {
2230                 isp_prt(isp, ISP_LOGERR, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s", chan, portid, handle, msg);
2231         }
2232 out:
2233         if (gs == 0) {
2234                 FC_SCRATCH_RELEASE(isp, chan);
2235         }
2236         return (rval);
2237 }
2238
2239 static int
2240 isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
2241 {
2242         mbreg_t mbs;
2243
2244         MBSINIT(&mbs, MBOX_FABRIC_LOGIN, MBLOGNONE, 500000);
2245         if (ISP_CAP_2KLOGIN(isp)) {
2246                 mbs.param[1] = handle;
2247                 mbs.ibits = (1 << 10);
2248         } else {
2249                 mbs.param[1] = handle << 8;
2250         }
2251         mbs.param[2] = portid >> 16;
2252         mbs.param[3] = portid;
2253         mbs.logval = MBLOGNONE;
2254         mbs.timeout = 500000;
2255         isp_mboxcmd(isp, &mbs);
2256
2257         switch (mbs.param[0]) {
2258         case MBOX_PORT_ID_USED:
2259                 isp_prt(isp, ISP_LOGDEBUG0,
2260                     "isp_port_login: portid 0x%06x already logged in as %u",
2261                     portid, mbs.param[1]);
2262                 return (MBOX_PORT_ID_USED | (mbs.param[1] << 16));
2263
2264         case MBOX_LOOP_ID_USED:
2265                 isp_prt(isp, ISP_LOGDEBUG0,
2266                     "isp_port_login: handle 0x%04x in use for port id 0x%02xXXXX",
2267                     handle, mbs.param[1] & 0xff);
2268                 return (MBOX_LOOP_ID_USED);
2269
2270         case MBOX_COMMAND_COMPLETE:
2271                 return (0);
2272
2273         case MBOX_COMMAND_ERROR:
2274                 isp_prt(isp, ISP_LOGINFO,
2275                     "isp_port_login: error 0x%x in PLOGI to port 0x%06x",
2276                     mbs.param[1], portid);
2277                 return (MBOX_COMMAND_ERROR);
2278
2279         case MBOX_ALL_IDS_USED:
2280                 isp_prt(isp, ISP_LOGINFO,
2281                     "isp_port_login: all IDs used for fabric login");
2282                 return (MBOX_ALL_IDS_USED);
2283
2284         default:
2285                 isp_prt(isp, ISP_LOGINFO,
2286                     "isp_port_login: error 0x%x on port login of 0x%06x@0x%0x",
2287                     mbs.param[0], portid, handle);
2288                 return (mbs.param[0]);
2289         }
2290 }
2291
2292 static int
2293 isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
2294 {
2295         mbreg_t mbs;
2296
2297         MBSINIT(&mbs, MBOX_FABRIC_LOGOUT, MBLOGNONE, 500000);
2298         if (ISP_CAP_2KLOGIN(isp)) {
2299                 mbs.param[1] = handle;
2300                 mbs.ibits = (1 << 10);
2301         } else {
2302                 mbs.param[1] = handle << 8;
2303         }
2304         isp_mboxcmd(isp, &mbs);
2305         return (mbs.param[0] == MBOX_COMMAND_COMPLETE? 0 : mbs.param[0]);
2306 }
2307
2308 static int
2309 isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
2310 {
2311         fcparam *fcp = FCPARAM(isp, chan);
2312         mbreg_t mbs;
2313         union {
2314                 isp_pdb_21xx_t fred;
2315                 isp_pdb_24xx_t bill;
2316         } un;
2317
2318         MBSINIT(&mbs, MBOX_GET_PORT_DB, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 250000);
2319         if (IS_24XX(isp)) {
2320                 mbs.ibits = (1 << 9)|(1 << 10);
2321                 mbs.param[1] = id;
2322                 mbs.param[9] = chan;
2323         } else if (ISP_CAP_2KLOGIN(isp)) {
2324                 mbs.param[1] = id;
2325         } else {
2326                 mbs.param[1] = id << 8;
2327         }
2328         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2329         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2330         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2331         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2332         if (dolock) {
2333                 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2334                         isp_prt(isp, ISP_LOGERR, sacq);
2335                         return (-1);
2336                 }
2337         }
2338         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (un), chan);
2339         isp_mboxcmd(isp, &mbs);
2340         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2341                 if (dolock) {
2342                         FC_SCRATCH_RELEASE(isp, chan);
2343                 }
2344                 return (mbs.param[0]);
2345         }
2346         if (IS_24XX(isp)) {
2347                 isp_get_pdb_24xx(isp, fcp->isp_scratch, &un.bill);
2348                 pdb->handle = un.bill.pdb_handle;
2349                 pdb->s3_role = un.bill.pdb_prli_svc3;
2350                 pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
2351                 ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
2352                 ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
2353                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2354                     "Chan %d Port 0x%06x flags 0x%x curstate %x",
2355                     chan, pdb->portid, un.bill.pdb_flags,
2356                     un.bill.pdb_curstate);
2357                 if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE ||
2358                     un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) {
2359                         mbs.param[0] = MBOX_NOT_LOGGED_IN;
2360                         if (dolock) {
2361                                 FC_SCRATCH_RELEASE(isp, chan);
2362                         }
2363                         return (mbs.param[0]);
2364                 }
2365         } else {
2366                 isp_get_pdb_21xx(isp, fcp->isp_scratch, &un.fred);
2367                 pdb->handle = un.fred.pdb_loopid;
2368                 pdb->s3_role = un.fred.pdb_prli_svc3;
2369                 pdb->portid = BITS2WORD(un.fred.pdb_portid_bits);
2370                 ISP_MEMCPY(pdb->portname, un.fred.pdb_portname, 8);
2371                 ISP_MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8);
2372         }
2373         if (dolock) {
2374                 FC_SCRATCH_RELEASE(isp, chan);
2375         }
2376         return (0);
2377 }
2378
2379 static void
2380 isp_dump_chip_portdb(ispsoftc_t *isp, int chan, int dolock)
2381 {
2382         isp_pdb_t pdb;
2383         int lim, loopid;
2384
2385         if (ISP_CAP_2KLOGIN(isp)) {
2386                 lim = NPH_MAX_2K;
2387         } else {
2388                 lim = NPH_MAX;
2389         }
2390         for (loopid = 0; loopid != lim; loopid++) {
2391                 if (isp_getpdb(isp, chan, loopid, &pdb, dolock)) {
2392                         continue;
2393                 }
2394                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGINFO, "Chan %d Loopid 0x%04x "
2395                     "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x",
2396                     chan, loopid, pdb.portid, pdb.portname[0], pdb.portname[1],
2397                     pdb.portname[2], pdb.portname[3], pdb.portname[4],
2398                     pdb.portname[5], pdb.portname[6], pdb.portname[7]);
2399         }
2400 }
2401
2402 static uint64_t
2403 isp_get_wwn(ispsoftc_t *isp, int chan, int loopid, int nodename)
2404 {
2405         uint64_t wwn = INI_NONE;
2406         fcparam *fcp = FCPARAM(isp, chan);
2407         mbreg_t mbs;
2408
2409         if (fcp->isp_fwstate < FW_READY ||
2410             fcp->isp_loopstate < LOOP_PDB_RCVD) {
2411                 return (wwn);
2412         }
2413         MBSINIT(&mbs, MBOX_GET_PORT_NAME, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 500000);
2414         if (ISP_CAP_2KLOGIN(isp)) {
2415                 mbs.param[1] = loopid;
2416                 mbs.ibits = (1 << 10);
2417                 if (nodename) {
2418                         mbs.param[10] = 1;
2419                 }
2420                 if (ISP_CAP_MULTI_ID(isp)) {
2421                         mbs.ibits |= (1 << 9);
2422                         mbs.param[9] = chan;
2423                 }
2424         } else {
2425                 mbs.param[1] = loopid << 8;
2426                 if (nodename) {
2427                         mbs.param[1] |= 1;
2428                 }
2429         }
2430         isp_mboxcmd(isp, &mbs);
2431         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2432                 return (wwn);
2433         }
2434         if (IS_24XX(isp)) {
2435                 wwn =
2436                     (((uint64_t)(mbs.param[2] >> 8))    << 56) |
2437                     (((uint64_t)(mbs.param[2] & 0xff))  << 48) |
2438                     (((uint64_t)(mbs.param[3] >> 8))    << 40) |
2439                     (((uint64_t)(mbs.param[3] & 0xff))  << 32) |
2440                     (((uint64_t)(mbs.param[6] >> 8))    << 24) |
2441                     (((uint64_t)(mbs.param[6] & 0xff))  << 16) |
2442                     (((uint64_t)(mbs.param[7] >> 8))    <<  8) |
2443                     (((uint64_t)(mbs.param[7] & 0xff)));
2444         } else {
2445                 wwn =
2446                     (((uint64_t)(mbs.param[2] & 0xff))  << 56) |
2447                     (((uint64_t)(mbs.param[2] >> 8))    << 48) |
2448                     (((uint64_t)(mbs.param[3] & 0xff))  << 40) |
2449                     (((uint64_t)(mbs.param[3] >> 8))    << 32) |
2450                     (((uint64_t)(mbs.param[6] & 0xff))  << 24) |
2451                     (((uint64_t)(mbs.param[6] >> 8))    << 16) |
2452                     (((uint64_t)(mbs.param[7] & 0xff))  <<  8) |
2453                     (((uint64_t)(mbs.param[7] >> 8)));
2454         }
2455         return (wwn);
2456 }
2457
2458 /*
2459  * Make sure we have good FC link.
2460  */
2461
2462 static int
2463 isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
2464 {
2465         mbreg_t mbs;
2466         int count, check_for_fabric, r;
2467         uint8_t lwfs;
2468         int loopid;
2469         fcparam *fcp;
2470         fcportdb_t *lp;
2471         isp_pdb_t pdb;
2472
2473         fcp = FCPARAM(isp, chan);
2474
2475         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d FC Link Test Entry", chan);
2476         ISP_MARK_PORTDB(isp, chan, 1);
2477
2478         /*
2479          * Wait up to N microseconds for F/W to go to a ready state.
2480          */
2481         lwfs = FW_CONFIG_WAIT;
2482         count = 0;
2483         while (count < usdelay) {
2484                 uint64_t enano;
2485                 uint32_t wrk;
2486                 NANOTIME_T hra, hrb;
2487
2488                 GET_NANOTIME(&hra);
2489                 isp_fw_state(isp, chan);
2490                 if (lwfs != fcp->isp_fwstate) {
2491                         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));
2492                         lwfs = fcp->isp_fwstate;
2493                 }
2494                 if (fcp->isp_fwstate == FW_READY) {
2495                         break;
2496                 }
2497                 GET_NANOTIME(&hrb);
2498
2499                 /*
2500                  * Get the elapsed time in nanoseconds.
2501                  * Always guaranteed to be non-zero.
2502                  */
2503                 enano = NANOTIME_SUB(&hrb, &hra);
2504
2505                 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));
2506
2507                 /*
2508                  * If the elapsed time is less than 1 millisecond,
2509                  * delay a period of time up to that millisecond of
2510                  * waiting.
2511                  *
2512                  * This peculiar code is an attempt to try and avoid
2513                  * invoking uint64_t math support functions for some
2514                  * platforms where linkage is a problem.
2515                  */
2516                 if (enano < (1000 * 1000)) {
2517                         count += 1000;
2518                         enano = (1000 * 1000) - enano;
2519                         while (enano > (uint64_t) 4000000000U) {
2520                                 ISP_SLEEP(isp, 4000000);
2521                                 enano -= (uint64_t) 4000000000U;
2522                         }
2523                         wrk = enano;
2524                         wrk /= 1000;
2525                         ISP_SLEEP(isp, wrk);
2526                 } else {
2527                         while (enano > (uint64_t) 4000000000U) {
2528                                 count += 4000000;
2529                                 enano -= (uint64_t) 4000000000U;
2530                         }
2531                         wrk = enano;
2532                         count += (wrk / 1000);
2533                 }
2534         }
2535
2536
2537
2538         /*
2539          * If we haven't gone to 'ready' state, return.
2540          */
2541         if (fcp->isp_fwstate != FW_READY) {
2542                 isp_prt(isp, ISP_LOGSANCFG, "%s: chan %d not at FW_READY state", __func__, chan);
2543                 return (-1);
2544         }
2545
2546         /*
2547          * Get our Loop ID and Port ID.
2548          */
2549         MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0);
2550         if (ISP_CAP_MULTI_ID(isp)) {
2551                 mbs.param[9] = chan;
2552                 mbs.ibits = (1 << 9);
2553                 mbs.obits = (1 << 7);
2554         }
2555         isp_mboxcmd(isp, &mbs);
2556         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2557                 return (-1);
2558         }
2559
2560         if (ISP_CAP_2KLOGIN(isp)) {
2561                 fcp->isp_loopid = mbs.param[1];
2562         } else {
2563                 fcp->isp_loopid = mbs.param[1] & 0xff;
2564         }
2565
2566         if (IS_2100(isp)) {
2567                 fcp->isp_topo = TOPO_NL_PORT;
2568         } else {
2569                 int topo = (int) mbs.param[6];
2570                 if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB) {
2571                         topo = TOPO_PTP_STUB;
2572                 }
2573                 fcp->isp_topo = topo;
2574         }
2575         fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
2576
2577         if (IS_2100(isp)) {
2578                 /*
2579                  * Don't bother with fabric if we are using really old
2580                  * 2100 firmware. It's just not worth it.
2581                  */
2582                 if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) {
2583                         check_for_fabric = 1;
2584                 } else {
2585                         check_for_fabric = 0;
2586                 }
2587         } else if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_F_PORT) {
2588                 check_for_fabric = 1;
2589         } else {
2590                 check_for_fabric = 0;
2591         }
2592
2593         /*
2594          * Check to make sure we got a valid loopid
2595          * The 24XX seems to mess this up for multiple channels.
2596          */
2597         if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT) {
2598                 uint8_t alpa = fcp->isp_portid;
2599
2600                 if (alpa == 0) {
2601                         /* "Cannot Happen" */
2602                         isp_prt(isp, ISP_LOGWARN, "Zero AL_PA for Loop Topology?");
2603                 } else {
2604                         int i;
2605                         for (i = 0; alpa_map[i]; i++) {
2606                                 if (alpa_map[i] == alpa) {
2607                                         break;
2608                                 }
2609                         }
2610                         if (alpa_map[i] && fcp->isp_loopid != i) {
2611                                 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);
2612                                 fcp->isp_loopid = i;
2613                         }
2614                 }
2615         }
2616
2617
2618         if (IS_24XX(isp)) { /* XXX SHOULDN'T THIS BE FOR 2K F/W? XXX */
2619                 loopid = NPH_FL_ID;
2620         } else {
2621                 loopid = FL_ID;
2622         }
2623         if (check_for_fabric) {
2624                 r = isp_getpdb(isp, chan, loopid, &pdb, 1);
2625                 if (r && (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT)) {
2626                         isp_prt(isp, ISP_LOGWARN, "fabric topology but cannot get info about fabric controller (0x%x)", r);
2627                         fcp->isp_topo = TOPO_PTP_STUB;
2628                 }
2629         } else {
2630                 r = -1;
2631         }
2632         if (r == 0) {
2633                 if (IS_2100(isp)) {
2634                         fcp->isp_topo = TOPO_FL_PORT;
2635                 }
2636                 if (pdb.portid == 0) {
2637                         /*
2638                          * Crock.
2639                          */
2640                         fcp->isp_topo = TOPO_NL_PORT;
2641                         goto not_on_fabric;
2642                 }
2643
2644                 /*
2645                  * Save the Fabric controller's port database entry.
2646                  */
2647                 lp = &fcp->portdb[FL_ID];
2648                 lp->state = FC_PORTDB_STATE_PENDING_VALID;
2649                 MAKE_WWN_FROM_NODE_NAME(lp->node_wwn, pdb.nodename);
2650                 MAKE_WWN_FROM_NODE_NAME(lp->port_wwn, pdb.portname);
2651                 lp->roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
2652                 lp->portid = pdb.portid;
2653                 lp->handle = pdb.handle;
2654                 lp->new_portid = lp->portid;
2655                 lp->new_roles = lp->roles;
2656                 if (IS_24XX(isp)) {
2657                         fcp->inorder = (mbs.param[7] & ISP24XX_INORDER) != 0;
2658                         if (ISP_FW_NEWER_THAN(isp, 4, 0, 27)) {
2659                                 fcp->npiv_fabric = (mbs.param[7] & ISP24XX_NPIV_SAN) != 0;
2660                                 if (fcp->npiv_fabric) {
2661                                         isp_prt(isp, ISP_LOGCONFIG, "fabric supports NP-IV");
2662                                 }
2663                         }
2664                         if (chan) {
2665                                 fcp->isp_sns_hdl = NPH_SNS_HDLBASE + chan;
2666                                 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);
2667                                 if (r) {
2668                                         isp_prt(isp, ISP_LOGWARN, "%s: Chan %d cannot log into SNS", __func__, chan);
2669                                         return (-1);
2670                                 }
2671                         } else {
2672                                 fcp->isp_sns_hdl = NPH_SNS_ID;
2673                         }
2674                         r = isp_register_fc4_type_24xx(isp, chan);
2675                 } else {
2676                         fcp->isp_sns_hdl = SNS_ID;
2677                         r = isp_register_fc4_type(isp, chan);
2678                 }
2679                 if (r) {
2680                         isp_prt(isp, ISP_LOGWARN|ISP_LOGSANCFG, "%s: register fc4 type failed", __func__);
2681                         return (-1);
2682                 }
2683         } else {
2684 not_on_fabric:
2685                 fcp->portdb[FL_ID].state = FC_PORTDB_STATE_NIL;
2686         }
2687
2688         fcp->isp_gbspeed = 1;
2689         if (IS_23XX(isp) || IS_24XX(isp)) {
2690                 MBSINIT(&mbs, MBOX_GET_SET_DATA_RATE, MBLOGALL, 3000000);
2691                 mbs.param[1] = MBGSD_GET_RATE;
2692                 /* mbs.param[2] undefined if we're just getting rate */
2693                 isp_mboxcmd(isp, &mbs);
2694                 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
2695                         if (mbs.param[1] == MBGSD_EIGHTGB) {
2696                                 isp_prt(isp, ISP_LOGINFO, "Chan %d 8Gb link speed", chan);
2697                                 fcp->isp_gbspeed = 8;
2698                         } else if (mbs.param[1] == MBGSD_FOURGB) {
2699                                 isp_prt(isp, ISP_LOGINFO, "Chan %d 4Gb link speed", chan);
2700                                 fcp->isp_gbspeed = 4;
2701                         } else if (mbs.param[1] == MBGSD_TWOGB) {
2702                                 isp_prt(isp, ISP_LOGINFO, "Chan %d 2Gb link speed", chan);
2703                                 fcp->isp_gbspeed = 2;
2704                         } else if (mbs.param[1] == MBGSD_ONEGB) {
2705                                 isp_prt(isp, ISP_LOGINFO, "Chan %d 1Gb link speed", chan);
2706                                 fcp->isp_gbspeed = 1;
2707                         }
2708                 }
2709         }
2710
2711         /*
2712          * Announce ourselves, too.
2713          */
2714         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));
2715         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d FC Link Test Complete", chan);
2716         return (0);
2717 }
2718
2719 /*
2720  * Complete the synchronization of our Port Database.
2721  *
2722  * At this point, we've scanned the local loop (if any) and the fabric
2723  * and performed fabric logins on all new devices.
2724  *
2725  * Our task here is to go through our port database and remove any entities
2726  * that are still marked probational (issuing PLOGO for ones which we had
2727  * PLOGI'd into) or are dead.
2728  *
2729  * Our task here is to also check policy to decide whether devices which
2730  * have *changed* in some way should still be kept active. For example,
2731  * if a device has just changed PortID, we can either elect to treat it
2732  * as an old device or as a newly arrived device (and notify the outer
2733  * layer appropriately).
2734  *
2735  * We also do initiator map target id assignment here for new initiator
2736  * devices and refresh old ones ot make sure that they point to the corret
2737  * entities.
2738  */
2739 static int
2740 isp_pdb_sync(ispsoftc_t *isp, int chan)
2741 {
2742         fcparam *fcp = FCPARAM(isp, chan);
2743         fcportdb_t *lp;
2744         uint16_t dbidx;
2745
2746         if (fcp->isp_loopstate == LOOP_READY) {
2747                 return (0);
2748         }
2749
2750         /*
2751          * Make sure we're okay for doing this right now.
2752          */
2753         if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
2754             fcp->isp_loopstate != LOOP_FSCAN_DONE &&
2755             fcp->isp_loopstate != LOOP_LSCAN_DONE) {
2756                 isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d",
2757                     fcp->isp_loopstate);
2758                 return (-1);
2759         }
2760
2761         if (fcp->isp_topo == TOPO_FL_PORT ||
2762             fcp->isp_topo == TOPO_NL_PORT ||
2763             fcp->isp_topo == TOPO_N_PORT) {
2764                 if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
2765                         if (isp_scan_loop(isp, chan) != 0) {
2766                                 isp_prt(isp, ISP_LOGWARN,
2767                                     "isp_pdb_sync: isp_scan_loop failed");
2768                                 return (-1);
2769                         }
2770                 }
2771         }
2772
2773         if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
2774                 if (fcp->isp_loopstate < LOOP_FSCAN_DONE) {
2775                         if (isp_scan_fabric(isp, chan) != 0) {
2776                                 isp_prt(isp, ISP_LOGWARN,
2777                                     "isp_pdb_sync: isp_scan_fabric failed");
2778                                 return (-1);
2779                         }
2780                 }
2781         }
2782
2783         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2784             "Chan %d Synchronizing PDBs", chan);
2785
2786         fcp->isp_loopstate = LOOP_SYNCING_PDB;
2787
2788         for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
2789                 lp = &fcp->portdb[dbidx];
2790
2791                 if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode) {
2792                         continue;
2793                 }
2794
2795                 if (lp->state == FC_PORTDB_STATE_VALID) {
2796                         if (dbidx != FL_ID) {
2797                                 isp_prt(isp,
2798                                     ISP_LOGERR, "portdb idx %d already valid",
2799                                     dbidx);
2800                         }
2801                         continue;
2802                 }
2803
2804                 switch (lp->state) {
2805                 case FC_PORTDB_STATE_PROBATIONAL:
2806                 case FC_PORTDB_STATE_DEAD:
2807                         /*
2808                          * It's up to the outer layers to clear isp_dev_map.
2809                          */
2810                         lp->state = FC_PORTDB_STATE_NIL;
2811                         isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
2812                         if (lp->autologin == 0) {
2813                                 (void) isp_plogx(isp, chan, lp->handle,
2814                                     lp->portid,
2815                                     PLOGX_FLG_CMD_LOGO |
2816                                     PLOGX_FLG_IMPLICIT |
2817                                     PLOGX_FLG_FREE_NPHDL, 0);
2818                         } else {
2819                                 lp->autologin = 0;
2820                         }
2821                         lp->new_roles = 0;
2822                         lp->new_portid = 0;
2823                         /*
2824                          * Note that we might come out of this with our state
2825                          * set to FC_PORTDB_STATE_ZOMBIE.
2826                          */
2827                         break;
2828                 case FC_PORTDB_STATE_NEW:
2829                         /*
2830                          * It's up to the outer layers to assign a virtual
2831                          * target id in isp_dev_map (if any).
2832                          */
2833                         lp->portid = lp->new_portid;
2834                         lp->roles = lp->new_roles;
2835                         lp->state = FC_PORTDB_STATE_VALID;
2836                         isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
2837                         lp->new_roles = 0;
2838                         lp->new_portid = 0;
2839                         lp->reserved = 0;
2840                         lp->new_reserved = 0;
2841                         break;
2842                 case FC_PORTDB_STATE_CHANGED:
2843 /*
2844  * XXXX FIX THIS
2845  */
2846                         lp->state = FC_PORTDB_STATE_VALID;
2847                         isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
2848                         lp->new_roles = 0;
2849                         lp->new_portid = 0;
2850                         lp->reserved = 0;
2851                         lp->new_reserved = 0;
2852                         break;
2853                 case FC_PORTDB_STATE_PENDING_VALID:
2854                         lp->portid = lp->new_portid;
2855                         lp->roles = lp->new_roles;
2856                         if (lp->dev_map_idx) {
2857                                 int t = lp->dev_map_idx - 1;
2858                                 fcp->isp_dev_map[t] = dbidx + 1;
2859                         }
2860                         lp->state = FC_PORTDB_STATE_VALID;
2861                         isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
2862                         if (dbidx != FL_ID) {
2863                                 lp->new_roles = 0;
2864                                 lp->new_portid = 0;
2865                         }
2866                         lp->reserved = 0;
2867                         lp->new_reserved = 0;
2868                         break;
2869                 case FC_PORTDB_STATE_ZOMBIE:
2870                         break;
2871                 default:
2872                         isp_prt(isp, ISP_LOGWARN,
2873                             "isp_scan_loop: state %d for idx %d",
2874                             lp->state, dbidx);
2875                         isp_dump_portdb(isp, chan);
2876                 }
2877         }
2878
2879         /*
2880          * If we get here, we've for sure seen not only a valid loop
2881          * but know what is or isn't on it, so mark this for usage
2882          * in isp_start.
2883          */
2884         fcp->loop_seen_once = 1;
2885         fcp->isp_loopstate = LOOP_READY;
2886         return (0);
2887 }
2888
2889 /*
2890  * Scan local loop for devices.
2891  */
2892 static int
2893 isp_scan_loop(ispsoftc_t *isp, int chan)
2894 {
2895         fcportdb_t *lp, tmp;
2896         fcparam *fcp = FCPARAM(isp, chan);
2897         int i;
2898         isp_pdb_t pdb;
2899         uint16_t handle, lim = 0;
2900
2901         if (fcp->isp_fwstate < FW_READY ||
2902             fcp->isp_loopstate < LOOP_PDB_RCVD) {
2903                 return (-1);
2904         }
2905
2906         if (fcp->isp_loopstate > LOOP_SCANNING_LOOP) {
2907                 return (0);
2908         }
2909
2910         /*
2911          * Check our connection topology.
2912          *
2913          * If we're a public or private loop, we scan 0..125 as handle values.
2914          * The firmware has (typically) peformed a PLOGI for us. We skip this
2915          * step if we're a ISP_24XX in NP-IV mode.
2916          *
2917          * If we're a N-port connection, we treat this is a short loop (0..1).
2918          */
2919         switch (fcp->isp_topo) {
2920         case TOPO_NL_PORT:
2921                 lim = LOCAL_LOOP_LIM;
2922                 break;
2923         case TOPO_FL_PORT:
2924                 if (IS_24XX(isp) && isp->isp_nchan > 1) {
2925                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2926                             "Chan %d Skipping Local Loop Scan", chan);
2927                         fcp->isp_loopstate = LOOP_LSCAN_DONE;
2928                         return (0);
2929                 }
2930                 lim = LOCAL_LOOP_LIM;
2931                 break;
2932         case TOPO_N_PORT:
2933                 lim = 2;
2934                 break;
2935         default:
2936                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2937                     "Chan %d no loop topology to scan", chan);
2938                 fcp->isp_loopstate = LOOP_LSCAN_DONE;
2939                 return (0);
2940         }
2941
2942         fcp->isp_loopstate = LOOP_SCANNING_LOOP;
2943
2944         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2945             "Chan %d FC scan loop 0..%d", chan, lim-1);
2946
2947
2948         /*
2949          * Run through the list and get the port database info for each one.
2950          */
2951         for (handle = 0; handle < lim; handle++) {
2952                 int r;
2953                 /*
2954                  * Don't scan "special" ids.
2955                  */
2956                 if (handle >= FL_ID && handle <= SNS_ID) {
2957                         continue;
2958                 }
2959                 if (ISP_CAP_2KLOGIN(isp)) {
2960                         if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
2961                                 continue;
2962                         }
2963                 }
2964                 /*
2965                  * In older cards with older f/w GET_PORT_DATABASE has been
2966                  * known to hang. This trick gets around that problem.
2967                  */
2968                 if (IS_2100(isp) || IS_2200(isp)) {
2969                         uint64_t node_wwn = isp_get_wwn(isp, chan, handle, 1);
2970                         if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2971                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2972                                     "Chan %d FC scan loop DONE (bad)", chan);
2973                                 return (-1);
2974                         }
2975                         if (node_wwn == INI_NONE) {
2976                                 continue;
2977                         }
2978                 }
2979
2980                 /*
2981                  * Get the port database entity for this index.
2982                  */
2983                 r = isp_getpdb(isp, chan, handle, &pdb, 1);
2984                 if (r != 0) {
2985                         isp_prt(isp, ISP_LOGDEBUG1,
2986                             "Chan %d FC scan loop handle %d returned %x",
2987                             chan, handle, r);
2988                         if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2989                                 ISP_MARK_PORTDB(isp, chan, 1);
2990                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2991                                     "Chan %d FC scan loop DONE (bad)", chan);
2992                                 return (-1);
2993                         }
2994                         continue;
2995                 }
2996
2997                 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2998                         ISP_MARK_PORTDB(isp, chan, 1);
2999                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3000                             "Chan %d FC scan loop DONE (bad)", chan);
3001                         return (-1);
3002                 }
3003
3004                 /*
3005                  * On *very* old 2100 firmware we would end up sometimes
3006                  * with the firmware returning the port database entry
3007                  * for something else. We used to restart this, but
3008                  * now we just punt.
3009                  */
3010                 if (IS_2100(isp) && pdb.handle != handle) {
3011                         isp_prt(isp, ISP_LOGWARN,
3012                             "Chan %d cannot synchronize port database", chan);
3013                         ISP_MARK_PORTDB(isp, chan, 1);
3014                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3015                             "Chan %d FC scan loop DONE (bad)", chan);
3016                         return (-1);
3017                 }
3018
3019                 /*
3020                  * Save the pertinent info locally.
3021                  */
3022                 MAKE_WWN_FROM_NODE_NAME(tmp.node_wwn, pdb.nodename);
3023                 MAKE_WWN_FROM_NODE_NAME(tmp.port_wwn, pdb.portname);
3024                 tmp.roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
3025                 tmp.portid = pdb.portid;
3026                 tmp.handle = pdb.handle;
3027
3028                 /*
3029                  * Check to make sure it's still a valid entry. The 24XX seems
3030                  * to return a portid but not a WWPN/WWNN or role for devices
3031                  * which shift on a loop.
3032                  */
3033                 if (tmp.node_wwn == 0 || tmp.port_wwn == 0 || tmp.portid == 0) {
3034                         int a, b, c;
3035                         a = (tmp.node_wwn == 0);
3036                         b = (tmp.port_wwn == 0);
3037                         c = (tmp.portid == 0);
3038                         if (a == 0 && b == 0) {
3039                                 tmp.node_wwn =
3040                                     isp_get_wwn(isp, chan, handle, 1);
3041                                 tmp.port_wwn =
3042                                     isp_get_wwn(isp, chan, handle, 0);
3043                                 if (tmp.node_wwn && tmp.port_wwn) {
3044                                         isp_prt(isp, ISP_LOGINFO, "DODGED!");
3045                                         goto cont;
3046                                 }
3047                         }
3048                         isp_prt(isp, ISP_LOGWARN,
3049                             "Chan %d bad pdb (%1d%1d%1d) @ handle 0x%x", chan,
3050                             a, b, c, handle);
3051                         isp_dump_portdb(isp, chan);
3052                         continue;
3053                 }
3054   cont:
3055
3056                 /*
3057                  * Now search the entire port database
3058                  * for the same Port and Node WWN.
3059                  */
3060                 for (i = 0; i < MAX_FC_TARG; i++) {
3061                         lp = &fcp->portdb[i];
3062
3063                         if (lp->state == FC_PORTDB_STATE_NIL ||
3064                             lp->target_mode) {
3065                                 continue;
3066                         }
3067                         if (lp->node_wwn != tmp.node_wwn) {
3068                                 continue;
3069                         }
3070                         if (lp->port_wwn != tmp.port_wwn) {
3071                                 continue;
3072                         }
3073
3074                         /*
3075                          * Okay- we've found a non-nil entry that matches.
3076                          * Check to make sure it's probational or a zombie.
3077                          */
3078                         if (lp->state != FC_PORTDB_STATE_PROBATIONAL &&
3079                             lp->state != FC_PORTDB_STATE_ZOMBIE) {
3080                                 isp_prt(isp, ISP_LOGERR,
3081                                     "Chan %d [%d] not probational/zombie (0x%x)",
3082                                     chan, i, lp->state);
3083                                 isp_dump_portdb(isp, chan);
3084                                 ISP_MARK_PORTDB(isp, chan, 1);
3085                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3086                                     "Chan %d FC scan loop DONE (bad)", chan);
3087                                 return (-1);
3088                         }
3089
3090                         /*
3091                          * Mark the device as something the f/w logs into
3092                          * automatically.
3093                          */
3094                         lp->autologin = 1;
3095
3096                         /*
3097                          * Check to make see if really still the same
3098                          * device. If it is, we mark it pending valid.
3099                          */
3100                         if (lp->portid == tmp.portid &&
3101                             lp->handle == tmp.handle &&
3102                             lp->roles == tmp.roles) {
3103                                 lp->new_portid = tmp.portid;
3104                                 lp->new_roles = tmp.roles;
3105                                 lp->state = FC_PORTDB_STATE_PENDING_VALID;
3106                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3107                                     "Chan %d Loop Port 0x%06x@0x%04x Pending "
3108                                     "Valid", chan, tmp.portid, tmp.handle);
3109                                 break;
3110                         }
3111
3112                         /*
3113                          * We can wipe out the old handle value
3114                          * here because it's no longer valid.
3115                          */
3116                         lp->handle = tmp.handle;
3117
3118                         /*
3119                          * Claim that this has changed and let somebody else
3120                          * decide what to do.
3121                          */
3122                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3123                             "Chan %d Loop Port 0x%06x@0x%04x changed",
3124                             chan, tmp.portid, tmp.handle);
3125                         lp->state = FC_PORTDB_STATE_CHANGED;
3126                         lp->new_portid = tmp.portid;
3127                         lp->new_roles = tmp.roles;
3128                         break;
3129                 }
3130
3131                 /*
3132                  * Did we find and update an old entry?
3133                  */
3134                 if (i < MAX_FC_TARG) {
3135                         continue;
3136                 }
3137
3138                 /*
3139                  * Ah. A new device entry. Find an empty slot
3140                  * for it and save info for later disposition.
3141                  */
3142                 for (i = 0; i < MAX_FC_TARG; i++) {
3143                         if (fcp->portdb[i].target_mode) {
3144                                 continue;
3145                         }
3146                         if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL) {
3147                                 break;
3148                         }
3149                 }
3150                 if (i == MAX_FC_TARG) {
3151                         isp_prt(isp, ISP_LOGERR,
3152                             "Chan %d out of portdb entries", chan);
3153                         continue;
3154                 }
3155                 lp = &fcp->portdb[i];
3156
3157                 ISP_MEMZERO(lp, sizeof (fcportdb_t));
3158                 lp->autologin = 1;
3159                 lp->state = FC_PORTDB_STATE_NEW;
3160                 lp->new_portid = tmp.portid;
3161                 lp->new_roles = tmp.roles;
3162                 lp->handle = tmp.handle;
3163                 lp->port_wwn = tmp.port_wwn;
3164                 lp->node_wwn = tmp.node_wwn;
3165                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3166                     "Chan %d Loop Port 0x%06x@0x%04x is New Entry",
3167                     chan, tmp.portid, tmp.handle);
3168         }
3169         fcp->isp_loopstate = LOOP_LSCAN_DONE;
3170         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3171             "Chan %d FC scan loop DONE", chan);
3172         return (0);
3173 }
3174
3175 /*
3176  * Scan the fabric for devices and add them to our port database.
3177  *
3178  * Use the GID_FT command to get all Port IDs for FC4 SCSI devices it knows.
3179  *
3180  * For 2100-23XX cards, we can use the SNS mailbox command to pass simple
3181  * name server commands to the switch management server via the QLogic f/w.
3182  *
3183  * For the 24XX card, we have to use CT-Pass through run via the Execute IOCB
3184  * mailbox command.
3185  *
3186  * The net result is to leave the list of Port IDs setting untranslated in
3187  * offset IGPOFF of the FC scratch area, whereupon we'll canonicalize it to
3188  * host order at OGPOFF.
3189  */
3190
3191 /*
3192  * Take less than half of our scratch area to store Port IDs
3193  */
3194 #define GIDLEN  ((ISP_FC_SCRLEN >> 1) - 16 - SNS_GID_FT_REQ_SIZE)
3195 #define NGENT   ((GIDLEN - 16) >> 2)
3196
3197 #define IGPOFF  (2 * QENTRY_LEN)
3198 #define OGPOFF  (ISP_FC_SCRLEN >> 1)
3199 #define ZTXOFF  (ISP_FC_SCRLEN - (1 * QENTRY_LEN))
3200 #define CTXOFF  (ISP_FC_SCRLEN - (2 * QENTRY_LEN))
3201 #define XTXOFF  (ISP_FC_SCRLEN - (3 * QENTRY_LEN))
3202
3203 static int
3204 isp_gid_ft_sns(ispsoftc_t *isp, int chan)
3205 {
3206         union {
3207                 sns_gid_ft_req_t _x;
3208                 uint8_t _y[SNS_GID_FT_REQ_SIZE];
3209         } un;
3210         fcparam *fcp = FCPARAM(isp, chan);
3211         sns_gid_ft_req_t *rq = &un._x;
3212         mbreg_t mbs;
3213
3214         isp_prt(isp, ISP_LOGDEBUG0,
3215             "Chan %d scanning fabric (GID_FT) via SNS", chan);
3216
3217         ISP_MEMZERO(rq, SNS_GID_FT_REQ_SIZE);
3218         rq->snscb_rblen = GIDLEN >> 1;
3219         rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + IGPOFF);
3220         rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + IGPOFF);
3221         rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + IGPOFF);
3222         rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + IGPOFF);
3223         rq->snscb_sblen = 6;
3224         rq->snscb_cmd = SNS_GID_FT;
3225         rq->snscb_mword_div_2 = NGENT;
3226         rq->snscb_fc4_type = FC4_SCSI;
3227
3228         isp_put_gid_ft_request(isp, rq, fcp->isp_scratch);
3229         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE, chan);
3230
3231         MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 10000000);
3232         mbs.param[0] = MBOX_SEND_SNS;
3233         mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
3234         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
3235         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
3236         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
3237         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
3238         isp_mboxcmd(isp, &mbs);
3239         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3240                 if (mbs.param[0] == MBOX_INVALID_COMMAND) {
3241                         return (1);
3242                 } else {
3243                         return (-1);
3244                 }
3245         }
3246         return (0);
3247 }
3248
3249 static int
3250 isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
3251 {
3252         mbreg_t mbs;
3253         fcparam *fcp = FCPARAM(isp, chan);
3254         union {
3255                 isp_ct_pt_t plocal;
3256                 ct_hdr_t clocal;
3257                 uint8_t q[QENTRY_LEN];
3258         } un;
3259         isp_ct_pt_t *pt;
3260         ct_hdr_t *ct;
3261         uint32_t *rp;
3262         uint8_t *scp = fcp->isp_scratch;
3263
3264         isp_prt(isp, ISP_LOGDEBUG0,
3265             "Chan %d scanning fabric (GID_FT) via CT", chan);
3266
3267         if (!IS_24XX(isp)) {
3268                 return (1);
3269         }
3270
3271         /*
3272          * Build a Passthrough IOCB in memory.
3273          */
3274         pt = &un.plocal;
3275         ISP_MEMZERO(un.q, QENTRY_LEN);
3276         pt->ctp_header.rqs_entry_count = 1;
3277         pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
3278         pt->ctp_handle = 0xffffffff;
3279         pt->ctp_nphdl = fcp->isp_sns_hdl;
3280         pt->ctp_cmd_cnt = 1;
3281         pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
3282         pt->ctp_time = 30;
3283         pt->ctp_rsp_cnt = 1;
3284         pt->ctp_rsp_bcnt = GIDLEN;
3285         pt->ctp_cmd_bcnt = sizeof (*ct) + sizeof (uint32_t);
3286         pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
3287         pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
3288         pt->ctp_dataseg[0].ds_count = sizeof (*ct) + sizeof (uint32_t);
3289         pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
3290         pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
3291         pt->ctp_dataseg[1].ds_count = GIDLEN;
3292         if (isp->isp_dblev & ISP_LOGDEBUG1) {
3293                 isp_print_bytes(isp, "ct IOCB", QENTRY_LEN, pt);
3294         }
3295         isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
3296
3297         /*
3298          * Build the CT header and command in memory.
3299          *
3300          * Note that the CT header has to end up as Big Endian format in memory.
3301          */
3302         ct = &un.clocal;
3303         ISP_MEMZERO(ct, sizeof (*ct));
3304         ct->ct_revision = CT_REVISION;
3305         ct->ct_fcs_type = CT_FC_TYPE_FC;
3306         ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
3307         ct->ct_cmd_resp = SNS_GID_FT;
3308         ct->ct_bcnt_resid = (GIDLEN - 16) >> 2;
3309
3310         isp_put_ct_hdr(isp, ct, (ct_hdr_t *) &scp[XTXOFF]);
3311         rp = (uint32_t *) &scp[XTXOFF+sizeof (*ct)];
3312         ISP_IOZPUT_32(isp, FC4_SCSI, rp);
3313         if (isp->isp_dblev & ISP_LOGDEBUG1) {
3314                 isp_print_bytes(isp, "CT HDR + payload after put",
3315                     sizeof (*ct) + sizeof (uint32_t), &scp[XTXOFF]);
3316         }
3317         ISP_MEMZERO(&scp[ZTXOFF], QENTRY_LEN);
3318         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
3319         mbs.param[1] = QENTRY_LEN;
3320         mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
3321         mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
3322         mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
3323         mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
3324         MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN, chan);
3325         isp_mboxcmd(isp, &mbs);
3326         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3327                 return (-1);
3328         }
3329         MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN, chan);
3330         pt = &un.plocal;
3331         isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
3332         if (isp->isp_dblev & ISP_LOGDEBUG1) {
3333                 isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
3334         }
3335
3336         if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) {
3337                 isp_prt(isp, ISP_LOGWARN,
3338                     "Chan %d ISP GID FT CT Passthrough returned 0x%x",
3339                     chan, pt->ctp_status);
3340                 return (-1);
3341         }
3342         MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN + 16, chan);
3343         if (isp->isp_dblev & ISP_LOGDEBUG1) {
3344                 isp_print_bytes(isp, "CT response", GIDLEN+16, &scp[IGPOFF]);
3345         }
3346         return (0);
3347 }
3348
3349 static int
3350 isp_scan_fabric(ispsoftc_t *isp, int chan)
3351 {
3352         fcparam *fcp = FCPARAM(isp, chan);
3353         uint32_t portid;
3354         uint16_t handle, oldhandle, loopid;
3355         isp_pdb_t pdb;
3356         int portidx, portlim, r;
3357         sns_gid_ft_rsp_t *rs0, *rs1;
3358
3359         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3360             "Chan %d FC Scan Fabric", chan);
3361         if (fcp->isp_fwstate != FW_READY ||
3362             fcp->isp_loopstate < LOOP_LSCAN_DONE) {
3363                 return (-1);
3364         }
3365         if (fcp->isp_loopstate > LOOP_SCANNING_FABRIC) {
3366                 return (0);
3367         }
3368         if (fcp->isp_topo != TOPO_FL_PORT && fcp->isp_topo != TOPO_F_PORT) {
3369                 fcp->isp_loopstate = LOOP_FSCAN_DONE;
3370                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3371                     "Chan %d FC Scan Fabric Done (no fabric)", chan);
3372                 return (0);
3373         }
3374
3375         fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
3376         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
3377                 isp_prt(isp, ISP_LOGERR, sacq);
3378                 ISP_MARK_PORTDB(isp, chan, 1);
3379                 return (-1);
3380         }
3381         if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3382                 FC_SCRATCH_RELEASE(isp, chan);
3383                 ISP_MARK_PORTDB(isp, chan, 1);
3384                 return (-1);
3385         }
3386
3387         /*
3388          * Make sure we still are logged into the fabric controller.
3389          */
3390         if (IS_24XX(isp)) {     /* XXX SHOULDN'T THIS BE TRUE FOR 2K F/W? XXX */
3391                 loopid = NPH_FL_ID;
3392         } else {
3393                 loopid = FL_ID;
3394         }
3395         r = isp_getpdb(isp, chan, loopid, &pdb, 0);
3396         if (r == MBOX_NOT_LOGGED_IN) {
3397                 isp_dump_chip_portdb(isp, chan, 0);
3398         }
3399         if (r) {
3400                 fcp->isp_loopstate = LOOP_PDB_RCVD;
3401                 FC_SCRATCH_RELEASE(isp, chan);
3402                 ISP_MARK_PORTDB(isp, chan, 1);
3403                 return (-1);
3404         }
3405
3406         if (IS_24XX(isp)) {
3407                 r = isp_gid_ft_ct_passthru(isp, chan);
3408         } else {
3409                 r = isp_gid_ft_sns(isp, chan);
3410         }
3411
3412         if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3413                 FC_SCRATCH_RELEASE(isp, chan);
3414                 ISP_MARK_PORTDB(isp, chan, 1);
3415                 return (-1);
3416         }
3417
3418         if (r > 0) {
3419                 fcp->isp_loopstate = LOOP_FSCAN_DONE;
3420                 FC_SCRATCH_RELEASE(isp, chan);
3421                 return (0);
3422         } else if (r < 0) {
3423                 fcp->isp_loopstate = LOOP_PDB_RCVD;     /* try again */
3424                 FC_SCRATCH_RELEASE(isp, chan);
3425                 return (0);
3426         }
3427
3428         MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN, chan);
3429         rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF);
3430         rs1 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+OGPOFF);
3431         isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
3432         if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3433                 FC_SCRATCH_RELEASE(isp, chan);
3434                 ISP_MARK_PORTDB(isp, chan, 1);
3435                 return (-1);
3436         }
3437         if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) {
3438                 int level;
3439                 if (rs1->snscb_cthdr.ct_reason == 9 &&
3440                     rs1->snscb_cthdr.ct_explanation == 7) {
3441                         level = ISP_LOGSANCFG|ISP_LOGDEBUG0;
3442                 } else {
3443                         level = ISP_LOGWARN;
3444                 }
3445                 isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_FT"
3446                     " (Reason=0x%x Expl=0x%x)", chan,
3447                     rs1->snscb_cthdr.ct_reason,
3448                     rs1->snscb_cthdr.ct_explanation);
3449                 FC_SCRATCH_RELEASE(isp, chan);
3450                 fcp->isp_loopstate = LOOP_FSCAN_DONE;
3451                 return (0);
3452         }
3453
3454
3455         /*
3456          * If we get this far, we certainly still have the fabric controller.
3457          */
3458         fcp->portdb[FL_ID].state = FC_PORTDB_STATE_PENDING_VALID;
3459
3460         /*
3461          * Prime the handle we will start using.
3462          */
3463         oldhandle = FCPARAM(isp, 0)->isp_lasthdl;
3464
3465         /*
3466          * Go through the list and remove duplicate port ids.
3467          */
3468
3469         portlim = 0;
3470         portidx = 0;
3471         for (portidx = 0; portidx < NGENT-1; portidx++) {
3472                 if (rs1->snscb_ports[portidx].control & 0x80) {
3473                         break;
3474                 }
3475         }
3476
3477         /*
3478          * If we're not at the last entry, our list wasn't big enough.
3479          */
3480         if ((rs1->snscb_ports[portidx].control & 0x80) == 0) {
3481                 isp_prt(isp, ISP_LOGWARN,
3482                     "fabric too big for scratch area: increase ISP_FC_SCRLEN");
3483         }
3484         portlim = portidx + 1;
3485         isp_prt(isp, ISP_LOGSANCFG,
3486             "Chan %d got %d ports back from name server", chan, portlim);
3487
3488         for (portidx = 0; portidx < portlim; portidx++) {
3489                 int npidx;
3490
3491                 portid =
3492                     ((rs1->snscb_ports[portidx].portid[0]) << 16) |
3493                     ((rs1->snscb_ports[portidx].portid[1]) << 8) |
3494                     ((rs1->snscb_ports[portidx].portid[2]));
3495
3496                 for (npidx = portidx + 1; npidx < portlim; npidx++) {
3497                         uint32_t new_portid =
3498                             ((rs1->snscb_ports[npidx].portid[0]) << 16) |
3499                             ((rs1->snscb_ports[npidx].portid[1]) << 8) |
3500                             ((rs1->snscb_ports[npidx].portid[2]));
3501                         if (new_portid == portid) {
3502                                 break;
3503                         }
3504                 }
3505
3506                 if (npidx < portlim) {
3507                         rs1->snscb_ports[npidx].portid[0] = 0;
3508                         rs1->snscb_ports[npidx].portid[1] = 0;
3509                         rs1->snscb_ports[npidx].portid[2] = 0;
3510                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3511                             "Chan %d removing duplicate PortID 0x%06x"
3512                             " entry from list", chan, portid);
3513                 }
3514         }
3515
3516         /*
3517          * We now have a list of Port IDs for all FC4 SCSI devices
3518          * that the Fabric Name server knows about.
3519          *
3520          * For each entry on this list go through our port database looking
3521          * for probational entries- if we find one, then an old entry is
3522          * maybe still this one. We get some information to find out.
3523          *
3524          * Otherwise, it's a new fabric device, and we log into it
3525          * (unconditionally). After searching the entire database
3526          * again to make sure that we never ever ever ever have more
3527          * than one entry that has the same PortID or the same
3528          * WWNN/WWPN duple, we enter the device into our database.
3529          */
3530
3531         for (portidx = 0; portidx < portlim; portidx++) {
3532                 fcportdb_t *lp;
3533                 uint64_t wwnn, wwpn;
3534                 int dbidx, nr;
3535
3536                 portid =
3537                     ((rs1->snscb_ports[portidx].portid[0]) << 16) |
3538                     ((rs1->snscb_ports[portidx].portid[1]) << 8) |
3539                     ((rs1->snscb_ports[portidx].portid[2]));
3540
3541                 if (portid == 0) {
3542                         isp_prt(isp, ISP_LOGSANCFG,
3543                             "Chan %d skipping null PortID at idx %d",
3544                             chan, portidx);
3545                         continue;
3546                 }
3547
3548                 /*
3549                  * Skip ourselves here and on other channels. If we're
3550                  * multi-id, we can't check the portids in other FCPARAM
3551                  * arenas because the resolutions here aren't synchronized.
3552                  * The best way to do this is to exclude looking at portids
3553                  * that have the same domain and area code as our own
3554                  * portid.
3555                  */
3556                 if (ISP_CAP_MULTI_ID(isp)) {
3557                         if ((portid >> 8) == (fcp->isp_portid >> 8)) {
3558                                 isp_prt(isp, ISP_LOGSANCFG,
3559                                     "Chan %d skip PortID 0x%06x",
3560                                     chan, portid);
3561                                 continue;
3562                         }
3563                 } else if (portid == fcp->isp_portid) {
3564                         isp_prt(isp, ISP_LOGSANCFG,
3565                             "Chan %d skip ourselves on @ PortID 0x%06x",
3566                             chan, portid);
3567                         continue;
3568                 }
3569
3570                 isp_prt(isp, ISP_LOGSANCFG,
3571                     "Chan %d Checking Fabric Port 0x%06x", chan, portid);
3572
3573                 /*
3574                  * We now search our Port Database for any
3575                  * probational entries with this PortID. We don't
3576                  * look for zombies here- only probational
3577                  * entries (we've already logged out of zombies).
3578                  */
3579                 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
3580                         lp = &fcp->portdb[dbidx];
3581
3582                         if (lp->state != FC_PORTDB_STATE_PROBATIONAL ||
3583                             lp->target_mode) {
3584                                 continue;
3585                         }
3586                         if (lp->portid == portid) {
3587                                 break;
3588                         }
3589                 }
3590
3591                 /*
3592                  * We found a probational entry with this Port ID.
3593                  */
3594                 if (dbidx < MAX_FC_TARG) {
3595                         int handle_changed = 0;
3596
3597                         lp = &fcp->portdb[dbidx];
3598
3599                         /*
3600                          * See if we're still logged into it.
3601                          *
3602                          * If we aren't, mark it as a dead device and
3603                          * leave the new portid in the database entry
3604                          * for somebody further along to decide what to
3605                          * do (policy choice).
3606                          *
3607                          * If we are, check to see if it's the same
3608                          * device still (it should be). If for some
3609                          * reason it isn't, mark it as a changed device
3610                          * and leave the new portid and role in the
3611                          * database entry for somebody further along to
3612                          * decide what to do (policy choice).
3613                          *
3614                          */
3615
3616                         r = isp_getpdb(isp, chan, lp->handle, &pdb, 0);
3617                         if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3618                                 FC_SCRATCH_RELEASE(isp, chan);
3619                                 ISP_MARK_PORTDB(isp, chan, 1);
3620                                 return (-1);
3621                         }
3622                         if (r != 0) {
3623                                 lp->new_portid = portid;
3624                                 lp->state = FC_PORTDB_STATE_DEAD;
3625                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3626                                     "Chan %d Fabric Port 0x%06x is dead",
3627                                     chan, portid);
3628                                 continue;
3629                         }
3630
3631
3632                         /*
3633                          * Check to make sure that handle, portid, WWPN and
3634                          * WWNN agree. If they don't, then the association
3635                          * between this PortID and the stated handle has been
3636                          * broken by the firmware.
3637                          */
3638                         MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3639                         MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3640                         if (pdb.handle != lp->handle ||
3641                             pdb.portid != portid ||
3642                             wwpn != lp->port_wwn ||
3643                             wwnn != lp->node_wwn) {
3644                                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3645                                     fconf, chan, dbidx, pdb.handle, pdb.portid,
3646                                     (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
3647                                     (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
3648                                     lp->handle, portid,
3649                                     (uint32_t) (lp->node_wwn >> 32),
3650                                     (uint32_t) lp->node_wwn,
3651                                     (uint32_t) (lp->port_wwn >> 32),
3652                                     (uint32_t) lp->port_wwn);
3653                                 /*
3654                                  * Try to re-login to this device using a
3655                                  * new handle. If that fails, mark it dead.
3656                                  *
3657                                  * isp_login_device will check for handle and
3658                                  * portid consistency after re-login.
3659                                  *
3660                                  */
3661                                 if (isp_login_device(isp, chan, portid, &pdb,
3662                                     &oldhandle)) {
3663                                         lp->new_portid = portid;
3664                                         lp->state = FC_PORTDB_STATE_DEAD;
3665                                         if (fcp->isp_loopstate !=
3666                                             LOOP_SCANNING_FABRIC) {
3667                                                 FC_SCRATCH_RELEASE(isp, chan);
3668                                                 ISP_MARK_PORTDB(isp, chan, 1);
3669                                                 return (-1);
3670                                         }
3671                                         continue;
3672                                 }
3673                                 if (fcp->isp_loopstate !=
3674                                     LOOP_SCANNING_FABRIC) {
3675                                         FC_SCRATCH_RELEASE(isp, chan);
3676                                         ISP_MARK_PORTDB(isp, chan, 1);
3677                                         return (-1);
3678                                 }
3679                                 FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
3680                                 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3681                                 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3682                                 if (wwpn != lp->port_wwn ||
3683                                     wwnn != lp->node_wwn) {
3684                                         isp_prt(isp, ISP_LOGWARN, "changed WWN"
3685                                             " after relogin");
3686                                         lp->new_portid = portid;
3687                                         lp->state = FC_PORTDB_STATE_DEAD;
3688                                         continue;
3689                                 }
3690
3691                                 lp->handle = pdb.handle;
3692                                 handle_changed++;
3693                         }
3694
3695                         nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
3696
3697                         /*
3698                          * Check to see whether the portid and roles have
3699                          * stayed the same. If they have stayed the same,
3700                          * we believe that this is the same device and it
3701                          * hasn't become disconnected and reconnected, so
3702                          * mark it as pending valid.
3703                          *
3704                          * If they aren't the same, mark the device as a
3705                          * changed device and save the new port id and role
3706                          * and let somebody else decide.
3707                          */
3708
3709                         lp->new_portid = portid;
3710                         lp->new_roles = nr;
3711                         if (pdb.portid != lp->portid || nr != lp->roles ||
3712                             handle_changed) {
3713                                 isp_prt(isp, ISP_LOGSANCFG,
3714                                     "Chan %d Fabric Port 0x%06x changed",
3715                                     chan, portid);
3716                                 lp->state = FC_PORTDB_STATE_CHANGED;
3717                         } else {
3718                                 isp_prt(isp, ISP_LOGSANCFG,
3719                                     "Chan %d Fabric Port 0x%06x "
3720                                     "Now Pending Valid", chan, portid);
3721                                 lp->state = FC_PORTDB_STATE_PENDING_VALID;
3722                         }
3723                         continue;
3724                 }
3725
3726                 /*
3727                  * Ah- a new entry. Search the database again for all non-NIL
3728                  * entries to make sure we never ever make a new database entry
3729                  * with the same port id. While we're at it, mark where the
3730                  * last free entry was.
3731                  */
3732
3733                 dbidx = MAX_FC_TARG;
3734                 for (lp = fcp->portdb; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
3735                         if (lp >= &fcp->portdb[FL_ID] &&
3736                             lp <= &fcp->portdb[SNS_ID]) {
3737                                 continue;
3738                         }
3739                         /*
3740                          * Skip any target mode entries.
3741                          */
3742                         if (lp->target_mode) {
3743                                 continue;
3744                         }
3745                         if (lp->state == FC_PORTDB_STATE_NIL) {
3746                                 if (dbidx == MAX_FC_TARG) {
3747                                         dbidx = lp - fcp->portdb;
3748                                 }
3749                                 continue;
3750                         }
3751                         if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
3752                                 continue;
3753                         }
3754                         if (lp->portid == portid) {
3755                                 break;
3756                         }
3757                 }
3758
3759                 if (lp < &fcp->portdb[MAX_FC_TARG]) {
3760                         isp_prt(isp, ISP_LOGWARN, "Chan %d PortID 0x%06x "
3761                             "already at %d handle %d state %d",
3762                             chan, portid, dbidx, lp->handle, lp->state);
3763                         continue;
3764                 }
3765
3766                 /*
3767                  * We should have the index of the first free entry seen.
3768                  */
3769                 if (dbidx == MAX_FC_TARG) {
3770                         isp_prt(isp, ISP_LOGERR,
3771                             "port database too small to login PortID 0x%06x"
3772                             "- increase MAX_FC_TARG", portid);
3773                         continue;
3774                 }
3775
3776                 /*
3777                  * Otherwise, point to our new home.
3778                  */
3779                 lp = &fcp->portdb[dbidx];
3780
3781                 /*
3782                  * Try to see if we are logged into this device,
3783                  * and maybe log into it.
3784                  *
3785                  * isp_login_device will check for handle and
3786                  * portid consistency after login.
3787                  */
3788                 if (isp_login_device(isp, chan, portid, &pdb, &oldhandle)) {
3789                         if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3790                                 FC_SCRATCH_RELEASE(isp, chan);
3791                                 ISP_MARK_PORTDB(isp, chan, 1);
3792                                 return (-1);
3793                         }
3794                         continue;
3795                 }
3796                 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3797                         FC_SCRATCH_RELEASE(isp, chan);
3798                         ISP_MARK_PORTDB(isp, chan, 1);
3799                         return (-1);
3800                 }
3801                 FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
3802
3803                 handle = pdb.handle;
3804                 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3805                 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3806                 nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
3807
3808                 /*
3809                  * And go through the database *one* more time to make sure
3810                  * that we do not make more than one entry that has the same
3811                  * WWNN/WWPN duple
3812                  */
3813                 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
3814                         if (dbidx >= FL_ID && dbidx <= SNS_ID) {
3815                                 continue;
3816                         }
3817                         if (fcp->portdb[dbidx].target_mode) {
3818                                 continue;
3819                         }
3820                         if (fcp->portdb[dbidx].node_wwn == wwnn &&
3821                             fcp->portdb[dbidx].port_wwn == wwpn) {
3822                                 break;
3823                         }
3824                 }
3825
3826                 if (dbidx == MAX_FC_TARG) {
3827                         ISP_MEMZERO(lp, sizeof (fcportdb_t));
3828                         lp->handle = handle;
3829                         lp->node_wwn = wwnn;
3830                         lp->port_wwn = wwpn;
3831                         lp->new_portid = portid;
3832                         lp->new_roles = nr;
3833                         lp->state = FC_PORTDB_STATE_NEW;
3834                         isp_prt(isp, ISP_LOGSANCFG,
3835                             "Chan %d Fabric Port 0x%06x is a New Entry",
3836                             chan, portid);
3837                         continue;
3838                 }
3839
3840                 if (fcp->portdb[dbidx].state != FC_PORTDB_STATE_ZOMBIE) {
3841                         isp_prt(isp, ISP_LOGWARN,
3842                             "Chan %d PortID 0x%x 0x%08x%08x/0x%08x%08x %ld "
3843                             "already at idx %d, state 0x%x", chan, portid,
3844                             (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
3845                             (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
3846                             (long) (lp - fcp->portdb), dbidx,
3847                             fcp->portdb[dbidx].state);
3848                         continue;
3849                 }
3850
3851                 /*
3852                  * We found a zombie entry that matches us.
3853                  * Revive it. We know that WWN and WWPN
3854                  * are the same. For fabric devices, we
3855                  * don't care that handle is different
3856                  * as we assign that. If role or portid
3857                  * are different, it maybe a changed device.
3858                  */
3859                 lp = &fcp->portdb[dbidx];
3860                 lp->handle = handle;
3861                 lp->new_portid = portid;
3862                 lp->new_roles = nr;
3863                 if (lp->portid != portid || lp->roles != nr) {
3864                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3865                             "Chan %d Zombie Fabric Port 0x%06x Now Changed",
3866                             chan, portid);
3867                         lp->state = FC_PORTDB_STATE_CHANGED;
3868                 } else {
3869                         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3870                             "Chan %d Zombie Fabric Port 0x%06x "
3871                             "Now Pending Valid", chan, portid);
3872                         lp->state = FC_PORTDB_STATE_PENDING_VALID;
3873                 }
3874         }
3875
3876         FC_SCRATCH_RELEASE(isp, chan);
3877         if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3878                 ISP_MARK_PORTDB(isp, chan, 1);
3879                 return (-1);
3880         }
3881         fcp->isp_loopstate = LOOP_FSCAN_DONE;
3882         isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3883             "Chan %d FC Scan Fabric Done", chan);
3884         return (0);
3885 }
3886
3887 /*
3888  * Find an unused handle and try and use to login to a port.
3889  */
3890 static int
3891 isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
3892 {
3893         int lim, i, r;
3894         uint16_t handle;
3895
3896         if (ISP_CAP_2KLOGIN(isp)) {
3897                 lim = NPH_MAX_2K;
3898         } else {
3899                 lim = NPH_MAX;
3900         }
3901
3902         handle = isp_nxt_handle(isp, chan, *ohp);
3903         for (i = 0; i < lim; i++) {
3904                 /*
3905                  * See if we're still logged into something with
3906                  * this handle and that something agrees with this
3907                  * port id.
3908                  */
3909                 r = isp_getpdb(isp, chan, handle, p, 0);
3910                 if (r == 0 && p->portid != portid) {
3911                         (void) isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1);
3912                 } else if (r == 0) {
3913                         break;
3914                 }
3915                 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3916                         return (-1);
3917                 }
3918                 /*
3919                  * Now try and log into the device
3920                  */
3921                 r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
3922                 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3923                         return (-1);
3924                 }
3925                 if (r == 0) {
3926                         *ohp = handle;
3927                         break;
3928                 } else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
3929                         /*
3930                          * If we get here, then the firmwware still thinks we're logged into this device, but with a different
3931                          * handle. We need to break that association. We used to try and just substitute the handle, but then
3932                          * failed to get any data via isp_getpdb (below).
3933                          */
3934                         if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1)) {
3935                                 isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16);
3936                         }
3937                         if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3938                                 return (-1);
3939                         }
3940                         r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
3941                         if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3942                                 return (-1);
3943                         }
3944                         if (r == 0) {
3945                                 *ohp = handle;
3946                         } else {
3947                                 i = lim;
3948                         }
3949                         break;
3950                 } else if ((r & 0xffff) == MBOX_LOOP_ID_USED) {
3951                         /*
3952                          * Try the next loop id.
3953                          */
3954                         *ohp = handle;
3955                         handle = isp_nxt_handle(isp, chan, handle);
3956                 } else {
3957                         /*
3958                          * Give up.
3959                          */
3960                         i = lim;
3961                         break;
3962                 }
3963         }
3964
3965         if (i == lim) {
3966                 isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid);
3967                 return (-1);
3968         }
3969
3970         /*
3971          * If we successfully logged into it, get the PDB for it
3972          * so we can crosscheck that it is still what we think it
3973          * is and that we also have the role it plays
3974          */
3975         r = isp_getpdb(isp, chan, handle, p, 0);
3976         if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3977                 return (-1);
3978         }
3979         if (r != 0) {
3980                 isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
3981                 return (-1);
3982         }
3983
3984         if (p->handle != handle || p->portid != portid) {
3985                 isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
3986                     chan, portid, handle, p->portid, p->handle);
3987                 return (-1);
3988         }
3989         return (0);
3990 }
3991
3992 static int
3993 isp_register_fc4_type(ispsoftc_t *isp, int chan)
3994 {
3995         fcparam *fcp = FCPARAM(isp, chan);
3996         uint8_t local[SNS_RFT_ID_REQ_SIZE];
3997         sns_screq_t *reqp = (sns_screq_t *) local;
3998         mbreg_t mbs;
3999
4000         ISP_MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
4001         reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
4002         reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
4003         reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
4004         reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
4005         reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
4006         reqp->snscb_sblen = 22;
4007         reqp->snscb_data[0] = SNS_RFT_ID;
4008         reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
4009         reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
4010         reqp->snscb_data[6] = (1 << FC4_SCSI);
4011         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4012                 isp_prt(isp, ISP_LOGERR, sacq);
4013                 return (-1);
4014         }
4015         isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
4016         MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 1000000);
4017         mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
4018         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4019         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4020         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4021         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4022         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE, chan);
4023         isp_mboxcmd(isp, &mbs);
4024         FC_SCRATCH_RELEASE(isp, chan);
4025         if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
4026                 return (0);
4027         } else {
4028                 return (-1);
4029         }
4030 }
4031
4032 static int
4033 isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
4034 {
4035         mbreg_t mbs;
4036         fcparam *fcp = FCPARAM(isp, chan);
4037         union {
4038                 isp_ct_pt_t plocal;
4039                 rft_id_t clocal;
4040                 uint8_t q[QENTRY_LEN];
4041         } un;
4042         isp_ct_pt_t *pt;
4043         ct_hdr_t *ct;
4044         rft_id_t *rp;
4045         uint8_t *scp = fcp->isp_scratch;
4046
4047         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4048                 isp_prt(isp, ISP_LOGERR, sacq);
4049                 return (-1);
4050         }
4051
4052         /*
4053          * Build a Passthrough IOCB in memory.
4054          */
4055         ISP_MEMZERO(un.q, QENTRY_LEN);
4056         pt = &un.plocal;
4057         pt->ctp_header.rqs_entry_count = 1;
4058         pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
4059         pt->ctp_handle = 0xffffffff;
4060         pt->ctp_nphdl = fcp->isp_sns_hdl;
4061         pt->ctp_cmd_cnt = 1;
4062         pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
4063         pt->ctp_time = 1;
4064         pt->ctp_rsp_cnt = 1;
4065         pt->ctp_rsp_bcnt = sizeof (ct_hdr_t);
4066         pt->ctp_cmd_bcnt = sizeof (rft_id_t);
4067         pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
4068         pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
4069         pt->ctp_dataseg[0].ds_count = sizeof (rft_id_t);
4070         pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
4071         pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
4072         pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t);
4073         isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
4074         if (isp->isp_dblev & ISP_LOGDEBUG1) {
4075                 isp_print_bytes(isp, "IOCB CT Request", QENTRY_LEN, pt);
4076         }
4077
4078         /*
4079          * Build the CT header and command in memory.
4080          *
4081          * Note that the CT header has to end up as Big Endian format in memory.
4082          */
4083         ISP_MEMZERO(&un.clocal, sizeof (un.clocal));
4084         ct = &un.clocal.rftid_hdr;
4085         ct->ct_revision = CT_REVISION;
4086         ct->ct_fcs_type = CT_FC_TYPE_FC;
4087         ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
4088         ct->ct_cmd_resp = SNS_RFT_ID;
4089         ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
4090         rp = &un.clocal;
4091         rp->rftid_portid[0] = fcp->isp_portid >> 16;
4092         rp->rftid_portid[1] = fcp->isp_portid >> 8;
4093         rp->rftid_portid[2] = fcp->isp_portid;
4094         rp->rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
4095         isp_put_rft_id(isp, rp, (rft_id_t *) &scp[XTXOFF]);
4096         if (isp->isp_dblev & ISP_LOGDEBUG1) {
4097                 isp_print_bytes(isp, "CT Header", QENTRY_LEN, &scp[XTXOFF]);
4098         }
4099
4100         ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
4101
4102         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 1000000);
4103         mbs.param[1] = QENTRY_LEN;
4104         mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
4105         mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
4106         mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
4107         mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
4108         MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN, chan);
4109         isp_mboxcmd(isp, &mbs);
4110         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4111                 FC_SCRATCH_RELEASE(isp, chan);
4112                 return (-1);
4113         }
4114         MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN, chan);
4115         pt = &un.plocal;
4116         isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
4117         if (isp->isp_dblev & ISP_LOGDEBUG1) {
4118                 isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
4119         }
4120         if (pt->ctp_status) {
4121                 FC_SCRATCH_RELEASE(isp, chan);
4122                 isp_prt(isp, ISP_LOGWARN,
4123                     "Chan %d Register FC4 Type CT Passthrough returned 0x%x",
4124                     chan, pt->ctp_status);
4125                 return (1);
4126         }
4127
4128         isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct);
4129         FC_SCRATCH_RELEASE(isp, chan);
4130
4131         if (ct->ct_cmd_resp == LS_RJT) {
4132                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
4133                     "Chan %d Register FC4 Type rejected", chan);
4134                 return (-1);
4135         } else if (ct->ct_cmd_resp == LS_ACC) {
4136                 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
4137                     "Chan %d Register FC4 Type accepted", chan);
4138                 return (0);
4139         } else {
4140                 isp_prt(isp, ISP_LOGWARN,
4141                     "Chan %d Register FC4 Type: 0x%x",
4142                     chan, ct->ct_cmd_resp);
4143                 return (-1);
4144         }
4145 }
4146
4147 static uint16_t
4148 isp_nxt_handle(ispsoftc_t *isp, int chan, uint16_t handle)
4149 {
4150         int i;
4151         if (handle == NIL_HANDLE) {
4152                 if (FCPARAM(isp, chan)->isp_topo == TOPO_F_PORT) {
4153                         handle = 0;
4154                 } else {
4155                         handle = SNS_ID+1;
4156                 }
4157         } else {
4158                 handle += 1;
4159                 if (handle >= FL_ID && handle <= SNS_ID) {
4160                         handle = SNS_ID+1;
4161                 }
4162                 if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
4163                         handle = NPH_FL_ID+1;
4164                 }
4165                 if (ISP_CAP_2KLOGIN(isp)) {
4166                         if (handle == NPH_MAX_2K) {
4167                                 handle = 0;
4168                         }
4169                 } else {
4170                         if (handle == NPH_MAX) {
4171                                 handle = 0;
4172                         }
4173                 }
4174         }
4175         if (handle == FCPARAM(isp, chan)->isp_loopid) {
4176                 return (isp_nxt_handle(isp, chan, handle));
4177         }
4178         for (i = 0; i < MAX_FC_TARG; i++) {
4179                 if (FCPARAM(isp, chan)->portdb[i].state ==
4180                     FC_PORTDB_STATE_NIL) {
4181                         continue;
4182                 }
4183                 if (FCPARAM(isp, chan)->portdb[i].handle == handle) {
4184                         return (isp_nxt_handle(isp, chan, handle));
4185                 }
4186         }
4187         return (handle);
4188 }
4189
4190 /*
4191  * Start a command. Locking is assumed done in the caller.
4192  */
4193
4194 int
4195 isp_start(XS_T *xs)
4196 {
4197         ispsoftc_t *isp;
4198         uint32_t handle, cdblen;
4199         uint8_t local[QENTRY_LEN];
4200         ispreq_t *reqp;
4201         void *cdbp, *qep;
4202         uint16_t *tptr;
4203         int target, dmaresult, hdlidx = 0;
4204
4205         XS_INITERR(xs);
4206         isp = XS_ISP(xs);
4207
4208         /*
4209          * Now make sure we're running.
4210          */
4211
4212         if (isp->isp_state != ISP_RUNSTATE) {
4213                 isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
4214                 XS_SETERR(xs, HBA_BOTCH);
4215                 return (CMD_COMPLETE);
4216         }
4217
4218         /*
4219          * Check command CDB length, etc.. We really are limited to 16 bytes
4220          * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
4221          * but probably only if we're running fairly new firmware (we'll
4222          * let the old f/w choke on an extended command queue entry).
4223          */
4224
4225         if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
4226                 isp_prt(isp, ISP_LOGERR, "unsupported cdb length (%d, CDB[0]=0x%x)", XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
4227                 XS_SETERR(xs, HBA_BOTCH);
4228                 return (CMD_COMPLETE);
4229         }
4230
4231         /*
4232          * Translate the target to device handle as appropriate, checking
4233          * for correct device state as well.
4234          */
4235         target = XS_TGT(xs);
4236         if (IS_FC(isp)) {
4237                 fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
4238
4239                 if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
4240                         XS_SETERR(xs, HBA_SELTIMEOUT);
4241                         return (CMD_COMPLETE);
4242                 }
4243
4244                 /*
4245                  * Try again later.
4246                  */
4247                 if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate != LOOP_READY) {
4248                         return (CMD_RQLATER);
4249                 }
4250
4251                 if (XS_TGT(xs) >= MAX_FC_TARG) {
4252                         XS_SETERR(xs, HBA_SELTIMEOUT);
4253                         return (CMD_COMPLETE);
4254                 }
4255
4256                 hdlidx = fcp->isp_dev_map[XS_TGT(xs)] - 1;
4257                 isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d- hdlidx value %d", XS_TGT(xs), hdlidx);
4258                 if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4259                         XS_SETERR(xs, HBA_SELTIMEOUT);
4260                         return (CMD_COMPLETE);
4261                 }
4262                 if (fcp->portdb[hdlidx].state == FC_PORTDB_STATE_ZOMBIE) {
4263                         return (CMD_RQLATER);
4264                 }
4265                 if (fcp->portdb[hdlidx].state != FC_PORTDB_STATE_VALID) {
4266                         XS_SETERR(xs, HBA_SELTIMEOUT);
4267                         return (CMD_COMPLETE);
4268                 }
4269                 target = fcp->portdb[hdlidx].handle;
4270                 fcp->portdb[hdlidx].dirty = 1;
4271         } else {
4272                 sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
4273                 if ((sdp->role & ISP_ROLE_INITIATOR) == 0) {
4274                         XS_SETERR(xs, HBA_SELTIMEOUT);
4275                         return (CMD_COMPLETE);
4276                 }
4277                 if (sdp->update) {
4278                         isp_spi_update(isp, XS_CHANNEL(xs));
4279                 }
4280         }
4281
4282  start_again:
4283
4284         qep = isp_getrqentry(isp);
4285         if (qep == NULL) {
4286                 isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
4287                 XS_SETERR(xs, HBA_BOTCH);
4288                 return (CMD_EAGAIN);
4289         }
4290         XS_SETERR(xs, HBA_NOERROR);
4291
4292         /*
4293          * Now see if we need to synchronize the ISP with respect to anything.
4294          * We do dual duty here (cough) for synchronizing for busses other
4295          * than which we got here to send a command to.
4296          */
4297         reqp = (ispreq_t *) local;
4298         ISP_MEMZERO(local, QENTRY_LEN);
4299         if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) {
4300                 if (IS_24XX(isp)) {
4301                         isp_marker_24xx_t *m = (isp_marker_24xx_t *) reqp;
4302                         m->mrk_header.rqs_entry_count = 1;
4303                         m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
4304                         m->mrk_modifier = SYNC_ALL;
4305                         isp_put_marker_24xx(isp, m, qep);
4306                 } else {
4307                         isp_marker_t *m = (isp_marker_t *) reqp;
4308                         m->mrk_header.rqs_entry_count = 1;
4309                         m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
4310                         m->mrk_target = (XS_CHANNEL(xs) << 7);  /* bus # */
4311                         m->mrk_modifier = SYNC_ALL;
4312                         isp_put_marker(isp, m, qep);
4313                 }
4314                 ISP_SYNC_REQUEST(isp);
4315                 ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0);
4316                 goto start_again;
4317         }
4318
4319         reqp->req_header.rqs_entry_count = 1;
4320         if (IS_24XX(isp)) {
4321                 reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
4322         } else if (IS_FC(isp)) {
4323                 reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
4324         } else {
4325                 if (XS_CDBLEN(xs) > 12) {
4326                         reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
4327                 } else {
4328                         reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
4329                 }
4330         }
4331
4332         if (IS_24XX(isp)) {
4333                 int ttype;
4334                 if (XS_TAG_P(xs)) {
4335                         ttype = XS_TAG_TYPE(xs);
4336                 } else {
4337                         if (XS_CDBP(xs)[0] == 0x3) {
4338                                 ttype = REQFLAG_HTAG;
4339                         } else {
4340                                 ttype = REQFLAG_STAG;
4341                         }
4342                 }
4343                 if (ttype == REQFLAG_OTAG) {
4344                         ttype = FCP_CMND_TASK_ATTR_ORDERED;
4345                 } else if (ttype == REQFLAG_HTAG) {
4346                         ttype = FCP_CMND_TASK_ATTR_HEAD;
4347                 } else {
4348                         ttype = FCP_CMND_TASK_ATTR_SIMPLE;
4349                 }
4350                 ((ispreqt7_t *)reqp)->req_task_attribute = ttype;
4351         } else if (IS_FC(isp)) {
4352                 /*
4353                  * See comment in isp_intr
4354                  */
4355                 /* XS_SET_RESID(xs, 0); */
4356
4357                 /*
4358                  * Fibre Channel always requires some kind of tag.
4359                  * The Qlogic drivers seem be happy not to use a tag,
4360                  * but this breaks for some devices (IBM drives).
4361                  */
4362                 if (XS_TAG_P(xs)) {
4363                         ((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
4364                 } else {
4365                         /*
4366                          * If we don't know what tag to use, use HEAD OF QUEUE
4367                          * for Request Sense or Simple.
4368                          */
4369                         if (XS_CDBP(xs)[0] == 0x3)      /* REQUEST SENSE */
4370                                 ((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
4371                         else
4372                                 ((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
4373                 }
4374         } else {
4375                 sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
4376                 if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) && XS_TAG_P(xs)) {
4377                         reqp->req_flags = XS_TAG_TYPE(xs);
4378                 }
4379         }
4380
4381         tptr = &reqp->req_time;
4382
4383         /*
4384          * NB: we do not support long CDBs
4385          */
4386         cdblen = XS_CDBLEN(xs);
4387
4388         if (IS_SCSI(isp)) {
4389                 reqp->req_target = target | (XS_CHANNEL(xs) << 7);
4390                 reqp->req_lun_trn = XS_LUN(xs);
4391                 cdblen = ISP_MIN(cdblen, sizeof (reqp->req_cdb));
4392                 cdbp = reqp->req_cdb;
4393                 reqp->req_cdblen = cdblen;
4394         } else if (IS_24XX(isp)) {
4395                 ispreqt7_t *t7 = (ispreqt7_t *)local;
4396                 fcportdb_t *lp;
4397
4398                 lp = &FCPARAM(isp, XS_CHANNEL(xs))->portdb[hdlidx];
4399                 t7->req_nphdl = target;
4400                 t7->req_tidlo = lp->portid;
4401                 t7->req_tidhi = lp->portid >> 16;
4402                 t7->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs));
4403                 if (XS_LUN(xs) > 256) {
4404                         t7->req_lun[0] = XS_LUN(xs) >> 8;
4405                         t7->req_lun[0] |= 0x40;
4406                 }
4407                 t7->req_lun[1] = XS_LUN(xs);
4408                 tptr = &t7->req_time;
4409                 cdbp = t7->req_cdb;
4410                 cdblen = ISP_MIN(cdblen, sizeof (t7->req_cdb));
4411         } else if (ISP_CAP_2KLOGIN(isp)) {
4412                 ispreqt2e_t *t2e = (ispreqt2e_t *)local;
4413                 t2e->req_target = target;
4414                 t2e->req_scclun = XS_LUN(xs);
4415                 cdbp = t2e->req_cdb;
4416                 cdblen = ISP_MIN(cdblen, sizeof (t2e->req_cdb));
4417         } else if (ISP_CAP_SCCFW(isp)) {
4418                 ispreqt2_t *t2 = (ispreqt2_t *)local;
4419                 t2->req_target = target;
4420                 t2->req_scclun = XS_LUN(xs);
4421                 cdbp = t2->req_cdb;
4422                 cdblen = ISP_MIN(cdblen, sizeof (t2->req_cdb));
4423         } else {
4424                 ispreqt2_t *t2 = (ispreqt2_t *)local;
4425                 t2->req_target = target;
4426                 t2->req_lun_trn = XS_LUN(xs);
4427                 cdbp = t2->req_cdb;
4428                 cdblen = ISP_MIN(cdblen, sizeof (t2->req_cdb));
4429         }
4430         ISP_MEMCPY(cdbp, XS_CDBP(xs), cdblen);
4431
4432         *tptr = XS_TIME(xs) / 1000;
4433         if (*tptr == 0 && XS_TIME(xs)) {
4434                 *tptr = 1;
4435         }
4436         if (IS_24XX(isp) && *tptr > 0x1999) {
4437                 *tptr = 0x1999;
4438         }
4439
4440         if (isp_allocate_xs(isp, xs, &handle)) {
4441                 isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
4442                 XS_SETERR(xs, HBA_BOTCH);
4443                 return (CMD_EAGAIN);
4444         }
4445         /* Whew. Thankfully the same for type 7 requests */
4446         reqp->req_handle = handle;
4447
4448         /*
4449          * Set up DMA and/or do any platform dependent swizzling of the request entry
4450          * so that the Qlogic F/W understands what is being asked of it.
4451          *
4452          * The callee is responsible for adding all requests at this point.
4453          */
4454         dmaresult = ISP_DMASETUP(isp, xs, reqp);
4455         if (dmaresult != CMD_QUEUED) {
4456                 isp_destroy_handle(isp, handle);
4457                 /*
4458                  * dmasetup sets actual error in packet, and
4459                  * return what we were given to return.
4460                  */
4461                 return (dmaresult);
4462         }
4463         isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "START cmd cdb[0]=0x%x datalen %ld", XS_CDBP(xs)[0], (long) XS_XFRLEN(xs));
4464         isp->isp_nactive++;
4465         return (CMD_QUEUED);
4466 }
4467
4468 /*
4469  * isp control
4470  * Locks (ints blocked) assumed held.
4471  */
4472
4473 int
4474 isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
4475 {
4476         XS_T *xs;
4477         mbreg_t *mbr, mbs;
4478         int chan, tgt;
4479         uint32_t handle;
4480         __va_list ap;
4481
4482         switch (ctl) {
4483         case ISPCTL_RESET_BUS:
4484                 /*
4485                  * Issue a bus reset.
4486                  */
4487                 if (IS_24XX(isp)) {
4488                         isp_prt(isp, ISP_LOGWARN, "RESET BUS NOT IMPLEMENTED");
4489                         break;
4490                 } else if (IS_FC(isp)) {
4491                         mbs.param[1] = 10;
4492                         chan = 0;
4493                 } else {
4494                         __va_start(ap, ctl);
4495                         chan = __va_arg(ap, int);
4496                         __va_end(ap);
4497                         mbs.param[1] = SDPARAM(isp, chan)->isp_bus_reset_delay;
4498                         if (mbs.param[1] < 2) {
4499                                 mbs.param[1] = 2;
4500                         }
4501                         mbs.param[2] = chan;
4502                 }
4503                 MBSINIT(&mbs, MBOX_BUS_RESET, MBLOGALL, 0);
4504                 ISP_SET_SENDMARKER(isp, chan, 1);
4505                 isp_mboxcmd(isp, &mbs);
4506                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4507                         break;
4508                 }
4509                 isp_prt(isp, ISP_LOGINFO,
4510                     "driver initiated bus reset of bus %d", chan);
4511                 return (0);
4512
4513         case ISPCTL_RESET_DEV:
4514                 __va_start(ap, ctl);
4515                 chan = __va_arg(ap, int);
4516                 tgt = __va_arg(ap, int);
4517                 __va_end(ap);
4518                 if (IS_24XX(isp)) {
4519                         uint8_t local[QENTRY_LEN];
4520                         isp24xx_tmf_t *tmf;
4521                         isp24xx_statusreq_t *sp;
4522                         fcparam *fcp = FCPARAM(isp, chan);
4523                         fcportdb_t *lp;
4524                         int hdlidx;
4525
4526                         hdlidx = fcp->isp_dev_map[tgt] - 1;
4527                         if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4528                                 isp_prt(isp, ISP_LOGWARN,
4529                                     "Chan %d bad handle %d trying to reset"
4530                                     "target %d", chan, hdlidx, tgt);
4531                                 break;
4532                         }
4533                         lp = &fcp->portdb[hdlidx];
4534                         if (lp->state != FC_PORTDB_STATE_VALID) {
4535                                 isp_prt(isp, ISP_LOGWARN,
4536                                     "Chan %d handle %d for abort of target %d "
4537                                     "no longer valid", chan,
4538                                     hdlidx, tgt);
4539                                 break;
4540                         }
4541
4542                         tmf = (isp24xx_tmf_t *) local;
4543                         ISP_MEMZERO(tmf, QENTRY_LEN);
4544                         tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
4545                         tmf->tmf_header.rqs_entry_count = 1;
4546                         tmf->tmf_nphdl = lp->handle;
4547                         tmf->tmf_delay = 2;
4548                         tmf->tmf_timeout = 2;
4549                         tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
4550                         tmf->tmf_tidlo = lp->portid;
4551                         tmf->tmf_tidhi = lp->portid >> 16;
4552                         tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
4553                         isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
4554                         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
4555                         mbs.param[1] = QENTRY_LEN;
4556                         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4557                         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4558                         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4559                         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4560
4561                         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4562                                 isp_prt(isp, ISP_LOGERR, sacq);
4563                                 break;
4564                         }
4565                         isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch);
4566                         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN, chan);
4567                         fcp->sendmarker = 1;
4568                         isp_mboxcmd(isp, &mbs);
4569                         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4570                                 FC_SCRATCH_RELEASE(isp, chan);
4571                                 break;
4572                         }
4573                         MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
4574                             QENTRY_LEN, chan);
4575                         sp = (isp24xx_statusreq_t *) local;
4576                         isp_get_24xx_response(isp,
4577                             &((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp);
4578                         FC_SCRATCH_RELEASE(isp, chan);
4579                         if (sp->req_completion_status == 0) {
4580                                 return (0);
4581                         }
4582                         isp_prt(isp, ISP_LOGWARN,
4583                             "Chan %d reset of target %d returned 0x%x",
4584                             chan, tgt, sp->req_completion_status);
4585                         break;
4586                 } else if (IS_FC(isp)) {
4587                         if (ISP_CAP_2KLOGIN(isp)) {
4588                                 mbs.param[1] = tgt;
4589                                 mbs.ibits = (1 << 10);
4590                         } else {
4591                                 mbs.param[1] = (tgt << 8);
4592                         }
4593                 } else {
4594                         mbs.param[1] = (chan << 15) | (tgt << 8);
4595                 }
4596                 MBSINIT(&mbs, MBOX_ABORT_TARGET, MBLOGALL, 0);
4597                 mbs.param[2] = 3;       /* 'delay', in seconds */
4598                 isp_mboxcmd(isp, &mbs);
4599                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4600                         break;
4601                 }
4602                 isp_prt(isp, ISP_LOGINFO,
4603                     "Target %d on Bus %d Reset Succeeded", tgt, chan);
4604                 ISP_SET_SENDMARKER(isp, chan, 1);
4605                 return (0);
4606
4607         case ISPCTL_ABORT_CMD:
4608                 __va_start(ap, ctl);
4609                 xs = __va_arg(ap, XS_T *);
4610                 __va_end(ap);
4611
4612                 tgt = XS_TGT(xs);
4613                 chan = XS_CHANNEL(xs);
4614
4615                 handle = isp_find_handle(isp, xs);
4616                 if (handle == 0) {
4617                         isp_prt(isp, ISP_LOGWARN,
4618                             "cannot find handle for command to abort");
4619                         break;
4620                 }
4621                 if (IS_24XX(isp)) {
4622                         isp24xx_abrt_t local, *ab = &local, *ab2;
4623                         fcparam *fcp;
4624                         fcportdb_t *lp;
4625                         int hdlidx;
4626
4627                         fcp = FCPARAM(isp, chan);
4628                         hdlidx = fcp->isp_dev_map[tgt] - 1;
4629                         if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4630                                 isp_prt(isp, ISP_LOGWARN,
4631                                     "Chan %d bad handle %d trying to abort"
4632                                     "target %d", chan, hdlidx, tgt);
4633                                 break;
4634                         }
4635                         lp = &fcp->portdb[hdlidx];
4636                         if (lp->state != FC_PORTDB_STATE_VALID) {
4637                                 isp_prt(isp, ISP_LOGWARN,
4638                                     "Chan %d handle %d for abort of target %d "
4639                                     "no longer valid", chan, hdlidx, tgt);
4640                                 break;
4641                         }
4642                         isp_prt(isp, ISP_LOGALL,
4643                             "Chan %d Abort Cmd for N-Port 0x%04x @ Port "
4644                             "0x%06x %p", chan, lp->handle, lp->portid, xs);
4645                         ISP_MEMZERO(ab, QENTRY_LEN);
4646                         ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
4647                         ab->abrt_header.rqs_entry_count = 1;
4648                         ab->abrt_handle = lp->handle;
4649                         ab->abrt_cmd_handle = handle;
4650                         ab->abrt_tidlo = lp->portid;
4651                         ab->abrt_tidhi = lp->portid >> 16;
4652                         ab->abrt_vpidx = ISP_GET_VPIDX(isp, chan);
4653
4654                         ISP_MEMZERO(&mbs, sizeof (mbs));
4655                         MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
4656                         mbs.param[1] = QENTRY_LEN;
4657                         mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4658                         mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4659                         mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4660                         mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4661
4662                         if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4663                                 isp_prt(isp, ISP_LOGERR, sacq);
4664                                 break;
4665                         }
4666                         isp_put_24xx_abrt(isp, ab, fcp->isp_scratch);
4667                         ab2 = (isp24xx_abrt_t *)
4668                             &((uint8_t *)fcp->isp_scratch)[QENTRY_LEN];
4669                         ab2->abrt_nphdl = 0xdeaf;
4670                         MEMORYBARRIER(isp, SYNC_SFORDEV, 0, 2 * QENTRY_LEN, chan);
4671                         isp_mboxcmd(isp, &mbs);
4672                         if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4673                                 FC_SCRATCH_RELEASE(isp, chan);
4674                                 break;
4675                         }
4676                         MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
4677                             QENTRY_LEN, chan);
4678                         isp_get_24xx_abrt(isp, ab2, ab);
4679                         FC_SCRATCH_RELEASE(isp, chan);
4680                         if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY) {
4681                                 return (0);
4682                         }
4683                         isp_prt(isp, ISP_LOGWARN,
4684                             "Chan %d handle %d abort returned 0x%x", chan,
4685                             hdlidx, ab->abrt_nphdl);
4686                         break;
4687                 } else if (IS_FC(isp)) {
4688                         if (ISP_CAP_SCCFW(isp)) {
4689                                 if (ISP_CAP_2KLOGIN(isp)) {
4690                                         mbs.param[1] = tgt;
4691                                 } else {
4692                                         mbs.param[1] = tgt << 8;
4693                                 }
4694                                 mbs.param[6] = XS_LUN(xs);
4695                         } else {
4696                                 mbs.param[1] = tgt << 8 | XS_LUN(xs);
4697                         }
4698                 } else {
4699                         mbs.param[1] = (chan << 15) | (tgt << 8) | XS_LUN(xs);
4700                 }
4701                 MBSINIT(&mbs, MBOX_ABORT, MBLOGALL & ~MBOX_COMMAND_ERROR, 0);
4702                 mbs.param[2] = handle;
4703                 isp_mboxcmd(isp, &mbs);
4704                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4705                         break;
4706                 }
4707                 return (0);
4708
4709         case ISPCTL_UPDATE_PARAMS:
4710
4711                 __va_start(ap, ctl);
4712                 chan = __va_arg(ap, int);
4713                 __va_end(ap);
4714                 isp_spi_update(isp, chan);
4715                 return (0);
4716
4717         case ISPCTL_FCLINK_TEST:
4718
4719                 if (IS_FC(isp)) {
4720                         int usdelay;
4721                         __va_start(ap, ctl);
4722                         chan = __va_arg(ap, int);
4723                         usdelay = __va_arg(ap, int);
4724                         __va_end(ap);
4725                         if (usdelay == 0) {
4726                                 usdelay =  250000;
4727                         }
4728                         return (isp_fclink_test(isp, chan, usdelay));
4729                 }
4730                 break;
4731
4732         case ISPCTL_SCAN_FABRIC:
4733
4734                 if (IS_FC(isp)) {
4735                         __va_start(ap, ctl);
4736                         chan = __va_arg(ap, int);
4737                         __va_end(ap);
4738                         return (isp_scan_fabric(isp, chan));
4739                 }
4740                 break;
4741
4742         case ISPCTL_SCAN_LOOP:
4743
4744                 if (IS_FC(isp)) {
4745                         __va_start(ap, ctl);
4746                         chan = __va_arg(ap, int);
4747                         __va_end(ap);
4748                         return (isp_scan_loop(isp, chan));
4749                 }
4750                 break;
4751
4752         case ISPCTL_PDB_SYNC:
4753
4754                 if (IS_FC(isp)) {
4755                         __va_start(ap, ctl);
4756                         chan = __va_arg(ap, int);
4757                         __va_end(ap);
4758                         return (isp_pdb_sync(isp, chan));
4759                 }
4760                 break;
4761
4762         case ISPCTL_SEND_LIP:
4763
4764                 if (IS_FC(isp) && !IS_24XX(isp)) {
4765                         MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
4766                         if (ISP_CAP_2KLOGIN(isp)) {
4767                                 mbs.ibits = (1 << 10);
4768                         }
4769                         isp_mboxcmd(isp, &mbs);
4770                         if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
4771                                 return (0);
4772                         }
4773                 }
4774                 break;
4775
4776         case ISPCTL_GET_PDB:
4777                 if (IS_FC(isp)) {
4778                         isp_pdb_t *pdb;
4779                         __va_start(ap, ctl);
4780                         chan = __va_arg(ap, int);
4781                         tgt = __va_arg(ap, int);
4782                         pdb = __va_arg(ap, isp_pdb_t *);
4783                         __va_end(ap);
4784                         return (isp_getpdb(isp, chan, tgt, pdb, 1));
4785                 }
4786                 break;
4787
4788         case ISPCTL_GET_NAMES:
4789         {
4790                 uint64_t *wwnn, *wwnp;
4791                 __va_start(ap, ctl);
4792                 chan = __va_arg(ap, int);
4793                 tgt = __va_arg(ap, int);
4794                 wwnn = __va_arg(ap, uint64_t *);
4795                 wwnp = __va_arg(ap, uint64_t *);
4796                 __va_end(ap);
4797                 if (wwnn == NULL && wwnp == NULL) {
4798                         break;
4799                 }
4800                 if (wwnn) {
4801                         *wwnn = isp_get_wwn(isp, chan, tgt, 1);
4802                         if (*wwnn == INI_NONE) {
4803                                 break;
4804                         }
4805                 }
4806                 if (wwnp) {
4807                         *wwnp = isp_get_wwn(isp, chan, tgt, 0);
4808                         if (*wwnp == INI_NONE) {
4809                                 break;
4810                         }
4811                 }
4812                 return (0);
4813         }
4814         case ISPCTL_RUN_MBOXCMD:
4815         {
4816                 __va_start(ap, ctl);
4817                 mbr = __va_arg(ap, mbreg_t *);
4818                 __va_end(ap);
4819                 isp_mboxcmd(isp, mbr);
4820                 return (0);
4821         }
4822         case ISPCTL_PLOGX:
4823         {
4824                 isp_plcmd_t *p;
4825                 int r;
4826
4827                 __va_start(ap, ctl);
4828                 p = __va_arg(ap, isp_plcmd_t *);
4829                 __va_end(ap);
4830
4831                 if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
4832                         return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0));
4833                 }
4834                 do {
4835                         p->handle = isp_nxt_handle(isp, p->channel, p->handle);
4836                         r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0);
4837                         if ((r & 0xffff) == MBOX_PORT_ID_USED) {
4838                                 p->handle = r >> 16;
4839                                 r = 0;
4840                                 break;
4841                         }
4842                 } while ((r & 0xffff) == MBOX_LOOP_ID_USED);
4843                 return (r);
4844         }
4845         default:
4846                 isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
4847                 break;
4848
4849         }
4850         return (-1);
4851 }
4852
4853 /*
4854  * Interrupt Service Routine(s).
4855  *
4856  * External (OS) framework has done the appropriate locking,
4857  * and the locking will be held throughout this function.
4858  */
4859
4860 /*
4861  * Limit our stack depth by sticking with the max likely number
4862  * of completions on a request queue at any one time.
4863  */
4864 #ifndef MAX_REQUESTQ_COMPLETIONS
4865 #define MAX_REQUESTQ_COMPLETIONS        32
4866 #endif
4867
4868 void
4869 isp_intr(ispsoftc_t *isp, uint32_t isr, uint16_t sema, uint16_t mbox)
4870 {
4871         XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
4872         uint32_t iptr, optr, junk;
4873         int i, nlooked = 0, ndone = 0;
4874
4875 again:
4876         optr = isp->isp_residx;
4877         /*
4878          * Is this a mailbox related interrupt?
4879          * The mailbox semaphore will be nonzero if so.
4880          */
4881         if (sema) {
4882  fmbox:
4883                 if (mbox & MBOX_COMMAND_COMPLETE) {
4884                         isp->isp_intmboxc++;
4885                         if (isp->isp_mboxbsy) {
4886                                 int obits = isp->isp_obits;
4887                                 isp->isp_mboxtmp[0] = mbox;
4888                                 for (i = 1; i < MAX_MAILBOX(isp); i++) {
4889                                         if ((obits & (1 << i)) == 0) {
4890                                                 continue;
4891                                         }
4892                                         isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
4893                                 }
4894                                 if (isp->isp_mbxwrk0) {
4895                                         if (isp_mbox_continue(isp) == 0) {
4896                                                 return;
4897                                         }
4898                                 }
4899                                 MBOX_NOTIFY_COMPLETE(isp);
4900                         } else {
4901                                 isp_prt(isp, ISP_LOGWARN, "mailbox cmd (0x%x) with no waiters", mbox);
4902                         }
4903                 } else {
4904                         i = IS_FC(isp)? isp_parse_async_fc(isp, mbox) : isp_parse_async(isp, mbox);
4905                         if (i < 0) {
4906                                 return;
4907                         }
4908                 }
4909                 if ((IS_FC(isp) && mbox != ASYNC_RIOZIO_STALL) || isp->isp_state != ISP_RUNSTATE) {
4910                         goto out;
4911                 }
4912         }
4913
4914         /*
4915          * We can't be getting this now.
4916          */
4917         if (isp->isp_state != ISP_RUNSTATE) {
4918                 /*
4919                  * This seems to happen to 23XX and 24XX cards- don't know why.
4920                  */
4921                  if (isp->isp_mboxbsy && isp->isp_lastmbxcmd == MBOX_ABOUT_FIRMWARE) {
4922                         goto fmbox;
4923                 }
4924                 isp_prt(isp, ISP_LOGINFO, "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
4925                 /*
4926                  * Thank you very much!  *Burrrp*!
4927                  */
4928                 ISP_WRITE(isp, isp->isp_respoutrp, ISP_READ(isp, isp->isp_respinrp));
4929                 if (IS_24XX(isp)) {
4930                         ISP_DISABLE_INTS(isp);
4931                 }
4932                 goto out;
4933         }
4934
4935 #ifdef  ISP_TARGET_MODE
4936         /*
4937          * Check for ATIO Queue entries.
4938          */
4939         if (IS_24XX(isp)) {
4940                 iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
4941                 optr = ISP_READ(isp, BIU2400_ATIO_RSPOUTP);
4942
4943                 while (optr != iptr) {
4944                         uint8_t qe[QENTRY_LEN];
4945                         isphdr_t *hp;
4946                         uint32_t oop;
4947                         void *addr;
4948
4949                         oop = optr;
4950                         MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1);
4951                         addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
4952                         isp_get_hdr(isp, addr, (isphdr_t *)qe);
4953                         hp = (isphdr_t *)qe;
4954                         switch (hp->rqs_entry_type) {
4955                         case RQSTYPE_NOTIFY:
4956                         case RQSTYPE_ATIO:
4957                                 (void) isp_target_notify(isp, addr, &oop);
4958                                 break;
4959                         default:
4960                                 isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
4961                                 break;
4962                         }
4963                         optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
4964                         ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
4965                 }
4966                 optr = isp->isp_residx;
4967         }
4968 #endif
4969
4970         /*
4971          * Get the current Response Queue Out Pointer.
4972          *
4973          * If we're a 2300 or 2400, we can ask what hardware what it thinks.
4974          */
4975         if (IS_23XX(isp) || IS_24XX(isp)) {
4976                 optr = ISP_READ(isp, isp->isp_respoutrp);
4977                 /*
4978                  * Debug: to be taken out eventually
4979                  */
4980                 if (isp->isp_residx != optr) {
4981                         isp_prt(isp, ISP_LOGINFO, "isp_intr: hard optr=%x, soft optr %x", optr, isp->isp_residx);
4982                         isp->isp_residx = optr;
4983                 }
4984         } else {
4985                 optr = isp->isp_residx;
4986         }
4987
4988         /*
4989          * You *must* read the Response Queue In Pointer
4990          * prior to clearing the RISC interrupt.
4991          *
4992          * Debounce the 2300 if revision less than 2.
4993          */
4994         if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
4995                 i = 0;
4996                 do {
4997                         iptr = ISP_READ(isp, isp->isp_respinrp);
4998                         junk = ISP_READ(isp, isp->isp_respinrp);
4999                 } while (junk != iptr && ++i < 1000);
5000
5001                 if (iptr != junk) {
5002                         isp_prt(isp, ISP_LOGWARN, "Response Queue Out Pointer Unstable (%x, %x)", iptr, junk);
5003                         goto out;
5004                 }
5005         } else {
5006                 iptr = ISP_READ(isp, isp->isp_respinrp);
5007         }
5008         isp->isp_resodx = iptr;
5009
5010
5011         if (optr == iptr && sema == 0) {
5012                 /*
5013                  * There are a lot of these- reasons unknown- mostly on
5014                  * faster Alpha machines.
5015                  *
5016                  * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
5017                  * make sure the old interrupt went away (to avoid 'ringing'
5018                  * effects), but that didn't stop this from occurring.
5019                  */
5020                 if (IS_24XX(isp)) {
5021                         junk = 0;
5022                 } else if (IS_23XX(isp)) {
5023                         ISP_DELAY(100);
5024                         iptr = ISP_READ(isp, isp->isp_respinrp);
5025                         junk = ISP_READ(isp, BIU_R2HSTSLO);
5026                 } else {
5027                         junk = ISP_READ(isp, BIU_ISR);
5028                 }
5029                 if (optr == iptr) {
5030                         if (IS_23XX(isp) || IS_24XX(isp)) {
5031                                 ;
5032                         } else {
5033                                 sema = ISP_READ(isp, BIU_SEMA);
5034                                 mbox = ISP_READ(isp, OUTMAILBOX0);
5035                                 if ((sema & 0x3) && (mbox & 0x8000)) {
5036                                         goto again;
5037                                 }
5038                         }
5039                         isp->isp_intbogus++;
5040                         isp_prt(isp, ISP_LOGDEBUG1, "bogus intr- isr %x (%x) iptr %x optr %x", isr, junk, iptr, optr);
5041                 }
5042         }
5043         isp->isp_resodx = iptr;
5044
5045         while (optr != iptr) {
5046                 uint8_t qe[QENTRY_LEN];
5047                 ispstatusreq_t *sp = (ispstatusreq_t *) qe;
5048                 isphdr_t *hp;
5049                 int buddaboom, etype, scsi_status, completion_status;
5050                 int req_status_flags, req_state_flags;
5051                 uint8_t *snsp, *resp;
5052                 uint32_t rlen, slen;
5053                 long resid;
5054                 uint16_t oop;
5055
5056                 hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
5057                 oop = optr;
5058                 optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
5059                 nlooked++;
5060  read_again:
5061                 buddaboom = req_status_flags = req_state_flags = 0;
5062                 resid = 0L;
5063
5064                 /*
5065                  * Synchronize our view of this response queue entry.
5066                  */
5067                 MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN, -1);
5068                 isp_get_hdr(isp, hp, &sp->req_header);
5069                 etype = sp->req_header.rqs_entry_type;
5070
5071                 if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) {
5072                         isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe;
5073                         isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp2);
5074                         if (isp->isp_dblev & ISP_LOGDEBUG1) {
5075                                 isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp2);
5076                         }
5077                         scsi_status = sp2->req_scsi_status;
5078                         completion_status = sp2->req_completion_status;
5079                         req_state_flags = 0;
5080                         resid = sp2->req_resid;
5081                 } else if (etype == RQSTYPE_RESPONSE) {
5082                         isp_get_response(isp, (ispstatusreq_t *) hp, sp);
5083                         if (isp->isp_dblev & ISP_LOGDEBUG1) {
5084                                 isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp);
5085                         }
5086                         scsi_status = sp->req_scsi_status;
5087                         completion_status = sp->req_completion_status;
5088                         req_status_flags = sp->req_status_flags;
5089                         req_state_flags = sp->req_state_flags;
5090                         resid = sp->req_resid;
5091                 } else if (etype == RQSTYPE_RIO1) {
5092                         isp_rio1_t *rio = (isp_rio1_t *) qe;
5093                         isp_get_rio1(isp, (isp_rio1_t *) hp, rio);
5094                         if (isp->isp_dblev & ISP_LOGDEBUG1) {
5095                                 isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, rio);
5096                         }
5097                         for (i = 0; i < rio->req_header.rqs_seqno; i++) {
5098                                 isp_fastpost_complete(isp, rio->req_handles[i]);
5099                         }
5100                         if (isp->isp_fpcchiwater < rio->req_header.rqs_seqno) {
5101                                 isp->isp_fpcchiwater = rio->req_header.rqs_seqno;
5102                         }
5103                         ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
5104                         continue;
5105                 } else if (etype == RQSTYPE_RIO2) {
5106                         isp_prt(isp, ISP_LOGERR, "dropping RIO2 response\n");
5107                         ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
5108                         continue;
5109                 } else {
5110                         /*
5111                          * Somebody reachable via isp_handle_other_response
5112                          * may have updated the response queue pointers for
5113                          * us, so we reload our goal index.
5114                          */
5115                         int r;
5116                         uint32_t tsto = oop;
5117                         r = isp_handle_other_response(isp, etype, hp, &tsto);
5118                         if (r < 0) {
5119                                 goto read_again;
5120                         }
5121                         /*
5122                          * If somebody updated the output pointer, then reset
5123                          * optr to be one more than the updated amount.
5124                          */
5125                         while (tsto != oop) {
5126                                 optr = ISP_NXT_QENTRY(tsto,
5127                                     RESULT_QUEUE_LEN(isp));
5128                         }
5129                         if (r > 0) {
5130                                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
5131                                 ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
5132                                 continue;
5133                         }
5134
5135                         /*
5136                          * After this point, we'll just look at the header as
5137                          * we don't know how to deal with the rest of the
5138                          * response.
5139                          */
5140
5141                         /*
5142                          * It really has to be a bounced request just copied
5143                          * from the request queue to the response queue. If
5144                          * not, something bad has happened.
5145                          */
5146                         if (etype != RQSTYPE_REQUEST) {
5147                                 isp_prt(isp, ISP_LOGERR, notresp,
5148                                     etype, oop, optr, nlooked);
5149                                 isp_print_bytes(isp,
5150                                     "Request Queue Entry", QENTRY_LEN, sp);
5151                                 ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
5152                                 continue;
5153                         }
5154                         buddaboom = 1;
5155                         scsi_status = sp->req_scsi_status;
5156                         completion_status = sp->req_completion_status;
5157                         req_status_flags = sp->req_status_flags;
5158                         req_state_flags = sp->req_state_flags;
5159                         resid = sp->req_resid;
5160                 }
5161
5162                 if (sp->req_header.rqs_flags & RQSFLAG_MASK) {
5163                         if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
5164                                 isp_print_bytes(isp, "unexpected continuation segment", QENTRY_LEN, sp);
5165                                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
5166                                 continue;
5167                         }
5168                         if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
5169                                 isp_prt(isp, ISP_LOGDEBUG0, "internal queues full");
5170                                 /*
5171                                  * We'll synthesize a QUEUE FULL message below.
5172                                  */
5173                         }
5174                         if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
5175                                 isp_print_bytes(isp, "bad header flag", QENTRY_LEN, sp);
5176                                 buddaboom++;
5177                         }
5178                         if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
5179                                 isp_print_bytes(isp, "bad request packet", QENTRY_LEN, sp);
5180                                 buddaboom++;
5181                         }
5182                         if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
5183                                 isp_print_bytes(isp, "invalid entry count", QENTRY_LEN, sp);
5184                                 buddaboom++;
5185                         }
5186                         if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
5187                                 isp_print_bytes(isp, "invalid IOCB ordering", QENTRY_LEN, sp);
5188                                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
5189                                 continue;
5190                         }
5191                 }
5192
5193                 if (!ISP_VALID_HANDLE(isp, sp->req_handle)) {
5194                         isp_prt(isp, ISP_LOGERR, "bad request handle 0x%x (iocb type 0x%x)", sp->req_handle, etype);
5195                         ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
5196                         ISP_WRITE(isp, isp->isp_respoutrp, optr);
5197                         continue;
5198                 }
5199                 xs = isp_find_xs(isp, sp->req_handle);
5200                 if (xs == NULL) {
5201                         uint8_t ts = completion_status & 0xff;
5202                         /*
5203                          * Only whine if this isn't the expected fallout of
5204                          * aborting the command or resetting the target.
5205                          */
5206                         if (etype != RQSTYPE_RESPONSE) {
5207                                 isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (type 0x%x)", sp->req_handle, etype);
5208                         } else if (ts != RQCS_ABORTED && ts != RQCS_RESET_OCCURRED) {
5209                                 isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", sp->req_handle, ts);
5210                         }
5211                         ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
5212                         ISP_WRITE(isp, isp->isp_respoutrp, optr);
5213                         continue;
5214                 }
5215                 if (req_status_flags & RQSTF_BUS_RESET) {
5216                         XS_SETERR(xs, HBA_BUSRESET);
5217                         ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
5218                 }
5219                 if (buddaboom) {
5220                         XS_SETERR(xs, HBA_BOTCH);
5221                 }
5222
5223                 resp = NULL;
5224                 rlen = 0;
5225                 snsp = NULL;
5226                 slen = 0;
5227                 if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) {
5228                         resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
5229                         rlen = ((isp24xx_statusreq_t *)sp)->req_response_len;
5230                 } else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) {
5231                         resp = sp->req_response;
5232                         rlen = sp->req_response_len;
5233                 }
5234                 if (IS_FC(isp) && (scsi_status & RQCS_SV) != 0) {
5235                         /*
5236                          * Fibre Channel F/W doesn't say we got status
5237                          * if there's Sense Data instead. I guess they
5238                          * think it goes w/o saying.
5239                          */
5240                         req_state_flags |= RQSF_GOT_STATUS|RQSF_GOT_SENSE;
5241                         if (IS_24XX(isp)) {
5242                                 snsp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
5243                                 snsp += rlen;
5244                                 slen = ((isp24xx_statusreq_t *)sp)->req_sense_len;
5245                         } else {
5246                                 snsp = sp->req_sense_data;
5247                                 slen = sp->req_sense_len;
5248                         }
5249                 } else if (IS_SCSI(isp) && (req_state_flags & RQSF_GOT_SENSE)) {
5250                         snsp = sp->req_sense_data;
5251                         slen = sp->req_sense_len;
5252                 }
5253                 if (req_state_flags & RQSF_GOT_STATUS) {
5254                         *XS_STSP(xs) = scsi_status & 0xff;
5255                 }
5256
5257                 switch (etype) {
5258                 case RQSTYPE_RESPONSE:
5259                         if (resp && rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
5260                                 const char *ptr;
5261                                 char lb[64];
5262                                 const char *rnames[6] = {
5263                                         "Task Management Function Done",
5264                                         "Data Length Differs From Burst Length",
5265                                         "Invalid FCP Cmnd",
5266                                         "FCP DATA RO mismatch with FCP DATA_XFR_RDY RO",
5267                                         "Task Management Function Rejected",
5268                                         "Task Management Function Failed",
5269                                 };
5270                                 if (resp[FCP_RSPNS_CODE_OFFSET] > 5) {
5271                                         ISP_SNPRINTF(lb, sizeof lb, "Unknown FCP Response Code 0x%x", resp[FCP_RSPNS_CODE_OFFSET]);
5272                                         ptr = lb;
5273                                 } else {
5274                                         ptr = rnames[resp[FCP_RSPNS_CODE_OFFSET]];
5275                                 }
5276                                 isp_xs_prt(isp, xs, ISP_LOGWARN, "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x", rlen, ptr, XS_CDBP(xs)[0] & 0xff);
5277                                 if (resp[FCP_RSPNS_CODE_OFFSET] != 0) {
5278                                         XS_SETERR(xs, HBA_BOTCH);
5279                                 }
5280                         }
5281                         if (IS_24XX(isp)) {
5282                                 isp_parse_status_24xx(isp, (isp24xx_statusreq_t *)sp, xs, &resid);
5283                         } else {
5284                                 isp_parse_status(isp, (void *)sp, xs, &resid);
5285                         }
5286                         if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) && (*XS_STSP(xs) == SCSI_BUSY)) {
5287                                 XS_SETERR(xs, HBA_TGTBSY);
5288                         }
5289                         if (IS_SCSI(isp)) {
5290                                 XS_SET_RESID(xs, resid);
5291                                 /*
5292                                  * A new synchronous rate was negotiated for
5293                                  * this target. Mark state such that we'll go
5294                                  * look up that which has changed later.
5295                                  */
5296                                 if (req_status_flags & RQSTF_NEGOTIATION) {
5297                                         int t = XS_TGT(xs);
5298                                         sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
5299                                         sdp->isp_devparam[t].dev_refresh = 1;
5300                                         sdp->update = 1;
5301                                 }
5302                         } else {
5303                                 if (req_status_flags & RQSF_XFER_COMPLETE) {
5304                                         XS_SET_RESID(xs, 0);
5305                                 } else if (scsi_status & RQCS_RESID) {
5306                                         XS_SET_RESID(xs, resid);
5307                                 } else {
5308                                         XS_SET_RESID(xs, 0);
5309                                 }
5310                         }
5311                         if (snsp && slen) {
5312                                 XS_SAVE_SENSE(xs, snsp, slen);
5313                         } else if ((req_status_flags & RQSF_GOT_STATUS) && (scsi_status & 0xff) == SCSI_CHECK && IS_FC(isp)) {
5314                                 isp_prt(isp, ISP_LOGWARN, "CHECK CONDITION w/o sense data for CDB=0x%x", XS_CDBP(xs)[0] & 0xff);
5315                                 isp_print_bytes(isp, "CC with no Sense", QENTRY_LEN, qe);
5316                         }
5317                         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));
5318                         break;
5319                 case RQSTYPE_REQUEST:
5320                 case RQSTYPE_A64:
5321                 case RQSTYPE_T2RQS:
5322                 case RQSTYPE_T3RQS:
5323                 case RQSTYPE_T7RQS:
5324                         if (!IS_24XX(isp) && (sp->req_header.rqs_flags & RQSFLAG_FULL)) {
5325                                 /*
5326                                  * Force Queue Full status.
5327                                  */
5328                                 *XS_STSP(xs) = SCSI_QFULL;
5329                                 XS_SETERR(xs, HBA_NOERROR);
5330                         } else if (XS_NOERR(xs)) {
5331                                 XS_SETERR(xs, HBA_BOTCH);
5332                         }
5333                         XS_SET_RESID(xs, XS_XFRLEN(xs));
5334                         break;
5335                 default:
5336                         isp_print_bytes(isp, "Unhandled Response Type", QENTRY_LEN, qe);
5337                         if (XS_NOERR(xs)) {
5338                                 XS_SETERR(xs, HBA_BOTCH);
5339                         }
5340                         break;
5341                 }
5342
5343                 /*
5344                  * Free any DMA resources. As a side effect, this may
5345                  * also do any cache flushing necessary for data coherence.
5346                  */
5347                 if (XS_XFRLEN(xs)) {
5348                         ISP_DMAFREE(isp, xs, sp->req_handle);
5349                 }
5350                 isp_destroy_handle(isp, sp->req_handle);
5351
5352                 if (((isp->isp_dblev & (ISP_LOGDEBUG1|ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
5353                     ((isp->isp_dblev & (ISP_LOGDEBUG0|ISP_LOG_CWARN) && ((!XS_NOERR(xs)) || (*XS_STSP(xs) != SCSI_GOOD))))) {
5354                         isp_prt_endcmd(isp, xs);
5355                 }
5356                 if (isp->isp_nactive > 0) {
5357                     isp->isp_nactive--;
5358                 }
5359                 complist[ndone++] = xs; /* defer completion call until later */
5360                 ISP_MEMZERO(hp, QENTRY_LEN);    /* PERF */
5361                 if (ndone == MAX_REQUESTQ_COMPLETIONS) {
5362                         break;
5363                 }
5364         }
5365
5366         /*
5367          * If we looked at any commands, then it's valid to find out
5368          * what the outpointer is. It also is a trigger to update the
5369          * ISP's notion of what we've seen so far.
5370          */
5371         if (nlooked) {
5372                 ISP_WRITE(isp, isp->isp_respoutrp, optr);
5373                 /*
5374                  * While we're at it, read the requst queue out pointer.
5375                  */
5376                 isp->isp_reqodx = ISP_READ(isp, isp->isp_rqstoutrp);
5377                 if (isp->isp_rscchiwater < ndone) {
5378                         isp->isp_rscchiwater = ndone;
5379                 }
5380         }
5381
5382 out:
5383
5384         if (IS_24XX(isp)) {
5385                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
5386         } else {
5387                 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
5388                 ISP_WRITE(isp, BIU_SEMA, 0);
5389         }
5390
5391         isp->isp_residx = optr;
5392         for (i = 0; i < ndone; i++) {
5393                 xs = complist[i];
5394                 if (xs) {
5395                         isp->isp_rsltccmplt++;
5396                         isp_done(xs);
5397                 }
5398         }
5399 }
5400
5401 /*
5402  * Support routines.
5403  */
5404
5405 void
5406 isp_prt_endcmd(ispsoftc_t *isp, XS_T *xs)
5407 {
5408         char cdbstr[16 * 5 + 1];
5409         int i, lim;
5410
5411         lim = XS_CDBLEN(xs) > 16? 16 : XS_CDBLEN(xs);
5412         ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "0x%02x ", XS_CDBP(xs)[0]);
5413         for (i = 1; i < lim; i++) {
5414                 ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "%s0x%02x ", cdbstr, XS_CDBP(xs)[i]);
5415         }
5416         if (XS_SENSE_VALID(xs)) {
5417                 isp_xs_prt(isp, xs, ISP_LOGALL, "FIN dl%d resid %ld CDB=%s KEY/ASC/ASCQ=XXX/XXX/XXX",
5418                     XS_XFRLEN(xs), (long) XS_GET_RESID(xs), cdbstr /* XXX swildner , XS_SNSKEY(xs), XS_SNSASC(xs), XS_SNSASCQ(xs) */);
5419         } else {
5420                 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));
5421         }
5422 }
5423
5424 /*
5425  * Parse an ASYNC mailbox complete
5426  *
5427  * Return non-zero if the event has been acknowledged.
5428  */
5429 static int
5430 isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
5431 {
5432         int acked = 0;
5433         uint32_t h1 = 0, h2 = 0;
5434         uint16_t chan = 0;
5435
5436         /*
5437          * Pick up the channel, but not if this is a ASYNC_RIO32_2,
5438          * where Mailboxes 6/7 have the second handle.
5439          */
5440         if (mbox != ASYNC_RIO32_2) {
5441                 if (IS_DUALBUS(isp)) {
5442                         chan = ISP_READ(isp, OUTMAILBOX6);
5443                 }
5444         }
5445         isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
5446
5447         switch (mbox) {
5448         case ASYNC_BUS_RESET:
5449                 ISP_SET_SENDMARKER(isp, chan, 1);
5450 #ifdef  ISP_TARGET_MODE
5451                 if (isp_target_async(isp, chan, mbox)) {
5452                         acked = 1;
5453                 }
5454 #endif
5455                 isp_async(isp, ISPASYNC_BUS_RESET, chan);
5456                 break;
5457         case ASYNC_SYSTEM_ERROR:
5458                 isp->isp_dead = 1;
5459                 isp->isp_state = ISP_CRASHED;
5460                 /*
5461                  * Were we waiting for a mailbox command to complete?
5462                  * If so, it's dead, so wake up the waiter.
5463                  */
5464                 if (isp->isp_mboxbsy) {
5465                         isp->isp_obits = 1;
5466                         isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
5467                         MBOX_NOTIFY_COMPLETE(isp);
5468                 }
5469                 /*
5470                  * It's up to the handler for isp_async to reinit stuff and
5471                  * restart the firmware
5472                  */
5473                 isp_async(isp, ISPASYNC_FW_CRASH);
5474                 acked = 1;
5475                 break;
5476
5477         case ASYNC_RQS_XFER_ERR:
5478                 isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
5479                 break;
5480
5481         case ASYNC_RSP_XFER_ERR:
5482                 isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
5483                 break;
5484
5485         case ASYNC_QWAKEUP:
5486                 /*
5487                  * We've just been notified that the Queue has woken up.
5488                  * We don't need to be chatty about this- just unlatch things
5489                  * and move on.
5490                  */
5491                 mbox = ISP_READ(isp, isp->isp_rqstoutrp);
5492                 break;
5493
5494         case ASYNC_TIMEOUT_RESET:
5495                 isp_prt(isp, ISP_LOGWARN, "timeout initiated SCSI bus reset of chan %d", chan);
5496                 ISP_SET_SENDMARKER(isp, chan, 1);
5497 #ifdef  ISP_TARGET_MODE
5498                 if (isp_target_async(isp, chan, mbox)) {
5499                         acked = 1;
5500                 }
5501 #endif
5502                 break;
5503
5504         case ASYNC_DEVICE_RESET:
5505                 isp_prt(isp, ISP_LOGINFO, "device reset on chan %d", chan);
5506                 ISP_SET_SENDMARKER(isp, chan, 1);
5507 #ifdef  ISP_TARGET_MODE
5508                 if (isp_target_async(isp, chan, mbox)) {
5509                         acked = 1;
5510                 }
5511 #endif
5512                 break;
5513
5514         case ASYNC_EXTMSG_UNDERRUN:
5515                 isp_prt(isp, ISP_LOGWARN, "extended message underrun");
5516                 break;
5517
5518         case ASYNC_SCAM_INT:
5519                 isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
5520                 break;
5521
5522         case ASYNC_HUNG_SCSI:
5523                 isp_prt(isp, ISP_LOGERR, "stalled SCSI Bus after DATA Overrun");
5524                 /* XXX: Need to issue SCSI reset at this point */
5525                 break;
5526
5527         case ASYNC_KILLED_BUS:
5528                 isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
5529                 break;
5530
5531         case ASYNC_BUS_TRANSIT:
5532                 mbox = ISP_READ(isp, OUTMAILBOX2);
5533                 switch (mbox & SXP_PINS_MODE_MASK) {
5534                 case SXP_PINS_LVD_MODE:
5535                         isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
5536                         SDPARAM(isp, chan)->isp_diffmode = 0;
5537                         SDPARAM(isp, chan)->isp_ultramode = 0;
5538                         SDPARAM(isp, chan)->isp_lvdmode = 1;
5539                         break;
5540                 case SXP_PINS_HVD_MODE:
5541                         isp_prt(isp, ISP_LOGINFO,
5542                             "Transition to Differential mode");
5543                         SDPARAM(isp, chan)->isp_diffmode = 1;
5544                         SDPARAM(isp, chan)->isp_ultramode = 0;
5545                         SDPARAM(isp, chan)->isp_lvdmode = 0;
5546                         break;
5547                 case SXP_PINS_SE_MODE:
5548                         isp_prt(isp, ISP_LOGINFO,
5549                             "Transition to Single Ended mode");
5550                         SDPARAM(isp, chan)->isp_diffmode = 0;
5551                         SDPARAM(isp, chan)->isp_ultramode = 1;
5552                         SDPARAM(isp, chan)->isp_lvdmode = 0;
5553                         break;
5554                 default:
5555                         isp_prt(isp, ISP_LOGWARN,
5556                             "Transition to Unknown Mode 0x%x", mbox);
5557                         break;
5558                 }
5559                 /*
5560                  * XXX: Set up to renegotiate again!
5561                  */
5562                 /* Can only be for a 1080... */
5563                 ISP_SET_SENDMARKER(isp, chan, 1);
5564                 break;
5565
5566         case ASYNC_CMD_CMPLT:
5567         case ASYNC_RIO32_1:
5568                 if (!IS_ULTRA3(isp)) {
5569                         isp_prt(isp, ISP_LOGERR, "unexpected fast posting completion");
5570                         break;
5571                 }
5572                 /* FALLTHROUGH */
5573                 h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1);
5574                 break;
5575
5576         case ASYNC_RIO32_2:
5577                 h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1);
5578                 h2 = (ISP_READ(isp, OUTMAILBOX7) << 16) | ISP_READ(isp, OUTMAILBOX6);
5579                 break;
5580
5581         case ASYNC_RIO16_5:
5582         case ASYNC_RIO16_4:
5583         case ASYNC_RIO16_3:
5584         case ASYNC_RIO16_2:
5585         case ASYNC_RIO16_1:
5586                 isp_prt(isp, ISP_LOGERR, "unexpected 16 bit RIO handle");
5587                 break;
5588         default:
5589                 isp_prt(isp, ISP_LOGWARN, "%s: unhandled async code 0x%x", __func__, mbox);
5590                 break;
5591         }
5592
5593         if (h1 || h2) {
5594                 isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h1);
5595                 isp_fastpost_complete(isp, h1);
5596                 if (h2) {
5597                         isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h2);
5598                         isp_fastpost_complete(isp, h2);
5599                         if (isp->isp_fpcchiwater < 2) {
5600                                 isp->isp_fpcchiwater = 2;
5601                         }
5602                 } else {
5603                         if (isp->isp_fpcchiwater < 1) {
5604                                 isp->isp_fpcchiwater = 1;
5605                         }
5606                 }
5607         } else {
5608                 isp->isp_intoasync++;
5609         }
5610         return (acked);
5611 }
5612
5613 #define GET_24XX_BUS(isp, chan, msg)                                                                            \
5614         if (IS_24XX(isp)) {                                                                                     \
5615                 chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;                                                       \
5616                 if (chan >= isp->isp_nchan) {                                                                   \
5617                         isp_prt(isp, ISP_LOGERR, "bogus channel %u for %s at line %d",  chan, msg, __LINE__);   \
5618                         break;                                                                                  \
5619                 }                                                                                               \
5620         }
5621
5622
5623 static int
5624 isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox)
5625 {
5626         int acked = 0;
5627         uint16_t chan;
5628
5629         if (IS_DUALBUS(isp)) {
5630                 chan = ISP_READ(isp, OUTMAILBOX6);
5631         } else {
5632                 chan = 0;
5633         }
5634         isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
5635
5636         switch (mbox) {
5637         case ASYNC_SYSTEM_ERROR:
5638                 isp->isp_dead = 1;
5639                 isp->isp_state = ISP_CRASHED;
5640                 FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
5641                 FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
5642                 /*
5643                  * Were we waiting for a mailbox command to complete?
5644                  * If so, it's dead, so wake up the waiter.
5645                  */
5646                 if (isp->isp_mboxbsy) {
5647                         isp->isp_obits = 1;
5648                         isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
5649                         MBOX_NOTIFY_COMPLETE(isp);
5650                 }
5651                 /*
5652                  * It's up to the handler for isp_async to reinit stuff and
5653                  * restart the firmware
5654                  */
5655                 isp_async(isp, ISPASYNC_FW_CRASH);
5656                 acked = 1;
5657                 break;
5658
5659         case ASYNC_RQS_XFER_ERR:
5660                 isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
5661                 break;
5662
5663         case ASYNC_RSP_XFER_ERR:
5664                 isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
5665                 break;
5666
5667         case ASYNC_QWAKEUP:
5668 #ifdef  ISP_TARGET_MODE
5669                 if (IS_24XX(isp)) {
5670                         isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
5671                         break;
5672                 }
5673 #endif
5674                 isp_prt(isp, ISP_LOGERR, "%s: unexpected ASYNC_QWAKEUP code", __func__);
5675                 break;
5676
5677         case ASYNC_CMD_CMPLT:
5678                 isp_fastpost_complete(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1));
5679                 if (isp->isp_fpcchiwater < 1) {
5680                         isp->isp_fpcchiwater = 1;
5681                 }
5682                 break;
5683
5684         case ASYNC_RIOZIO_STALL:
5685                 break;
5686
5687         case ASYNC_CTIO_DONE:
5688 #ifdef  ISP_TARGET_MODE
5689                 if (isp_target_async(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1), mbox)) {
5690                         acked = 1;
5691                 } else {
5692                         isp->isp_fphccmplt++;
5693                 }
5694 #else
5695                 isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC CTIO done");
5696 #endif
5697                 break;
5698         case ASYNC_LIP_ERROR:
5699         case ASYNC_LIP_F8:
5700         case ASYNC_LIP_OCCURRED:
5701         case ASYNC_PTPMODE:
5702                 /*
5703                  * These are broadcast events that have to be sent across
5704                  * all active channels.
5705                  */
5706                 for (chan = 0; chan < isp->isp_nchan; chan++) {
5707                         fcparam *fcp = FCPARAM(isp, chan);
5708                         int topo = fcp->isp_topo;
5709
5710                         if (fcp->role == ISP_ROLE_NONE) {
5711                                 continue;
5712                         }
5713
5714                         fcp->isp_fwstate = FW_CONFIG_WAIT;
5715                         fcp->isp_loopstate = LOOP_LIP_RCVD;
5716                         ISP_SET_SENDMARKER(isp, chan, 1);
5717                         ISP_MARK_PORTDB(isp, chan, 1);
5718                         isp_async(isp, ISPASYNC_LIP, chan);
5719 #ifdef  ISP_TARGET_MODE
5720                         if (isp_target_async(isp, chan, mbox)) {
5721                                 acked = 1;
5722                         }
5723 #endif
5724                         /*
5725                          * We've had problems with data corruption occuring on
5726                          * commands that complete (with no apparent error) after
5727                          * we receive a LIP. This has been observed mostly on
5728                          * Local Loop topologies. To be safe, let's just mark
5729                          * all active initiator commands as dead.
5730                          */
5731                         if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
5732                                 int i, j;
5733                                 for (i = j = 0; i < isp->isp_maxcmds; i++) {
5734                                         XS_T *xs;
5735                                         isp_hdl_t *hdp;
5736
5737                                         hdp = &isp->isp_xflist[i];
5738                                         if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) {
5739                                                 continue;
5740                                         }
5741                                         xs = hdp->cmd;
5742                                         if (XS_CHANNEL(xs) != chan) {
5743                                                 continue;
5744                                         }
5745                                         j++;
5746                                         XS_SETERR(xs, HBA_BUSRESET);
5747                                 }
5748                                 if (j) {
5749                                         isp_prt(isp, ISP_LOGERR, lipd, chan, j);
5750                                 }
5751                         }
5752                 }
5753                 break;
5754
5755         case ASYNC_LOOP_UP:
5756                 /*
5757                  * This is a broadcast event that has to be sent across
5758                  * all active channels.
5759                  */
5760                 for (chan = 0; chan < isp->isp_nchan; chan++) {
5761                         fcparam *fcp = FCPARAM(isp, chan);
5762
5763                         if (fcp->role == ISP_ROLE_NONE) {
5764                                 continue;
5765                         }
5766
5767                         ISP_SET_SENDMARKER(isp, chan, 1);
5768
5769                         fcp->isp_fwstate = FW_CONFIG_WAIT;
5770                         fcp->isp_loopstate = LOOP_LIP_RCVD;
5771                         ISP_MARK_PORTDB(isp, chan, 1);
5772                         isp_async(isp, ISPASYNC_LOOP_UP, chan);
5773 #ifdef  ISP_TARGET_MODE
5774                         if (isp_target_async(isp, chan, mbox)) {
5775                                 acked = 1;
5776                         }
5777 #endif
5778                 }
5779                 break;
5780
5781         case ASYNC_LOOP_DOWN:
5782                 /*
5783                  * This is a broadcast event that has to be sent across
5784                  * all active channels.
5785                  */
5786                 for (chan = 0; chan < isp->isp_nchan; chan++) {
5787                         fcparam *fcp = FCPARAM(isp, chan);
5788
5789                         if (fcp->role == ISP_ROLE_NONE) {
5790                                 continue;
5791                         }
5792
5793                         ISP_SET_SENDMARKER(isp, chan, 1);
5794                         fcp->isp_fwstate = FW_CONFIG_WAIT;
5795                         fcp->isp_loopstate = LOOP_NIL;
5796                         ISP_MARK_PORTDB(isp, chan, 1);
5797                         isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
5798 #ifdef  ISP_TARGET_MODE
5799                         if (isp_target_async(isp, chan, mbox)) {
5800                                 acked = 1;
5801                         }
5802 #endif
5803                 }
5804                 break;
5805
5806         case ASYNC_LOOP_RESET:
5807                 /*
5808                  * This is a broadcast event that has to be sent across
5809                  * all active channels.
5810                  */
5811                 for (chan = 0; chan < isp->isp_nchan; chan++) {
5812                         fcparam *fcp = FCPARAM(isp, chan);
5813
5814                         if (fcp->role == ISP_ROLE_NONE) {
5815                                 continue;
5816                         }
5817
5818                         ISP_SET_SENDMARKER(isp, chan, 1);
5819                         fcp->isp_fwstate = FW_CONFIG_WAIT;
5820                         fcp->isp_loopstate = LOOP_NIL;
5821                         ISP_MARK_PORTDB(isp, chan, 1);
5822                         isp_async(isp, ISPASYNC_LOOP_RESET, chan);
5823 #ifdef  ISP_TARGET_MODE
5824                         if (isp_target_async(isp, chan, mbox)) {
5825                                 acked = 1;
5826                         }
5827 #endif
5828                 }
5829                 break;
5830
5831         case ASYNC_PDB_CHANGED:
5832         {
5833                 int nphdl, nlstate, reason;
5834                 /*
5835                  * We *should* get a channel out of the 24XX, but we don't seem
5836                  * to get more than a PDB CHANGED on channel 0, so turn it into
5837                  * a broadcast event.
5838                  */
5839                 if (IS_24XX(isp)) {
5840                         nphdl = ISP_READ(isp, OUTMAILBOX1);
5841                         nlstate = ISP_READ(isp, OUTMAILBOX2);
5842                         reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
5843                 } else {
5844                         nphdl = NIL_HANDLE;
5845                         nlstate = reason = 0;
5846                 }
5847                 for (chan = 0; chan < isp->isp_nchan; chan++) {
5848                         fcparam *fcp = FCPARAM(isp, chan);
5849
5850                         if (fcp->role == ISP_ROLE_NONE) {
5851                                 continue;
5852                         }
5853                         ISP_SET_SENDMARKER(isp, chan, 1);
5854                         fcp->isp_loopstate = LOOP_PDB_RCVD;
5855                         ISP_MARK_PORTDB(isp, chan, 1);
5856                         isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
5857                 }
5858                 break;
5859         }
5860         case ASYNC_CHANGE_NOTIFY:
5861         {
5862                 int lochan, hichan;
5863
5864                 if (ISP_FW_NEWER_THAN(isp, 4, 0, 25) && ISP_CAP_MULTI_ID(isp)) {
5865                         GET_24XX_BUS(isp, chan, "ASYNC_CHANGE_NOTIFY");
5866                         lochan = chan;
5867                         hichan = chan + 1;
5868                 } else {
5869                         lochan = 0;
5870                         hichan = isp->isp_nchan;
5871                 }
5872                 for (chan = lochan; chan < hichan; chan++) {
5873                         fcparam *fcp = FCPARAM(isp, chan);
5874
5875                         if (fcp->role == ISP_ROLE_NONE) {
5876                                 continue;
5877                         }
5878
5879                         if (fcp->isp_topo == TOPO_F_PORT) {
5880                                 fcp->isp_loopstate = LOOP_LSCAN_DONE;
5881                         } else {
5882                                 fcp->isp_loopstate = LOOP_PDB_RCVD;
5883                         }
5884                         ISP_MARK_PORTDB(isp, chan, 1);
5885                         isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_SNS);
5886                 }
5887                 break;
5888         }
5889
5890         case ASYNC_CONNMODE:
5891                 /*
5892                  * This only applies to 2100 amd 2200 cards
5893                  */
5894                 if (!IS_2200(isp) && !IS_2100(isp)) {
5895                         isp_prt(isp, ISP_LOGWARN, "bad card for ASYNC_CONNMODE event");
5896                         break;
5897                 }
5898                 chan = 0;
5899                 mbox = ISP_READ(isp, OUTMAILBOX1);
5900                 ISP_MARK_PORTDB(isp, chan, 1);
5901                 switch (mbox) {
5902                 case ISP_CONN_LOOP:
5903                         isp_prt(isp, ISP_LOGINFO,
5904                             "Point-to-Point -> Loop mode");
5905                         break;
5906                 case ISP_CONN_PTP:
5907                         isp_prt(isp, ISP_LOGINFO,
5908                             "Loop -> Point-to-Point mode");
5909                         break;
5910                 case ISP_CONN_BADLIP:
5911                         isp_prt(isp, ISP_LOGWARN,
5912                             "Point-to-Point -> Loop mode (BAD LIP)");
5913                         break;
5914                 case ISP_CONN_FATAL:
5915                         isp->isp_dead = 1;
5916                         isp->isp_state = ISP_CRASHED;
5917                         isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
5918                         isp_async(isp, ISPASYNC_FW_CRASH);
5919                         return (-1);
5920                 case ISP_CONN_LOOPBACK:
5921                         isp_prt(isp, ISP_LOGWARN,
5922                             "Looped Back in Point-to-Point mode");
5923                         break;
5924                 default:
5925                         isp_prt(isp, ISP_LOGWARN,
5926                             "Unknown connection mode (0x%x)", mbox);
5927                         break;
5928                 }
5929                 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_OTHER);
5930                 FCPARAM(isp, chan)->sendmarker = 1;
5931                 FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
5932                 FCPARAM(isp, chan)->isp_loopstate = LOOP_LIP_RCVD;
5933                 break;
5934
5935         case ASYNC_RCV_ERR:
5936                 if (IS_24XX(isp)) {
5937                         isp_prt(isp, ISP_LOGWARN, "Receive Error");
5938                 } else {
5939                         isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC_RCV_ERR");
5940                 }
5941                 break;
5942         case ASYNC_RJT_SENT:    /* same as ASYNC_QFULL_SENT */
5943                 if (IS_24XX(isp)) {
5944                         isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
5945                         break;
5946                 } else if (IS_2200(isp)) {
5947                         isp_prt(isp, ISP_LOGTDEBUG0, "QFULL sent");
5948                         break;
5949                 }
5950                 /* FALLTHROUGH */
5951         default:
5952                 isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
5953                 break;
5954         }
5955         if (mbox != ASYNC_CTIO_DONE && mbox != ASYNC_CMD_CMPLT) {
5956                 isp->isp_intoasync++;
5957         }
5958         return (acked);
5959 }
5960
5961 /*
5962  * Handle other response entries. A pointer to the request queue output
5963  * index is here in case we want to eat several entries at once, although
5964  * this is not used currently.
5965  */
5966
5967 static int
5968 isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *optrp)
5969 {
5970         switch (type) {
5971         case RQSTYPE_STATUS_CONT:
5972                 isp_prt(isp, ISP_LOGDEBUG0, "Ignored Continuation Response");
5973                 return (1);
5974         case RQSTYPE_MARKER:
5975                 isp_prt(isp, ISP_LOGDEBUG0, "Marker Response");
5976                 return (1);
5977         case RQSTYPE_ATIO:
5978         case RQSTYPE_CTIO:
5979         case RQSTYPE_ENABLE_LUN:
5980         case RQSTYPE_MODIFY_LUN:
5981         case RQSTYPE_NOTIFY:
5982         case RQSTYPE_NOTIFY_ACK:
5983         case RQSTYPE_CTIO1:
5984         case RQSTYPE_ATIO2:
5985         case RQSTYPE_CTIO2:
5986         case RQSTYPE_CTIO3:
5987         case RQSTYPE_CTIO7:
5988         case RQSTYPE_ABTS_RCVD:
5989         case RQSTYPE_ABTS_RSP:
5990                 isp->isp_rsltccmplt++;  /* count as a response completion */
5991 #ifdef  ISP_TARGET_MODE
5992                 if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
5993                         return (1);
5994                 }
5995 #endif
5996                 /* FALLTHROUGH */
5997         case RQSTYPE_RPT_ID_ACQ:
5998                 if (IS_24XX(isp)) {
5999                         isp_ridacq_t rid;
6000                         isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
6001                         if (rid.ridacq_format == 0) {
6002                         }
6003                         return (1);
6004                 }
6005                 /* FALLTHROUGH */
6006         case RQSTYPE_REQUEST:
6007         default:
6008                 ISP_DELAY(100);
6009                 if (type != isp_get_response_type(isp, hp)) {
6010                         /*
6011                          * This is questionable- we're just papering over
6012                          * something we've seen on SMP linux in target
6013                          * mode- we don't really know what's happening
6014                          * here that causes us to think we've gotten
6015                          * an entry, but that either the entry isn't
6016                          * filled out yet or our CPU read data is stale.
6017                          */
6018                         isp_prt(isp, ISP_LOGINFO,
6019                                 "unstable type in response queue");
6020                         return (-1);
6021                 }
6022                 isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
6023                     isp_get_response_type(isp, hp));
6024                 return (0);
6025         }
6026 }
6027
6028 static void
6029 isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
6030 {
6031         switch (sp->req_completion_status & 0xff) {
6032         case RQCS_COMPLETE:
6033                 if (XS_NOERR(xs)) {
6034                         XS_SETERR(xs, HBA_NOERROR);
6035                 }
6036                 return;
6037
6038         case RQCS_INCOMPLETE:
6039                 if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
6040                         isp_xs_prt(isp, xs, ISP_LOGDEBUG1, "Selection Timeout");
6041                         if (XS_NOERR(xs)) {
6042                                 XS_SETERR(xs, HBA_SELTIMEOUT);
6043                                 *rp = XS_XFRLEN(xs);
6044                         }
6045                         return;
6046                 }
6047                 isp_xs_prt(isp, xs, ISP_LOGERR, "Command Incomplete, state 0x%x", sp->req_state_flags);
6048                 break;
6049
6050         case RQCS_DMA_ERROR:
6051                 isp_xs_prt(isp, xs, ISP_LOGERR, "DMA Error");
6052                 *rp = XS_XFRLEN(xs);
6053                 break;
6054
6055         case RQCS_TRANSPORT_ERROR:
6056         {
6057                 char buf[172];
6058                 ISP_SNPRINTF(buf, sizeof (buf), "states=>");
6059                 if (sp->req_state_flags & RQSF_GOT_BUS) {
6060                         ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
6061                 }
6062                 if (sp->req_state_flags & RQSF_GOT_TARGET) {
6063                         ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
6064                 }
6065                 if (sp->req_state_flags & RQSF_SENT_CDB) {
6066                         ISP_SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
6067                 }
6068                 if (sp->req_state_flags & RQSF_XFRD_DATA) {
6069                         ISP_SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
6070                 }
6071                 if (sp->req_state_flags & RQSF_GOT_STATUS) {
6072                         ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
6073                 }
6074                 if (sp->req_state_flags & RQSF_GOT_SENSE) {
6075                         ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
6076                 }
6077                 if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
6078                         ISP_SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
6079                 }
6080                 ISP_SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
6081                 if (sp->req_status_flags & RQSTF_DISCONNECT) {
6082                         ISP_SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
6083                 }
6084                 if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
6085                         ISP_SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
6086                 }
6087                 if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
6088                         ISP_SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
6089                 }
6090                 if (sp->req_status_flags & RQSTF_BUS_RESET) {
6091                         ISP_SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
6092                 }
6093                 if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
6094                         ISP_SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
6095                 }
6096                 if (sp->req_status_flags & RQSTF_ABORTED) {
6097                         ISP_SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
6098                 }
6099                 if (sp->req_status_flags & RQSTF_TIMEOUT) {
6100                         ISP_SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
6101                 }
6102                 if (sp->req_status_flags & RQSTF_NEGOTIATION) {
6103                         ISP_SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
6104                 }
6105                 isp_xs_prt(isp, xs,  ISP_LOGERR, "Transport Error: %s", buf);
6106                 *rp = XS_XFRLEN(xs);
6107                 break;
6108         }
6109         case RQCS_RESET_OCCURRED:
6110         {
6111                 int chan;
6112                 isp_xs_prt(isp, xs, ISP_LOGWARN, "Bus Reset destroyed command");
6113                 for (chan = 0; chan < isp->isp_nchan; chan++) {
6114                         FCPARAM(isp, chan)->sendmarker = 1;
6115                 }
6116                 if (XS_NOERR(xs)) {
6117                         XS_SETERR(xs, HBA_BUSRESET);
6118                 }
6119                 *rp = XS_XFRLEN(xs);
6120                 return;
6121         }
6122         case RQCS_ABORTED:
6123                 isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
6124                 ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
6125                 if (XS_NOERR(xs)) {
6126                         XS_SETERR(xs, HBA_ABORTED);
6127                 }
6128                 return;
6129
6130         case RQCS_TIMEOUT:
6131                 isp_xs_prt(isp, xs, ISP_LOGWARN, "Command timed out");
6132                 /*
6133                  * XXX: Check to see if we logged out of the device.
6134                  */
6135                 if (XS_NOERR(xs)) {
6136                         XS_SETERR(xs, HBA_CMDTIMEOUT);
6137                 }
6138                 return;
6139
6140         case RQCS_DATA_OVERRUN:
6141                 XS_SET_RESID(xs, sp->req_resid);
6142                 isp_xs_prt(isp, xs, ISP_LOGERR, "data overrun (%ld)", (long) XS_GET_RESID(xs));
6143                 if (XS_NOERR(xs)) {
6144                         XS_SETERR(xs, HBA_DATAOVR);
6145                 }
6146                 return;
6147
6148         case RQCS_COMMAND_OVERRUN:
6149                 isp_xs_prt(isp, xs, ISP_LOGERR, "command overrun");
6150                 break;
6151
6152         case RQCS_STATUS_OVERRUN:
6153                 isp_xs_prt(isp, xs, ISP_LOGERR, "status overrun");
6154                 break;
6155
6156         case RQCS_BAD_MESSAGE:
6157                 isp_xs_prt(isp, xs, ISP_LOGERR, "msg not COMMAND COMPLETE after status");
6158                 break;
6159
6160         case RQCS_NO_MESSAGE_OUT:
6161                 isp_xs_prt(isp, xs, ISP_LOGERR, "No MESSAGE OUT phase after selection");
6162                 break;
6163
6164         case RQCS_EXT_ID_FAILED:
6165                 isp_xs_prt(isp, xs, ISP_LOGERR, "EXTENDED IDENTIFY failed");
6166                 break;
6167
6168         case RQCS_IDE_MSG_FAILED:
6169                 isp_xs_prt(isp, xs, ISP_LOGERR, "INITIATOR DETECTED ERROR rejected");
6170                 break;
6171
6172         case RQCS_ABORT_MSG_FAILED:
6173                 isp_xs_prt(isp, xs, ISP_LOGERR, "ABORT OPERATION rejected");
6174                 break;
6175
6176         case RQCS_REJECT_MSG_FAILED:
6177                 isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE REJECT rejected");
6178                 break;
6179
6180         case RQCS_NOP_MSG_FAILED:
6181                 isp_xs_prt(isp, xs, ISP_LOGERR, "NOP rejected");
6182                 break;
6183
6184         case RQCS_PARITY_ERROR_MSG_FAILED:
6185                 isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE PARITY ERROR rejected");
6186                 break;
6187
6188         case RQCS_DEVICE_RESET_MSG_FAILED:
6189                 isp_xs_prt(isp, xs, ISP_LOGWARN, "BUS DEVICE RESET rejected");
6190                 break;
6191
6192         case RQCS_ID_MSG_FAILED:
6193                 isp_xs_prt(isp, xs, ISP_LOGERR, "IDENTIFY rejected");
6194                 break;
6195
6196         case RQCS_UNEXP_BUS_FREE:
6197                 isp_xs_prt(isp, xs, ISP_LOGERR, "Unexpected Bus Free");
6198                 break;
6199
6200         case RQCS_DATA_UNDERRUN:
6201         {
6202                 if (IS_FC(isp)) {
6203                         int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
6204                         if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
6205                                 isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
6206                                 if (XS_NOERR(xs)) {
6207                                         XS_SETERR(xs, HBA_BOTCH);
6208                                 }
6209                                 return;
6210                         }
6211                 }
6212                 XS_SET_RESID(xs, sp->req_resid);
6213                 if (XS_NOERR(xs)) {
6214                         XS_SETERR(xs, HBA_NOERROR);
6215                 }
6216                 return;
6217         }
6218
6219         case RQCS_XACT_ERR1:
6220                 isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued transaction with disconnect not set");
6221                 break;
6222
6223         case RQCS_XACT_ERR2:
6224                 isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued transaction to target routine %d", XS_LUN(xs));
6225                 break;
6226
6227         case RQCS_XACT_ERR3:
6228                 isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued cmd when queueing disabled");
6229                 break;
6230
6231         case RQCS_BAD_ENTRY:
6232                 isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
6233                 break;
6234
6235         case RQCS_QUEUE_FULL:
6236                 isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "internal queues full status 0x%x", *XS_STSP(xs));
6237
6238                 /*
6239                  * If QFULL or some other status byte is set, then this
6240                  * isn't an error, per se.
6241                  *
6242                  * Unfortunately, some QLogic f/w writers have, in
6243                  * some cases, ommitted to *set* status to QFULL.
6244                  *
6245
6246                 if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
6247                         XS_SETERR(xs, HBA_NOERROR);
6248                         return;
6249                 }
6250
6251                  *
6252                  *
6253                  */
6254
6255                 *XS_STSP(xs) = SCSI_QFULL;
6256                 XS_SETERR(xs, HBA_NOERROR);
6257                 return;
6258
6259         case RQCS_PHASE_SKIPPED:
6260                 isp_xs_prt(isp, xs, ISP_LOGERR, "SCSI phase skipped");
6261                 break;
6262
6263         case RQCS_ARQS_FAILED:
6264                 isp_xs_prt(isp, xs, ISP_LOGERR, "Auto Request Sense Failed");
6265                 if (XS_NOERR(xs)) {
6266                         XS_SETERR(xs, HBA_ARQFAIL);
6267                 }
6268                 return;
6269
6270         case RQCS_WIDE_FAILED:
6271                 isp_xs_prt(isp, xs, ISP_LOGERR, "Wide Negotiation Failed");
6272                 if (IS_SCSI(isp)) {
6273                         sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
6274                         sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
6275                         sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
6276                         sdp->update = 1;
6277                 }
6278                 if (XS_NOERR(xs)) {
6279                         XS_SETERR(xs, HBA_NOERROR);
6280                 }
6281                 return;
6282
6283         case RQCS_SYNCXFER_FAILED:
6284                 isp_xs_prt(isp, xs, ISP_LOGERR, "SDTR Message Failed");
6285                 if (IS_SCSI(isp)) {
6286                         sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
6287                         sdp += XS_CHANNEL(xs);
6288                         sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
6289                         sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
6290                         sdp->update = 1;
6291                 }
6292                 break;
6293
6294         case RQCS_LVD_BUSERR:
6295                 isp_xs_prt(isp, xs, ISP_LOGERR, "Bad LVD condition");
6296                 break;
6297
6298         case RQCS_PORT_UNAVAILABLE:
6299                 /*
6300                  * No such port on the loop. Moral equivalent of SELTIMEO
6301                  */
6302         case RQCS_PORT_LOGGED_OUT:
6303         {
6304                 const char *reason;
6305                 uint8_t sts = sp->req_completion_status & 0xff;
6306
6307                 /*
6308                  * It was there (maybe)- treat as a selection timeout.
6309                  */
6310                 if (sts == RQCS_PORT_UNAVAILABLE) {
6311                         reason = "unavailable";
6312                 } else {
6313                         reason = "logout";
6314                 }
6315
6316                 isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
6317                     reason, XS_TGT(xs));
6318
6319                 /*
6320                  * If we're on a local loop, force a LIP (which is overkill)
6321                  * to force a re-login of this unit. If we're on fabric,
6322                  * then we'll have to log in again as a matter of course.
6323                  */
6324                 if (FCPARAM(isp, 0)->isp_topo == TOPO_NL_PORT ||
6325                     FCPARAM(isp, 0)->isp_topo == TOPO_FL_PORT) {
6326                         mbreg_t mbs;
6327                         MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
6328                         if (ISP_CAP_2KLOGIN(isp)) {
6329                                 mbs.ibits = (1 << 10);
6330                         }
6331                         isp_mboxcmd_qnw(isp, &mbs, 1);
6332                 }
6333                 if (XS_NOERR(xs)) {
6334                         XS_SETERR(xs, HBA_SELTIMEOUT);
6335                 }
6336                 return;
6337         }
6338         case RQCS_PORT_CHANGED:
6339                 isp_prt(isp, ISP_LOGWARN,
6340                     "port changed for target %d", XS_TGT(xs));
6341                 if (XS_NOERR(xs)) {
6342                         XS_SETERR(xs, HBA_SELTIMEOUT);
6343                 }
6344                 return;
6345
6346         case RQCS_PORT_BUSY:
6347                 isp_prt(isp, ISP_LOGWARN,
6348                     "port busy for target %d", XS_TGT(xs));
6349                 if (XS_NOERR(xs)) {
6350                         XS_SETERR(xs, HBA_TGTBSY);
6351                 }
6352                 return;
6353
6354         default:
6355                 isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
6356                     sp->req_completion_status);
6357                 break;
6358         }
6359         if (XS_NOERR(xs)) {
6360                 XS_SETERR(xs, HBA_BOTCH);
6361         }
6362 }
6363
6364 static void
6365 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs, long *rp)
6366 {
6367         int ru_marked, sv_marked;
6368         int chan = XS_CHANNEL(xs);
6369
6370         switch (sp->req_completion_status) {
6371         case RQCS_COMPLETE:
6372                 if (XS_NOERR(xs)) {
6373                         XS_SETERR(xs, HBA_NOERROR);
6374                 }
6375                 return;
6376
6377         case RQCS_DMA_ERROR:
6378                 isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error");
6379                 break;
6380
6381         case RQCS_TRANSPORT_ERROR:
6382                 isp_xs_prt(isp, xs,  ISP_LOGERR, "Transport Error");
6383                 break;
6384
6385         case RQCS_RESET_OCCURRED:
6386                 isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command");
6387                 FCPARAM(isp, chan)->sendmarker = 1;
6388                 if (XS_NOERR(xs)) {
6389                         XS_SETERR(xs, HBA_BUSRESET);
6390                 }
6391                 return;
6392
6393         case RQCS_ABORTED:
6394                 isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
6395                 FCPARAM(isp, chan)->sendmarker = 1;
6396                 if (XS_NOERR(xs)) {
6397                         XS_SETERR(xs, HBA_ABORTED);
6398                 }
6399                 return;
6400
6401         case RQCS_TIMEOUT:
6402                 isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out");
6403                 if (XS_NOERR(xs)) {
6404                         XS_SETERR(xs, HBA_CMDTIMEOUT);
6405                 }
6406                 return;
6407
6408         case RQCS_DATA_OVERRUN:
6409                 XS_SET_RESID(xs, sp->req_resid);
6410                 isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun");
6411                 if (XS_NOERR(xs)) {
6412                         XS_SETERR(xs, HBA_DATAOVR);
6413                 }
6414                 return;
6415
6416         case RQCS_24XX_DRE:     /* data reassembly error */
6417                 isp_prt(isp, ISP_LOGERR,
6418                     "Chan %d data reassembly error for target %d",
6419                     chan, XS_TGT(xs));
6420                 if (XS_NOERR(xs)) {
6421                         XS_SETERR(xs, HBA_ABORTED);
6422                 }
6423                 *rp = XS_XFRLEN(xs);
6424                 return;
6425
6426         case RQCS_24XX_TABORT:  /* aborted by target */
6427                 isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS",
6428                     chan, XS_TGT(xs));
6429                 if (XS_NOERR(xs)) {
6430                         XS_SETERR(xs, HBA_ABORTED);
6431                 }
6432                 return;
6433
6434         case RQCS_DATA_UNDERRUN:
6435                 ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
6436                 /*
6437                  * We can get an underrun w/o things being marked
6438                  * if we got a non-zero status.
6439                  */
6440                 sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
6441                 if ((ru_marked == 0 && sv_marked == 0) ||
6442                     (sp->req_resid > XS_XFRLEN(xs))) {
6443                         isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
6444                         if (XS_NOERR(xs)) {
6445                                 XS_SETERR(xs, HBA_BOTCH);
6446                         }
6447                         return;
6448                 }
6449                 XS_SET_RESID(xs, sp->req_resid);
6450                 isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff);
6451                 if (XS_NOERR(xs)) {
6452                         XS_SETERR(xs, HBA_NOERROR);
6453                 }
6454                 return;
6455
6456         case RQCS_PORT_UNAVAILABLE:
6457                 /*
6458                  * No such port on the loop. Moral equivalent of SELTIMEO
6459                  */
6460         case RQCS_PORT_LOGGED_OUT:
6461         {
6462                 const char *reason;
6463                 uint8_t sts = sp->req_completion_status & 0xff;
6464
6465                 /*
6466                  * It was there (maybe)- treat as a selection timeout.
6467                  */
6468                 if (sts == RQCS_PORT_UNAVAILABLE) {
6469                         reason = "unavailable";
6470                 } else {
6471                         reason = "logout";
6472                 }
6473
6474                 isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d",
6475                     chan, reason, XS_TGT(xs));
6476
6477                 /*
6478                  * There is no MBOX_INIT_LIP for the 24XX.
6479                  */
6480                 if (XS_NOERR(xs)) {
6481                         XS_SETERR(xs, HBA_SELTIMEOUT);
6482                 }
6483                 return;
6484         }
6485         case RQCS_PORT_CHANGED:
6486                 isp_prt(isp, ISP_LOGWARN,
6487                     "port changed for target %d chan %d", XS_TGT(xs), chan);
6488                 if (XS_NOERR(xs)) {
6489                         XS_SETERR(xs, HBA_SELTIMEOUT);
6490                 }
6491                 return;
6492
6493
6494         case RQCS_24XX_ENOMEM:  /* f/w resource unavailable */
6495                 isp_prt(isp, ISP_LOGWARN,
6496                     "f/w resource unavailable for target %d chan %d",
6497                     XS_TGT(xs), chan);
6498                 if (XS_NOERR(xs)) {
6499                         *XS_STSP(xs) = SCSI_BUSY;
6500                         XS_SETERR(xs, HBA_TGTBSY);
6501                 }
6502                 return;
6503
6504         case RQCS_24XX_TMO:     /* task management overrun */
6505                 isp_prt(isp, ISP_LOGWARN,
6506                     "command for target %d overlapped task management for "
6507                     "chan %d", XS_TGT(xs), chan);
6508                 if (XS_NOERR(xs)) {
6509                         *XS_STSP(xs) = SCSI_BUSY;
6510                         XS_SETERR(xs, HBA_TGTBSY);
6511                 }
6512                 return;
6513
6514         default:
6515                 isp_prt(isp, ISP_LOGERR,
6516                     "Unknown Completion Status 0x%x on chan %d",
6517                     sp->req_completion_status, chan);
6518                 break;
6519         }
6520         if (XS_NOERR(xs)) {
6521                 XS_SETERR(xs, HBA_BOTCH);
6522         }
6523 }
6524
6525 static void
6526 isp_fastpost_complete(ispsoftc_t *isp, uint32_t fph)
6527 {
6528         XS_T *xs;
6529
6530         if (fph == 0) {
6531                 return;
6532         }
6533         xs = isp_find_xs(isp, fph);
6534         if (xs == NULL) {
6535                 isp_prt(isp, ISP_LOGWARN,
6536                     "Command for fast post handle 0x%x not found", fph);
6537                 return;
6538         }
6539         isp_destroy_handle(isp, fph);
6540
6541         /*
6542          * Since we don't have a result queue entry item,
6543          * we must believe that SCSI status is zero and
6544          * that all data transferred.
6545          */
6546         XS_SET_RESID(xs, 0);
6547         *XS_STSP(xs) = SCSI_GOOD;
6548         if (XS_XFRLEN(xs)) {
6549                 ISP_DMAFREE(isp, xs, fph);
6550         }
6551         if (isp->isp_nactive) {
6552                 isp->isp_nactive--;
6553         }
6554         isp->isp_fphccmplt++;
6555         isp_done(xs);
6556 }
6557
6558 static int
6559 isp_mbox_continue(ispsoftc_t *isp)
6560 {
6561         mbreg_t mbs;
6562         uint16_t *ptr;
6563         uint32_t offset;
6564
6565         switch (isp->isp_lastmbxcmd) {
6566         case MBOX_WRITE_RAM_WORD:
6567         case MBOX_READ_RAM_WORD:
6568         case MBOX_WRITE_RAM_WORD_EXTENDED:
6569         case MBOX_READ_RAM_WORD_EXTENDED:
6570                 break;
6571         default:
6572                 return (1);
6573         }
6574         if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
6575                 isp->isp_mbxwrk0 = 0;
6576                 return (-1);
6577         }
6578
6579         /*
6580          * Clear the previous interrupt.
6581          */
6582         if (IS_24XX(isp)) {
6583                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
6584         } else {
6585                 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
6586                 ISP_WRITE(isp, BIU_SEMA, 0);
6587         }
6588
6589         /*
6590          * Continue with next word.
6591          */
6592         ISP_MEMZERO(&mbs, sizeof (mbs));
6593         ptr = isp->isp_mbxworkp;
6594         switch (isp->isp_lastmbxcmd) {
6595         case MBOX_WRITE_RAM_WORD:
6596                 mbs.param[1] = isp->isp_mbxwrk1++;
6597                 mbs.param[2] = *ptr++;
6598                 break;
6599         case MBOX_READ_RAM_WORD:
6600                 *ptr++ = isp->isp_mboxtmp[2];
6601                 mbs.param[1] = isp->isp_mbxwrk1++;
6602                 break;
6603         case MBOX_WRITE_RAM_WORD_EXTENDED:
6604                 if (IS_24XX(isp)) {
6605                         uint32_t *lptr = (uint32_t *)ptr;
6606                         mbs.param[2] = lptr[0];
6607                         mbs.param[3] = lptr[0] >> 16;
6608                         lptr++;
6609                         ptr = (uint16_t *)lptr;
6610                 } else {
6611                         mbs.param[2] = *ptr++;
6612                 }
6613                 offset = isp->isp_mbxwrk1;
6614                 offset |= isp->isp_mbxwrk8 << 16;
6615                 mbs.param[1] = offset;
6616                 mbs.param[8] = offset >> 16;
6617                 offset++;
6618                 isp->isp_mbxwrk1 = offset;
6619                 isp->isp_mbxwrk8 = offset >> 16;
6620                 break;
6621         case MBOX_READ_RAM_WORD_EXTENDED:
6622                 if (IS_24XX(isp)) {
6623                         uint32_t *lptr = (uint32_t *)ptr;
6624                         uint32_t val = isp->isp_mboxtmp[2];
6625                         val |= (isp->isp_mboxtmp[3]) << 16;
6626                         *lptr++ = val;
6627                         ptr = (uint16_t *)lptr;
6628                 } else {
6629                         *ptr++ = isp->isp_mboxtmp[2];
6630                 }
6631                 offset = isp->isp_mbxwrk1;
6632                 offset |= isp->isp_mbxwrk8 << 16;
6633                 mbs.param[1] = offset;
6634                 mbs.param[8] = offset >> 16;
6635                 offset++;
6636                 isp->isp_mbxwrk1 = offset;
6637                 isp->isp_mbxwrk8 = offset >> 16;
6638                 break;
6639         }
6640         isp->isp_mbxworkp = ptr;
6641         isp->isp_mbxwrk0--;
6642         mbs.param[0] = isp->isp_lastmbxcmd;
6643         mbs.logval = MBLOGALL;
6644         isp_mboxcmd_qnw(isp, &mbs, 0);
6645         return (0);
6646 }
6647
6648 #define HIWRD(x)                        ((x) >> 16)
6649 #define LOWRD(x)                        ((x)  & 0xffff)
6650 #define ISPOPMAP(a, b)                  (((a) << 16) | (b))
6651 static const uint32_t mbpscsi[] = {
6652         ISPOPMAP(0x01, 0x01),   /* 0x00: MBOX_NO_OP */
6653         ISPOPMAP(0x1f, 0x01),   /* 0x01: MBOX_LOAD_RAM */
6654         ISPOPMAP(0x03, 0x01),   /* 0x02: MBOX_EXEC_FIRMWARE */
6655         ISPOPMAP(0x1f, 0x01),   /* 0x03: MBOX_DUMP_RAM */
6656         ISPOPMAP(0x07, 0x07),   /* 0x04: MBOX_WRITE_RAM_WORD */
6657         ISPOPMAP(0x03, 0x07),   /* 0x05: MBOX_READ_RAM_WORD */
6658         ISPOPMAP(0x3f, 0x3f),   /* 0x06: MBOX_MAILBOX_REG_TEST */
6659         ISPOPMAP(0x07, 0x07),   /* 0x07: MBOX_VERIFY_CHECKSUM   */
6660         ISPOPMAP(0x01, 0x0f),   /* 0x08: MBOX_ABOUT_FIRMWARE */
6661         ISPOPMAP(0x00, 0x00),   /* 0x09: */
6662         ISPOPMAP(0x00, 0x00),   /* 0x0a: */
6663         ISPOPMAP(0x00, 0x00),   /* 0x0b: */
6664         ISPOPMAP(0x00, 0x00),   /* 0x0c: */
6665         ISPOPMAP(0x00, 0x00),   /* 0x0d: */
6666         ISPOPMAP(0x01, 0x05),   /* 0x0e: MBOX_CHECK_FIRMWARE */
6667         ISPOPMAP(0x00, 0x00),   /* 0x0f: */
6668         ISPOPMAP(0x1f, 0x1f),   /* 0x10: MBOX_INIT_REQ_QUEUE */
6669         ISPOPMAP(0x3f, 0x3f),   /* 0x11: MBOX_INIT_RES_QUEUE */
6670         ISPOPMAP(0x0f, 0x0f),   /* 0x12: MBOX_EXECUTE_IOCB */
6671         ISPOPMAP(0x03, 0x03),   /* 0x13: MBOX_WAKE_UP   */
6672         ISPOPMAP(0x01, 0x3f),   /* 0x14: MBOX_STOP_FIRMWARE */
6673         ISPOPMAP(0x0f, 0x0f),   /* 0x15: MBOX_ABORT */
6674         ISPOPMAP(0x03, 0x03),   /* 0x16: MBOX_ABORT_DEVICE */
6675         ISPOPMAP(0x07, 0x07),   /* 0x17: MBOX_ABORT_TARGET */
6676         ISPOPMAP(0x07, 0x07),   /* 0x18: MBOX_BUS_RESET */
6677         ISPOPMAP(0x03, 0x07),   /* 0x19: MBOX_STOP_QUEUE */
6678         ISPOPMAP(0x03, 0x07),   /* 0x1a: MBOX_START_QUEUE */
6679         ISPOPMAP(0x03, 0x07),   /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6680         ISPOPMAP(0x03, 0x07),   /* 0x1c: MBOX_ABORT_QUEUE */
6681         ISPOPMAP(0x03, 0x4f),   /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6682         ISPOPMAP(0x00, 0x00),   /* 0x1e: */
6683         ISPOPMAP(0x01, 0x07),   /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6684         ISPOPMAP(0x01, 0x07),   /* 0x20: MBOX_GET_INIT_SCSI_ID */
6685         ISPOPMAP(0x01, 0x07),   /* 0x21: MBOX_GET_SELECT_TIMEOUT */
6686         ISPOPMAP(0x01, 0xc7),   /* 0x22: MBOX_GET_RETRY_COUNT   */
6687         ISPOPMAP(0x01, 0x07),   /* 0x23: MBOX_GET_TAG_AGE_LIMIT */
6688         ISPOPMAP(0x01, 0x03),   /* 0x24: MBOX_GET_CLOCK_RATE */
6689         ISPOPMAP(0x01, 0x07),   /* 0x25: MBOX_GET_ACT_NEG_STATE */
6690         ISPOPMAP(0x01, 0x07),   /* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
6691         ISPOPMAP(0x01, 0x07),   /* 0x27: MBOX_GET_PCI_PARAMS */
6692         ISPOPMAP(0x03, 0x4f),   /* 0x28: MBOX_GET_TARGET_PARAMS */
6693         ISPOPMAP(0x03, 0x0f),   /* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
6694         ISPOPMAP(0x01, 0x07),   /* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
6695         ISPOPMAP(0x00, 0x00),   /* 0x2b: */
6696         ISPOPMAP(0x00, 0x00),   /* 0x2c: */
6697         ISPOPMAP(0x00, 0x00),   /* 0x2d: */
6698         ISPOPMAP(0x00, 0x00),   /* 0x2e: */
6699         ISPOPMAP(0x00, 0x00),   /* 0x2f: */
6700         ISPOPMAP(0x03, 0x03),   /* 0x30: MBOX_SET_INIT_SCSI_ID */
6701         ISPOPMAP(0x07, 0x07),   /* 0x31: MBOX_SET_SELECT_TIMEOUT */
6702         ISPOPMAP(0xc7, 0xc7),   /* 0x32: MBOX_SET_RETRY_COUNT   */
6703         ISPOPMAP(0x07, 0x07),   /* 0x33: MBOX_SET_TAG_AGE_LIMIT */
6704         ISPOPMAP(0x03, 0x03),   /* 0x34: MBOX_SET_CLOCK_RATE */
6705         ISPOPMAP(0x07, 0x07),   /* 0x35: MBOX_SET_ACT_NEG_STATE */
6706         ISPOPMAP(0x07, 0x07),   /* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
6707         ISPOPMAP(0x07, 0x07),   /* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
6708         ISPOPMAP(0x4f, 0x4f),   /* 0x38: MBOX_SET_TARGET_PARAMS */
6709         ISPOPMAP(0x0f, 0x0f),   /* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
6710         ISPOPMAP(0x07, 0x07),   /* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
6711         ISPOPMAP(0x00, 0x00),   /* 0x3b: */
6712         ISPOPMAP(0x00, 0x00),   /* 0x3c: */
6713         ISPOPMAP(0x00, 0x00),   /* 0x3d: */
6714         ISPOPMAP(0x00, 0x00),   /* 0x3e: */
6715         ISPOPMAP(0x00, 0x00),   /* 0x3f: */
6716         ISPOPMAP(0x01, 0x03),   /* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
6717         ISPOPMAP(0x3f, 0x01),   /* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
6718         ISPOPMAP(0x03, 0x07),   /* 0x42: MBOX_EXEC_BIOS_IOCB */
6719         ISPOPMAP(0x00, 0x00),   /* 0x43: */
6720         ISPOPMAP(0x00, 0x00),   /* 0x44: */
6721         ISPOPMAP(0x03, 0x03),   /* 0x45: SET SYSTEM PARAMETER */
6722         ISPOPMAP(0x01, 0x03),   /* 0x46: GET SYSTEM PARAMETER */
6723         ISPOPMAP(0x00, 0x00),   /* 0x47: */
6724         ISPOPMAP(0x01, 0xcf),   /* 0x48: GET SCAM CONFIGURATION */
6725         ISPOPMAP(0xcf, 0xcf),   /* 0x49: SET SCAM CONFIGURATION */
6726         ISPOPMAP(0x03, 0x03),   /* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
6727         ISPOPMAP(0x01, 0x03),   /* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
6728         ISPOPMAP(0x00, 0x00),   /* 0x4c: */
6729         ISPOPMAP(0x00, 0x00),   /* 0x4d: */
6730         ISPOPMAP(0x00, 0x00),   /* 0x4e: */
6731         ISPOPMAP(0x00, 0x00),   /* 0x4f: */
6732         ISPOPMAP(0xdf, 0xdf),   /* 0x50: LOAD RAM A64 */
6733         ISPOPMAP(0xdf, 0xdf),   /* 0x51: DUMP RAM A64 */
6734         ISPOPMAP(0xdf, 0xff),   /* 0x52: INITIALIZE REQUEST QUEUE A64 */
6735         ISPOPMAP(0xef, 0xff),   /* 0x53: INITIALIZE RESPONSE QUEUE A64 */
6736         ISPOPMAP(0xcf, 0x01),   /* 0x54: EXECUCUTE COMMAND IOCB A64 */
6737         ISPOPMAP(0x07, 0x01),   /* 0x55: ENABLE TARGET MODE */
6738         ISPOPMAP(0x03, 0x0f),   /* 0x56: GET TARGET STATUS */
6739         ISPOPMAP(0x00, 0x00),   /* 0x57: */
6740         ISPOPMAP(0x00, 0x00),   /* 0x58: */
6741         ISPOPMAP(0x00, 0x00),   /* 0x59: */
6742         ISPOPMAP(0x03, 0x03),   /* 0x5a: SET DATA OVERRUN RECOVERY MODE */
6743         ISPOPMAP(0x01, 0x03),   /* 0x5b: GET DATA OVERRUN RECOVERY MODE */
6744         ISPOPMAP(0x0f, 0x0f),   /* 0x5c: SET HOST DATA */
6745         ISPOPMAP(0x01, 0x01)    /* 0x5d: GET NOST DATA */
6746 };
6747
6748 static const char *scsi_mbcmd_names[] = {
6749         "NO-OP",
6750         "LOAD RAM",
6751         "EXEC FIRMWARE",
6752         "DUMP RAM",
6753         "WRITE RAM WORD",
6754         "READ RAM WORD",
6755         "MAILBOX REG TEST",
6756         "VERIFY CHECKSUM",
6757         "ABOUT FIRMWARE",
6758         NULL,
6759         NULL,
6760         NULL,
6761         NULL,
6762         NULL,
6763         "CHECK FIRMWARE",
6764         NULL,
6765         "INIT REQUEST QUEUE",
6766         "INIT RESULT QUEUE",
6767         "EXECUTE IOCB",
6768         "WAKE UP",
6769         "STOP FIRMWARE",
6770         "ABORT",
6771         "ABORT DEVICE",
6772         "ABORT TARGET",
6773         "BUS RESET",
6774         "STOP QUEUE",
6775         "START QUEUE",
6776         "SINGLE STEP QUEUE",
6777         "ABORT QUEUE",
6778         "GET DEV QUEUE STATUS",
6779         NULL,
6780         "GET FIRMWARE STATUS",
6781         "GET INIT SCSI ID",
6782         "GET SELECT TIMEOUT",
6783         "GET RETRY COUNT",
6784         "GET TAG AGE LIMIT",
6785         "GET CLOCK RATE",
6786         "GET ACT NEG STATE",
6787         "GET ASYNC DATA SETUP TIME",
6788         "GET PCI PARAMS",
6789         "GET TARGET PARAMS",
6790         "GET DEV QUEUE PARAMS",
6791         "GET RESET DELAY PARAMS",
6792         NULL,
6793         NULL,
6794         NULL,
6795         NULL,
6796         NULL,
6797         "SET INIT SCSI ID",
6798         "SET SELECT TIMEOUT",
6799         "SET RETRY COUNT",
6800         "SET TAG AGE LIMIT",
6801         "SET CLOCK RATE",
6802         "SET ACT NEG STATE",
6803         "SET ASYNC DATA SETUP TIME",
6804         "SET PCI CONTROL PARAMS",
6805         "SET TARGET PARAMS",
6806         "SET DEV QUEUE PARAMS",
6807         "SET RESET DELAY PARAMS",
6808         NULL,
6809         NULL,
6810         NULL,
6811         NULL,
6812         NULL,
6813         "RETURN BIOS BLOCK ADDR",
6814         "WRITE FOUR RAM WORDS",
6815         "EXEC BIOS IOCB",
6816         NULL,
6817         NULL,
6818         "SET SYSTEM PARAMETER",
6819         "GET SYSTEM PARAMETER",
6820         NULL,
6821         "GET SCAM CONFIGURATION",
6822         "SET SCAM CONFIGURATION",
6823         "SET FIRMWARE FEATURES",
6824         "GET FIRMWARE FEATURES",
6825         NULL,
6826         NULL,
6827         NULL,
6828         NULL,
6829         "LOAD RAM A64",
6830         "DUMP RAM A64",
6831         "INITIALIZE REQUEST QUEUE A64",
6832         "INITIALIZE RESPONSE QUEUE A64",
6833         "EXECUTE IOCB A64",
6834         "ENABLE TARGET MODE",
6835         "GET TARGET MODE STATE",
6836         NULL,
6837         NULL,
6838         NULL,
6839         "SET DATA OVERRUN RECOVERY MODE",
6840         "GET DATA OVERRUN RECOVERY MODE",
6841         "SET HOST DATA",
6842         "GET NOST DATA",
6843 };
6844
6845 static const uint32_t mbpfc[] = {
6846         ISPOPMAP(0x01, 0x01),   /* 0x00: MBOX_NO_OP */
6847         ISPOPMAP(0x1f, 0x01),   /* 0x01: MBOX_LOAD_RAM */
6848         ISPOPMAP(0x0f, 0x01),   /* 0x02: MBOX_EXEC_FIRMWARE */
6849         ISPOPMAP(0xdf, 0x01),   /* 0x03: MBOX_DUMP_RAM */
6850         ISPOPMAP(0x07, 0x07),   /* 0x04: MBOX_WRITE_RAM_WORD */
6851         ISPOPMAP(0x03, 0x07),   /* 0x05: MBOX_READ_RAM_WORD */
6852         ISPOPMAP(0xff, 0xff),   /* 0x06: MBOX_MAILBOX_REG_TEST */
6853         ISPOPMAP(0x07, 0x07),   /* 0x07: MBOX_VERIFY_CHECKSUM   */
6854         ISPOPMAP(0x01, 0x4f),   /* 0x08: MBOX_ABOUT_FIRMWARE */
6855         ISPOPMAP(0xdf, 0x01),   /* 0x09: MBOX_LOAD_RISC_RAM_2100 */
6856         ISPOPMAP(0xdf, 0x01),   /* 0x0a: DUMP RAM */
6857         ISPOPMAP(0x1ff, 0x01),  /* 0x0b: MBOX_LOAD_RISC_RAM */
6858         ISPOPMAP(0x00, 0x00),   /* 0x0c: */
6859         ISPOPMAP(0x10f, 0x01),  /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
6860         ISPOPMAP(0x01, 0x05),   /* 0x0e: MBOX_CHECK_FIRMWARE */
6861         ISPOPMAP(0x103, 0x0d),  /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
6862         ISPOPMAP(0x1f, 0x11),   /* 0x10: MBOX_INIT_REQ_QUEUE */
6863         ISPOPMAP(0x2f, 0x21),   /* 0x11: MBOX_INIT_RES_QUEUE */
6864         ISPOPMAP(0x0f, 0x01),   /* 0x12: MBOX_EXECUTE_IOCB */
6865         ISPOPMAP(0x03, 0x03),   /* 0x13: MBOX_WAKE_UP   */
6866         ISPOPMAP(0x01, 0xff),   /* 0x14: MBOX_STOP_FIRMWARE */
6867         ISPOPMAP(0x4f, 0x01),   /* 0x15: MBOX_ABORT */
6868         ISPOPMAP(0x07, 0x01),   /* 0x16: MBOX_ABORT_DEVICE */
6869         ISPOPMAP(0x07, 0x01),   /* 0x17: MBOX_ABORT_TARGET */
6870         ISPOPMAP(0x03, 0x03),   /* 0x18: MBOX_BUS_RESET */
6871         ISPOPMAP(0x07, 0x05),   /* 0x19: MBOX_STOP_QUEUE */
6872         ISPOPMAP(0x07, 0x05),   /* 0x1a: MBOX_START_QUEUE */
6873         ISPOPMAP(0x07, 0x05),   /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6874         ISPOPMAP(0x07, 0x05),   /* 0x1c: MBOX_ABORT_QUEUE */
6875         ISPOPMAP(0x07, 0x03),   /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6876         ISPOPMAP(0x00, 0x00),   /* 0x1e: */
6877         ISPOPMAP(0x01, 0x07),   /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6878         ISPOPMAP(0x01, 0x4f),   /* 0x20: MBOX_GET_LOOP_ID */
6879         ISPOPMAP(0x00, 0x00),   /* 0x21: */
6880         ISPOPMAP(0x01, 0x07),   /* 0x22: MBOX_GET_RETRY_COUNT   */
6881         ISPOPMAP(0x00, 0x00),   /* 0x23: */
6882         ISPOPMAP(0x00, 0x00),   /* 0x24: */
6883         ISPOPMAP(0x00, 0x00),   /* 0x25: */
6884         ISPOPMAP(0x00, 0x00),   /* 0x26: */
6885         ISPOPMAP(0x00, 0x00),   /* 0x27: */
6886         ISPOPMAP(0x01, 0x03),   /* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
6887         ISPOPMAP(0x03, 0x07),   /* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
6888         ISPOPMAP(0x00, 0x00),   /* 0x2a: */
6889         ISPOPMAP(0x00, 0x00),   /* 0x2b: */
6890         ISPOPMAP(0x00, 0x00),   /* 0x2c: */
6891         ISPOPMAP(0x00, 0x00),   /* 0x2d: */
6892         ISPOPMAP(0x00, 0x00),   /* 0x2e: */
6893         ISPOPMAP(0x00, 0x00),   /* 0x2f: */
6894         ISPOPMAP(0x00, 0x00),   /* 0x30: */
6895         ISPOPMAP(0x00, 0x00),   /* 0x31: */
6896         ISPOPMAP(0x07, 0x07),   /* 0x32: MBOX_SET_RETRY_COUNT   */
6897         ISPOPMAP(0x00, 0x00),   /* 0x33: */
6898         ISPOPMAP(0x00, 0x00),   /* 0x34: */
6899         ISPOPMAP(0x00, 0x00),   /* 0x35: */
6900         ISPOPMAP(0x00, 0x00),   /* 0x36: */
6901         ISPOPMAP(0x00, 0x00),   /* 0x37: */
6902         ISPOPMAP(0x0f, 0x01),   /* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
6903         ISPOPMAP(0x0f, 0x07),   /* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
6904         ISPOPMAP(0x00, 0x00),   /* 0x3a: */
6905         ISPOPMAP(0x00, 0x00),   /* 0x3b: */
6906         ISPOPMAP(0x00, 0x00),   /* 0x3c: */
6907         ISPOPMAP(0x00, 0x00),   /* 0x3d: */
6908         ISPOPMAP(0x00, 0x00),   /* 0x3e: */
6909         ISPOPMAP(0x00, 0x00),   /* 0x3f: */
6910         ISPOPMAP(0x03, 0x01),   /* 0x40: MBOX_LOOP_PORT_BYPASS */
6911         ISPOPMAP(0x03, 0x01),   /* 0x41: MBOX_LOOP_PORT_ENABLE */
6912         ISPOPMAP(0x03, 0x07),   /* 0x42: MBOX_GET_RESOURCE_COUNT */
6913         ISPOPMAP(0x01, 0x01),   /* 0x43: MBOX_REQUEST_OFFLINE_MODE */
6914         ISPOPMAP(0x00, 0x00),   /* 0x44: */
6915         ISPOPMAP(0x00, 0x00),   /* 0x45: */
6916         ISPOPMAP(0x00, 0x00),   /* 0x46: */
6917         ISPOPMAP(0xcf, 0x03),   /* 0x47: GET PORT_DATABASE ENHANCED */
6918         ISPOPMAP(0xcd, 0x01),   /* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */
6919         ISPOPMAP(0xcd, 0x01),   /* 0x49: MBOX_GET_VP_DATABASE */
6920         ISPOPMAP(0x2cd, 0x01),  /* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */
6921         ISPOPMAP(0x00, 0x00),   /* 0x4b: */
6922         ISPOPMAP(0x00, 0x00),   /* 0x4c: */
6923         ISPOPMAP(0x00, 0x00),   /* 0x4d: */
6924         ISPOPMAP(0x00, 0x00),   /* 0x4e: */
6925         ISPOPMAP(0x00, 0x00),   /* 0x4f: */
6926         ISPOPMAP(0x00, 0x00),   /* 0x50: */
6927         ISPOPMAP(0x00, 0x00),   /* 0x51: */
6928         ISPOPMAP(0x00, 0x00),   /* 0x52: */
6929         ISPOPMAP(0x00, 0x00),   /* 0x53: */
6930         ISPOPMAP(0xcf, 0x01),   /* 0x54: EXECUTE IOCB A64 */
6931         ISPOPMAP(0x00, 0x00),   /* 0x55: */
6932         ISPOPMAP(0x00, 0x00),   /* 0x56: */
6933         ISPOPMAP(0x00, 0x00),   /* 0x57: */
6934         ISPOPMAP(0x00, 0x00),   /* 0x58: */
6935         ISPOPMAP(0x00, 0x00),   /* 0x59: */
6936         ISPOPMAP(0x00, 0x00),   /* 0x5a: */
6937         ISPOPMAP(0x03, 0x01),   /* 0x5b: MBOX_DRIVER_HEARTBEAT */
6938         ISPOPMAP(0xcf, 0x01),   /* 0x5c: MBOX_FW_HEARTBEAT */
6939         ISPOPMAP(0x07, 0x03),   /* 0x5d: MBOX_GET_SET_DATA_RATE */
6940         ISPOPMAP(0x00, 0x00),   /* 0x5e: */
6941         ISPOPMAP(0x00, 0x00),   /* 0x5f: */
6942         ISPOPMAP(0xcd, 0x01),   /* 0x60: MBOX_INIT_FIRMWARE */
6943         ISPOPMAP(0x00, 0x00),   /* 0x61: */
6944         ISPOPMAP(0x01, 0x01),   /* 0x62: MBOX_INIT_LIP */
6945         ISPOPMAP(0xcd, 0x03),   /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
6946         ISPOPMAP(0xcf, 0x01),   /* 0x64: MBOX_GET_PORT_DB */
6947         ISPOPMAP(0x07, 0x01),   /* 0x65: MBOX_CLEAR_ACA */
6948         ISPOPMAP(0x07, 0x01),   /* 0x66: MBOX_TARGET_RESET */
6949         ISPOPMAP(0x07, 0x01),   /* 0x67: MBOX_CLEAR_TASK_SET */
6950         ISPOPMAP(0x07, 0x01),   /* 0x68: MBOX_ABORT_TASK_SET */
6951         ISPOPMAP(0x01, 0x07),   /* 0x69: MBOX_GET_FW_STATE */
6952         ISPOPMAP(0x03, 0xcf),   /* 0x6a: MBOX_GET_PORT_NAME */
6953         ISPOPMAP(0xcf, 0x01),   /* 0x6b: MBOX_GET_LINK_STATUS */
6954         ISPOPMAP(0x0f, 0x01),   /* 0x6c: MBOX_INIT_LIP_RESET */
6955         ISPOPMAP(0x00, 0x00),   /* 0x6d: */
6956         ISPOPMAP(0xcf, 0x03),   /* 0x6e: MBOX_SEND_SNS */
6957         ISPOPMAP(0x0f, 0x07),   /* 0x6f: MBOX_FABRIC_LOGIN */
6958         ISPOPMAP(0x03, 0x01),   /* 0x70: MBOX_SEND_CHANGE_REQUEST */
6959         ISPOPMAP(0x03, 0x03),   /* 0x71: MBOX_FABRIC_LOGOUT */
6960         ISPOPMAP(0x0f, 0x0f),   /* 0x72: MBOX_INIT_LIP_LOGIN */
6961         ISPOPMAP(0x00, 0x00),   /* 0x73: */
6962         ISPOPMAP(0x07, 0x01),   /* 0x74: LOGIN LOOP PORT */
6963         ISPOPMAP(0xcf, 0x03),   /* 0x75: GET PORT/NODE NAME LIST */
6964         ISPOPMAP(0x4f, 0x01),   /* 0x76: SET VENDOR ID */
6965         ISPOPMAP(0xcd, 0x01),   /* 0x77: INITIALIZE IP MAILBOX */
6966         ISPOPMAP(0x00, 0x00),   /* 0x78: */
6967         ISPOPMAP(0x00, 0x00),   /* 0x79: */
6968         ISPOPMAP(0x00, 0x00),   /* 0x7a: */
6969         ISPOPMAP(0x00, 0x00),   /* 0x7b: */
6970         ISPOPMAP(0x4f, 0x03),   /* 0x7c: Get ID List */
6971         ISPOPMAP(0xcf, 0x01),   /* 0x7d: SEND LFA */
6972         ISPOPMAP(0x0f, 0x01)    /* 0x7e: LUN RESET */
6973 };
6974 /*
6975  * Footnotes
6976  *
6977  * (1): this sets bits 21..16 in mailbox register #8, which we nominally
6978  *      do not access at this time in the core driver. The caller is
6979  *      responsible for setting this register first (Gross!). The assumption
6980  *      is that we won't overflow.
6981  */
6982
6983 static const char *fc_mbcmd_names[] = {
6984         "NO-OP",
6985         "LOAD RAM",
6986         "EXEC FIRMWARE",
6987         "DUMP RAM",
6988         "WRITE RAM WORD",
6989         "READ RAM WORD",
6990         "MAILBOX REG TEST",
6991         "VERIFY CHECKSUM",
6992         "ABOUT FIRMWARE",
6993         "LOAD RAM (2100)",
6994         "DUMP RAM",
6995         "LOAD RISC RAM",
6996         NULL,
6997         "WRITE RAM WORD EXTENDED",
6998         "CHECK FIRMWARE",
6999         "READ RAM WORD EXTENDED",
7000         "INIT REQUEST QUEUE",
7001         "INIT RESULT QUEUE",
7002         "EXECUTE IOCB",
7003         "WAKE UP",
7004         "STOP FIRMWARE",
7005         "ABORT",
7006         "ABORT DEVICE",
7007         "ABORT TARGET",
7008         "BUS RESET",
7009         "STOP QUEUE",
7010         "START QUEUE",
7011         "SINGLE STEP QUEUE",
7012         "ABORT QUEUE",
7013         "GET DEV QUEUE STATUS",
7014         NULL,
7015         "GET FIRMWARE STATUS",
7016         "GET LOOP ID",
7017         NULL,
7018         "GET RETRY COUNT",
7019         NULL,
7020         NULL,
7021         NULL,
7022         NULL,
7023         NULL,
7024         "GET FIRMWARE OPTIONS",
7025         "GET PORT QUEUE PARAMS",
7026         NULL,
7027         NULL,
7028         NULL,
7029         NULL,
7030         NULL,
7031         NULL,
7032         NULL,
7033         NULL,
7034         "SET RETRY COUNT",
7035         NULL,
7036         NULL,
7037         NULL,
7038         NULL,
7039         NULL,
7040         "SET FIRMWARE OPTIONS",
7041         "SET PORT QUEUE PARAMS",
7042         NULL,
7043         NULL,
7044         NULL,
7045         NULL,
7046         NULL,
7047         NULL,
7048         "LOOP PORT BYPASS",
7049         "LOOP PORT ENABLE",
7050         "GET RESOURCE COUNT",
7051         "REQUEST NON PARTICIPATING MODE",
7052         NULL,
7053         NULL,
7054         NULL,
7055         "GET PORT DATABASE ENHANCED",
7056         "INIT FIRMWARE MULTI ID",
7057         "GET VP DATABASE",
7058         "GET VP DATABASE ENTRY",
7059         NULL,
7060         NULL,
7061         NULL,
7062         NULL,
7063         NULL,
7064         NULL,
7065         NULL,
7066         NULL,
7067         NULL,
7068         "EXECUTE IOCB A64",
7069         NULL,
7070         NULL,
7071         NULL,
7072         NULL,
7073         NULL,
7074         NULL,
7075         "DRIVER HEARTBEAT",
7076         NULL,
7077         "GET/SET DATA RATE",
7078         NULL,
7079         NULL,
7080         "INIT FIRMWARE",
7081         NULL,
7082         "INIT LIP",
7083         "GET FC-AL POSITION MAP",
7084         "GET PORT DATABASE",
7085         "CLEAR ACA",
7086         "TARGET RESET",
7087         "CLEAR TASK SET",
7088         "ABORT TASK SET",
7089         "GET FW STATE",
7090         "GET PORT NAME",
7091         "GET LINK STATUS",
7092         "INIT LIP RESET",
7093         NULL,
7094         "SEND SNS",
7095         "FABRIC LOGIN",
7096         "SEND CHANGE REQUEST",
7097         "FABRIC LOGOUT",
7098         "INIT LIP LOGIN",
7099         NULL,
7100         "LOGIN LOOP PORT",
7101         "GET PORT/NODE NAME LIST",
7102         "SET VENDOR ID",
7103         "INITIALIZE IP MAILBOX",
7104         NULL,
7105         NULL,
7106         NULL,
7107         NULL,
7108         "Get ID List",
7109         "SEND LFA",
7110         "Lun RESET"
7111 };
7112
7113 static void
7114 isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay)
7115 {
7116         unsigned int ibits, obits, box, opcode;
7117         const uint32_t *mcp;
7118
7119         if (IS_FC(isp)) {
7120                 mcp = mbpfc;
7121         } else {
7122                 mcp = mbpscsi;
7123         }
7124         opcode = mbp->param[0];
7125         ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7126         obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7127         ibits |= mbp->ibits;
7128         obits |= mbp->obits;
7129         for (box = 0; box < MAX_MAILBOX(isp); box++) {
7130                 if (ibits & (1 << box)) {
7131                         ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
7132                 }
7133                 if (nodelay == 0) {
7134                         isp->isp_mboxtmp[box] = mbp->param[box] = 0;
7135                 }
7136         }
7137         if (nodelay == 0) {
7138                 isp->isp_lastmbxcmd = opcode;
7139                 isp->isp_obits = obits;
7140                 isp->isp_mboxbsy = 1;
7141         }
7142         if (IS_24XX(isp)) {
7143                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
7144         } else {
7145                 ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
7146         }
7147         /*
7148          * Oddly enough, if we're not delaying for an answer,
7149          * delay a bit to give the f/w a chance to pick up the
7150          * command.
7151          */
7152         if (nodelay) {
7153                 ISP_DELAY(1000);
7154         }
7155 }
7156
7157 static void
7158 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
7159 {
7160         const char *cname, *xname;
7161         char tname[16], mname[16];
7162         unsigned int lim, ibits, obits, box, opcode;
7163         const uint32_t *mcp;
7164
7165         if (IS_FC(isp)) {
7166                 mcp = mbpfc;
7167                 lim = NELEM(mbpfc);
7168         } else {
7169                 mcp = mbpscsi;
7170                 lim = NELEM(mbpscsi);
7171         }
7172
7173         if ((opcode = mbp->param[0]) >= lim) {
7174                 mbp->param[0] = MBOX_INVALID_COMMAND;
7175                 isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
7176                 return;
7177         }
7178
7179         ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7180         obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7181
7182         /*
7183          * Pick up any additional bits that the caller might have set.
7184          */
7185         ibits |= mbp->ibits;
7186         obits |= mbp->obits;
7187
7188         if (ibits == 0 && obits == 0) {
7189                 mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
7190                 isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
7191                 return;
7192         }
7193
7194         /*
7195          * Get exclusive usage of mailbox registers.
7196          */
7197         if (MBOX_ACQUIRE(isp)) {
7198                 mbp->param[0] = MBOX_REGS_BUSY;
7199                 goto out;
7200         }
7201
7202         for (box = 0; box < MAX_MAILBOX(isp); box++) {
7203                 if (ibits & (1 << box)) {
7204                         isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box,
7205                             mbp->param[box]);
7206                         ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
7207                 }
7208                 isp->isp_mboxtmp[box] = mbp->param[box] = 0;
7209         }
7210
7211         isp->isp_lastmbxcmd = opcode;
7212
7213         /*
7214          * We assume that we can't overwrite a previous command.
7215          */
7216         isp->isp_obits = obits;
7217         isp->isp_mboxbsy = 1;
7218
7219         /*
7220          * Set Host Interrupt condition so that RISC will pick up mailbox regs.
7221          */
7222         if (IS_24XX(isp)) {
7223                 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
7224         } else {
7225                 ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
7226         }
7227
7228         /*
7229          * While we haven't finished the command, spin our wheels here.
7230          */
7231         MBOX_WAIT_COMPLETE(isp, mbp);
7232
7233         /*
7234          * Did the command time out?
7235          */
7236         if (mbp->param[0] == MBOX_TIMEOUT) {
7237                 isp->isp_mboxbsy = 0;
7238                 MBOX_RELEASE(isp);
7239                 goto out;
7240         }
7241
7242         /*
7243          * Copy back output registers.
7244          */
7245         for (box = 0; box < MAX_MAILBOX(isp); box++) {
7246                 if (obits & (1 << box)) {
7247                         mbp->param[box] = isp->isp_mboxtmp[box];
7248                         isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box,
7249                             mbp->param[box]);
7250                 }
7251         }
7252
7253         isp->isp_mboxbsy = 0;
7254         MBOX_RELEASE(isp);
7255  out:
7256         if (mbp->logval == 0 || opcode == MBOX_EXEC_FIRMWARE) {
7257                 return;
7258         }
7259         cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
7260         if (cname == NULL) {
7261                 cname = tname;
7262                 ISP_SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
7263         }
7264
7265         /*
7266          * Just to be chatty here...
7267          */
7268         xname = NULL;
7269         switch (mbp->param[0]) {
7270         case MBOX_COMMAND_COMPLETE:
7271                 break;
7272         case MBOX_INVALID_COMMAND:
7273                 if (mbp->logval & MBLOGMASK(MBOX_COMMAND_COMPLETE)) {
7274                         xname = "INVALID COMMAND";
7275                 }
7276                 break;
7277         case MBOX_HOST_INTERFACE_ERROR:
7278                 if (mbp->logval & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR)) {
7279                         xname = "HOST INTERFACE ERROR";
7280                 }
7281                 break;
7282         case MBOX_TEST_FAILED:
7283                 if (mbp->logval & MBLOGMASK(MBOX_TEST_FAILED)) {
7284                         xname = "TEST FAILED";
7285                 }
7286                 break;
7287         case MBOX_COMMAND_ERROR:
7288                 if (mbp->logval & MBLOGMASK(MBOX_COMMAND_ERROR)) {
7289                         xname = "COMMAND ERROR";
7290                 }
7291                 break;
7292         case MBOX_COMMAND_PARAM_ERROR:
7293                 if (mbp->logval & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR)) {
7294                         xname = "COMMAND PARAMETER ERROR";
7295                 }
7296                 break;
7297         case MBOX_LOOP_ID_USED:
7298                 if (mbp->logval & MBLOGMASK(MBOX_LOOP_ID_USED)) {
7299                         xname = "LOOP ID ALREADY IN USE";
7300                 }
7301                 break;
7302         case MBOX_PORT_ID_USED:
7303                 if (mbp->logval & MBLOGMASK(MBOX_PORT_ID_USED)) {
7304                         xname = "PORT ID ALREADY IN USE";
7305                 }
7306                 break;
7307         case MBOX_ALL_IDS_USED:
7308                 if (mbp->logval & MBLOGMASK(MBOX_ALL_IDS_USED)) {
7309                         xname = "ALL LOOP IDS IN USE";
7310                 }
7311                 break;
7312         case MBOX_REGS_BUSY:
7313                 xname = "REGISTERS BUSY";
7314                 break;
7315         case MBOX_TIMEOUT:
7316                 xname = "TIMEOUT";
7317                 break;
7318         default:
7319                 ISP_SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
7320                 xname = mname;
7321                 break;
7322         }
7323         if (xname) {
7324                 isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
7325                     cname, xname);
7326         }
7327 }
7328
7329 static void
7330 isp_fw_state(ispsoftc_t *isp, int chan)
7331 {
7332         if (IS_FC(isp)) {
7333                 mbreg_t mbs;
7334                 fcparam *fcp = FCPARAM(isp, chan);
7335
7336                 MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0);
7337                 isp_mboxcmd(isp, &mbs);
7338                 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
7339                         fcp->isp_fwstate = mbs.param[1];
7340                 }
7341         }
7342 }
7343
7344 static void
7345 isp_spi_update(ispsoftc_t *isp, int chan)
7346 {
7347         int tgt;
7348         mbreg_t mbs;
7349         sdparam *sdp;
7350
7351         if (IS_FC(isp)) {
7352                 /*
7353                  * There are no 'per-bus' settings for Fibre Channel.
7354                  */
7355                 return;
7356         }
7357         sdp = SDPARAM(isp, chan);
7358         sdp->update = 0;
7359
7360         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7361                 uint16_t flags, period, offset;
7362                 int get;
7363
7364                 if (sdp->isp_devparam[tgt].dev_enable == 0) {
7365                         sdp->isp_devparam[tgt].dev_update = 0;
7366                         sdp->isp_devparam[tgt].dev_refresh = 0;
7367                         isp_prt(isp, ISP_LOGDEBUG0, "skipping target %d bus %d update", tgt, chan);
7368                         continue;
7369                 }
7370                 /*
7371                  * If the goal is to update the status of the device,
7372                  * take what's in goal_flags and try and set the device
7373                  * toward that. Otherwise, if we're just refreshing the
7374                  * current device state, get the current parameters.
7375                  */
7376
7377                 MBSINIT(&mbs, 0, MBLOGALL, 0);
7378
7379                 /*
7380                  * Refresh overrides set
7381                  */
7382                 if (sdp->isp_devparam[tgt].dev_refresh) {
7383                         mbs.param[0] = MBOX_GET_TARGET_PARAMS;
7384                         get = 1;
7385                 } else if (sdp->isp_devparam[tgt].dev_update) {
7386                         mbs.param[0] = MBOX_SET_TARGET_PARAMS;
7387
7388                         /*
7389                          * Make sure goal_flags has "Renegotiate on Error"
7390                          * on and "Freeze Queue on Error" off.
7391                          */
7392                         sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
7393                         sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
7394                         mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
7395
7396                         /*
7397                          * Insist that PARITY must be enabled
7398                          * if SYNC or WIDE is enabled.
7399                          */
7400                         if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
7401                                 mbs.param[2] |= DPARM_PARITY;
7402                         }
7403
7404                         if (mbs.param[2] & DPARM_SYNC) {
7405                                 mbs.param[3] =
7406                                     (sdp->isp_devparam[tgt].goal_offset << 8) |
7407                                     (sdp->isp_devparam[tgt].goal_period);
7408                         }
7409                         /*
7410                          * A command completion later that has
7411                          * RQSTF_NEGOTIATION set can cause
7412                          * the dev_refresh/announce cycle also.
7413                          *
7414                          * Note: It is really important to update our current
7415                          * flags with at least the state of TAG capabilities-
7416                          * otherwise we might try and send a tagged command
7417                          * when we have it all turned off. So change it here
7418                          * to say that current already matches goal.
7419                          */
7420                         sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
7421                         sdp->isp_devparam[tgt].actv_flags |=
7422                             (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
7423                         isp_prt(isp, ISP_LOGDEBUG0, "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
7424                             chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff);
7425                         get = 0;
7426                 } else {
7427                         continue;
7428                 }
7429                 mbs.param[1] = (chan << 15) | (tgt << 8);
7430                 isp_mboxcmd(isp, &mbs);
7431                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7432                         continue;
7433                 }
7434                 if (get == 0) {
7435                         sdp->sendmarker = 1;
7436                         sdp->isp_devparam[tgt].dev_update = 0;
7437                         sdp->isp_devparam[tgt].dev_refresh = 1;
7438                 } else {
7439                         sdp->isp_devparam[tgt].dev_refresh = 0;
7440                         flags = mbs.param[2];
7441                         period = mbs.param[3] & 0xff;
7442                         offset = mbs.param[3] >> 8;
7443                         sdp->isp_devparam[tgt].actv_flags = flags;
7444                         sdp->isp_devparam[tgt].actv_period = period;
7445                         sdp->isp_devparam[tgt].actv_offset = offset;
7446                         isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, chan, tgt);
7447                 }
7448         }
7449
7450         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7451                 if (sdp->isp_devparam[tgt].dev_update ||
7452                     sdp->isp_devparam[tgt].dev_refresh) {
7453                         sdp->update = 1;
7454                         break;
7455                 }
7456         }
7457 }
7458
7459 static void
7460 isp_setdfltsdparm(ispsoftc_t *isp)
7461 {
7462         int tgt;
7463         sdparam *sdp, *sdp1;
7464
7465         sdp = SDPARAM(isp, 0);
7466         sdp->role = GET_DEFAULT_ROLE(isp, 0);
7467         if (IS_DUALBUS(isp)) {
7468                 sdp1 = sdp + 1;
7469                 sdp1->role = GET_DEFAULT_ROLE(isp, 1);
7470         } else {
7471                 sdp1 = NULL;
7472         }
7473
7474         /*
7475          * Establish some default parameters.
7476          */
7477         sdp->isp_cmd_dma_burst_enable = 0;
7478         sdp->isp_data_dma_burst_enabl = 1;
7479         sdp->isp_fifo_threshold = 0;
7480         sdp->isp_initiator_id = DEFAULT_IID(isp, 0);
7481         if (isp->isp_type >= ISP_HA_SCSI_1040) {
7482                 sdp->isp_async_data_setup = 9;
7483         } else {
7484                 sdp->isp_async_data_setup = 6;
7485         }
7486         sdp->isp_selection_timeout = 250;
7487         sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
7488         sdp->isp_tag_aging = 8;
7489         sdp->isp_bus_reset_delay = 5;
7490         /*
7491          * Don't retry selection, busy or queue full automatically- reflect
7492          * these back to us.
7493          */
7494         sdp->isp_retry_count = 0;
7495         sdp->isp_retry_delay = 0;
7496
7497         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7498                 sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
7499                 sdp->isp_devparam[tgt].dev_enable = 1;
7500         }
7501
7502         /*
7503          * The trick here is to establish a default for the default (honk!)
7504          * state (goal_flags). Then try and get the current status from
7505          * the card to fill in the current state. We don't, in fact, set
7506          * the default to the SAFE default state- that's not the goal state.
7507          */
7508         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7509                 uint8_t off, per;
7510                 sdp->isp_devparam[tgt].actv_offset = 0;
7511                 sdp->isp_devparam[tgt].actv_period = 0;
7512                 sdp->isp_devparam[tgt].actv_flags = 0;
7513
7514                 sdp->isp_devparam[tgt].goal_flags =
7515                     sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
7516
7517                 /*
7518                  * We default to Wide/Fast for versions less than a 1040
7519                  * (unless it's SBus).
7520                  */
7521                 if (IS_ULTRA3(isp)) {
7522                         off = ISP_80M_SYNCPARMS >> 8;
7523                         per = ISP_80M_SYNCPARMS & 0xff;
7524                 } else if (IS_ULTRA2(isp)) {
7525                         off = ISP_40M_SYNCPARMS >> 8;
7526                         per = ISP_40M_SYNCPARMS & 0xff;
7527                 } else if (IS_1240(isp)) {
7528                         off = ISP_20M_SYNCPARMS >> 8;
7529                         per = ISP_20M_SYNCPARMS & 0xff;
7530                 } else if ((isp->isp_bustype == ISP_BT_SBUS &&
7531                     isp->isp_type < ISP_HA_SCSI_1020A) ||
7532                     (isp->isp_bustype == ISP_BT_PCI &&
7533                     isp->isp_type < ISP_HA_SCSI_1040) ||
7534                     (isp->isp_clock && isp->isp_clock < 60) ||
7535                     (sdp->isp_ultramode == 0)) {
7536                         off = ISP_10M_SYNCPARMS >> 8;
7537                         per = ISP_10M_SYNCPARMS & 0xff;
7538                 } else {
7539                         off = ISP_20M_SYNCPARMS_1040 >> 8;
7540                         per = ISP_20M_SYNCPARMS_1040 & 0xff;
7541                 }
7542                 sdp->isp_devparam[tgt].goal_offset =
7543                     sdp->isp_devparam[tgt].nvrm_offset = off;
7544                 sdp->isp_devparam[tgt].goal_period =
7545                     sdp->isp_devparam[tgt].nvrm_period = per;
7546
7547         }
7548
7549         /*
7550          * If we're a dual bus card, just copy the data over
7551          */
7552         if (sdp1) {
7553                 *sdp1 = *sdp;
7554                 sdp1->isp_initiator_id = DEFAULT_IID(isp, 1);
7555         }
7556
7557         /*
7558          * If we've not been told to avoid reading NVRAM, try and read it.
7559          * If we're successful reading it, we can then return because NVRAM
7560          * will tell us what the desired settings are. Otherwise, we establish
7561          * some reasonable 'fake' nvram and goal defaults.
7562          */
7563         if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7564                 mbreg_t mbs;
7565
7566                 if (isp_read_nvram(isp, 0) == 0) {
7567                         if (IS_DUALBUS(isp)) {
7568                                 if (isp_read_nvram(isp, 1) == 0) {
7569                                         return;
7570                                 }
7571                         }
7572                 }
7573                 MBSINIT(&mbs, MBOX_GET_ACT_NEG_STATE, MBLOGNONE, 0);
7574                 isp_mboxcmd(isp, &mbs);
7575                 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7576                         sdp->isp_req_ack_active_neg = 1;
7577                         sdp->isp_data_line_active_neg = 1;
7578                         if (sdp1) {
7579                                 sdp1->isp_req_ack_active_neg = 1;
7580                                 sdp1->isp_data_line_active_neg = 1;
7581                         }
7582                 } else {
7583                         sdp->isp_req_ack_active_neg =
7584                             (mbs.param[1] >> 4) & 0x1;
7585                         sdp->isp_data_line_active_neg =
7586                             (mbs.param[1] >> 5) & 0x1;
7587                         if (sdp1) {
7588                                 sdp1->isp_req_ack_active_neg =
7589                                     (mbs.param[2] >> 4) & 0x1;
7590                                 sdp1->isp_data_line_active_neg =
7591                                     (mbs.param[2] >> 5) & 0x1;
7592                         }
7593                 }
7594         }
7595
7596 }
7597
7598 static void
7599 isp_setdfltfcparm(ispsoftc_t *isp, int chan)
7600 {
7601         fcparam *fcp = FCPARAM(isp, chan);
7602
7603         /*
7604          * Establish some default parameters.
7605          */
7606         fcp->role = GET_DEFAULT_ROLE(isp, chan);
7607         fcp->isp_maxalloc = ICB_DFLT_ALLOC;
7608         fcp->isp_retry_delay = ICB_DFLT_RDELAY;
7609         fcp->isp_retry_count = ICB_DFLT_RCOUNT;
7610         fcp->isp_loopid = DEFAULT_LOOPID(isp, chan);
7611         fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
7612         fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
7613         fcp->isp_fwoptions = 0;
7614         fcp->isp_lasthdl = NIL_HANDLE;
7615
7616         if (IS_24XX(isp)) {
7617                 fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS;
7618                 fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS;
7619                 if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
7620                         fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
7621                 }
7622                 fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
7623         } else {
7624                 fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
7625                 fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
7626                 fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
7627                 if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
7628                         fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
7629                 }
7630                 /*
7631                  * Make sure this is turned off now until we get
7632                  * extended options from NVRAM
7633                  */
7634                 fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
7635         }
7636
7637
7638         /*
7639          * Now try and read NVRAM unless told to not do so.
7640          * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
7641          */
7642         if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7643                 int i, j = 0;
7644                 /*
7645                  * Give a couple of tries at reading NVRAM.
7646                  */
7647                 for (i = 0; i < 2; i++) {
7648                         j = isp_read_nvram(isp, chan);
7649                         if (j == 0) {
7650                                 break;
7651                         }
7652                 }
7653                 if (j) {
7654                         isp->isp_confopts |= ISP_CFG_NONVRAM;
7655                 }
7656         }
7657
7658         fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan);
7659         fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan);
7660         isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s",
7661             chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn),
7662             (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn),
7663             isp_class3_roles[fcp->role]);
7664 }
7665
7666 /*
7667  * Re-initialize the ISP and complete all orphaned commands
7668  * with a 'botched' notice. The reset/init routines should
7669  * not disturb an already active list of commands.
7670  */
7671
7672 void
7673 isp_reinit(ispsoftc_t *isp, int do_load_defaults)
7674 {
7675         int i;
7676
7677         isp_reset(isp, do_load_defaults);
7678
7679         if (isp->isp_state != ISP_RESETSTATE) {
7680                 isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
7681                 ISP_DISABLE_INTS(isp);
7682                 goto cleanup;
7683         }
7684
7685         isp_init(isp);
7686
7687         if (isp->isp_state == ISP_INITSTATE) {
7688                 isp->isp_state = ISP_RUNSTATE;
7689         }
7690
7691         if (isp->isp_state != ISP_RUNSTATE) {
7692 #ifndef ISP_TARGET_MODE
7693                 isp_prt(isp, ISP_LOGWARN, "%s: not at runstate", __func__);
7694 #endif
7695                 ISP_DISABLE_INTS(isp);
7696                 if (IS_FC(isp)) {
7697                         /*
7698                          * If we're in ISP_ROLE_NONE, turn off the lasers.
7699                          */
7700                         if (!IS_24XX(isp)) {
7701                                 ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
7702                                 ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
7703                                 ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
7704                                 ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
7705                                 ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
7706                         }
7707                 }
7708         }
7709
7710  cleanup:
7711
7712         isp->isp_nactive = 0;
7713
7714         isp_clear_commands(isp);
7715         if (IS_FC(isp)) {
7716                 for (i = 0; i < isp->isp_nchan; i++) {
7717                         ISP_MARK_PORTDB(isp, i, -1);
7718                 }
7719         }
7720 }
7721
7722 /*
7723  * NVRAM Routines
7724  */
7725 static int
7726 isp_read_nvram(ispsoftc_t *isp, int bus)
7727 {
7728         int i, amt, retval;
7729         uint8_t csum, minversion;
7730         union {
7731                 uint8_t _x[ISP2400_NVRAM_SIZE];
7732                 uint16_t _s[ISP2400_NVRAM_SIZE>>1];
7733         } _n;
7734 #define nvram_data      _n._x
7735 #define nvram_words     _n._s
7736
7737         if (IS_24XX(isp)) {
7738                 return (isp_read_nvram_2400(isp, nvram_data));
7739         } else if (IS_FC(isp)) {
7740                 amt = ISP2100_NVRAM_SIZE;
7741                 minversion = 1;
7742         } else if (IS_ULTRA2(isp)) {
7743                 amt = ISP1080_NVRAM_SIZE;
7744                 minversion = 0;
7745         } else {
7746                 amt = ISP_NVRAM_SIZE;
7747                 minversion = 2;
7748         }
7749
7750         for (i = 0; i < amt>>1; i++) {
7751                 isp_rdnvram_word(isp, i, &nvram_words[i]);
7752         }
7753
7754         if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7755             nvram_data[2] != 'P') {
7756                 if (isp->isp_bustype != ISP_BT_SBUS) {
7757                         isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
7758                         isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x", nvram_data[0], nvram_data[1], nvram_data[2]);
7759                 }
7760                 retval = -1;
7761                 goto out;
7762         }
7763
7764         for (csum = 0, i = 0; i < amt; i++) {
7765                 csum += nvram_data[i];
7766         }
7767         if (csum != 0) {
7768                 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7769                 retval = -1;
7770                 goto out;
7771         }
7772
7773         if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
7774                 isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
7775                     ISP_NVRAM_VERSION(nvram_data));
7776                 retval = -1;
7777                 goto out;
7778         }
7779
7780         if (IS_ULTRA3(isp)) {
7781                 isp_parse_nvram_12160(isp, bus, nvram_data);
7782         } else if (IS_1080(isp)) {
7783                 isp_parse_nvram_1080(isp, bus, nvram_data);
7784         } else if (IS_1280(isp) || IS_1240(isp)) {
7785                 isp_parse_nvram_1080(isp, bus, nvram_data);
7786         } else if (IS_SCSI(isp)) {
7787                 isp_parse_nvram_1020(isp, nvram_data);
7788         } else {
7789                 isp_parse_nvram_2100(isp, nvram_data);
7790         }
7791         retval = 0;
7792 out:
7793         return (retval);
7794 #undef  nvram_data
7795 #undef  nvram_words
7796 }
7797
7798 static int
7799 isp_read_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
7800 {
7801         int retval = 0;
7802         uint32_t addr, csum, lwrds, *dptr;
7803
7804         if (isp->isp_port) {
7805                 addr = ISP2400_NVRAM_PORT1_ADDR;
7806         } else {
7807                 addr = ISP2400_NVRAM_PORT0_ADDR;
7808         }
7809
7810         dptr = (uint32_t *) nvram_data;
7811         for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7812                 isp_rd_2400_nvram(isp, addr++, dptr++);
7813         }
7814         if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7815             nvram_data[2] != 'P') {
7816                 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
7817                     nvram_data[0], nvram_data[1], nvram_data[2]);
7818                 retval = -1;
7819                 goto out;
7820         }
7821         dptr = (uint32_t *) nvram_data;
7822         for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7823                 uint32_t tmp;
7824                 ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
7825                 csum += tmp;
7826         }
7827         if (csum != 0) {
7828                 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7829                 retval = -1;
7830                 goto out;
7831         }
7832         isp_parse_nvram_2400(isp, nvram_data);
7833 out:
7834         return (retval);
7835 }
7836
7837 static void
7838 isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
7839 {
7840         int i, cbits;
7841         uint16_t bit, rqst, junk;
7842
7843         ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7844         ISP_DELAY(10);
7845         ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7846         ISP_DELAY(10);
7847
7848         if (IS_FC(isp)) {
7849                 wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
7850                 if (IS_2312(isp) && isp->isp_port) {
7851                         wo += 128;
7852                 }
7853                 rqst = (ISP_NVRAM_READ << 8) | wo;
7854                 cbits = 10;
7855         } else if (IS_ULTRA2(isp)) {
7856                 wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
7857                 rqst = (ISP_NVRAM_READ << 8) | wo;
7858                 cbits = 10;
7859         } else {
7860                 wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
7861                 rqst = (ISP_NVRAM_READ << 6) | wo;
7862                 cbits = 8;
7863         }
7864
7865         /*
7866          * Clock the word select request out...
7867          */
7868         for (i = cbits; i >= 0; i--) {
7869                 if ((rqst >> i) & 1) {
7870                         bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
7871                 } else {
7872                         bit = BIU_NVRAM_SELECT;
7873                 }
7874                 ISP_WRITE(isp, BIU_NVRAM, bit);
7875                 ISP_DELAY(10);
7876                 junk = ISP_READ(isp, BIU_NVRAM);        /* force PCI flush */
7877                 ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
7878                 ISP_DELAY(10);
7879                 junk = ISP_READ(isp, BIU_NVRAM);        /* force PCI flush */
7880                 ISP_WRITE(isp, BIU_NVRAM, bit);
7881                 ISP_DELAY(10);
7882                 junk = ISP_READ(isp, BIU_NVRAM);        /* force PCI flush */
7883         }
7884         /*
7885          * Now read the result back in (bits come back in MSB format).
7886          */
7887         *rp = 0;
7888         for (i = 0; i < 16; i++) {
7889                 uint16_t rv;
7890                 *rp <<= 1;
7891                 ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7892                 ISP_DELAY(10);
7893                 rv = ISP_READ(isp, BIU_NVRAM);
7894                 if (rv & BIU_NVRAM_DATAIN) {
7895                         *rp |= 1;
7896                 }
7897                 ISP_DELAY(10);
7898                 ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7899                 ISP_DELAY(10);
7900                 junk = ISP_READ(isp, BIU_NVRAM);        /* force PCI flush */
7901         }
7902         ISP_WRITE(isp, BIU_NVRAM, 0);
7903         ISP_DELAY(10);
7904         junk = ISP_READ(isp, BIU_NVRAM);        /* force PCI flush */
7905         ISP_SWIZZLE_NVRAM_WORD(isp, rp);
7906 }
7907
7908 static void
7909 isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
7910 {
7911         int loops = 0;
7912         uint32_t base = 0x7ffe0000;
7913         uint32_t tmp = 0;
7914
7915         if (IS_25XX(isp)) {
7916                 base = 0x7ff00000 | 0x48000;
7917         }
7918         ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
7919         for (loops = 0; loops < 5000; loops++) {
7920                 ISP_DELAY(10);
7921                 tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
7922                 if ((tmp & (1U << 31)) != 0) {
7923                         break;
7924                 }
7925         }
7926         if (tmp & (1U << 31)) {
7927                 *rp = ISP_READ(isp, BIU2400_FLASH_DATA);
7928                 ISP_SWIZZLE_NVRAM_LONG(isp, rp);
7929         } else {
7930                 *rp = 0xffffffff;
7931         }
7932 }
7933
7934 static void
7935 isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
7936 {
7937         sdparam *sdp = SDPARAM(isp, 0);
7938         int tgt;
7939
7940         sdp->isp_fifo_threshold =
7941                 ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
7942                 (ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
7943
7944         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
7945                 sdp->isp_initiator_id =
7946                         ISP_NVRAM_INITIATOR_ID(nvram_data);
7947
7948         sdp->isp_bus_reset_delay =
7949                 ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
7950
7951         sdp->isp_retry_count =
7952                 ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
7953
7954         sdp->isp_retry_delay =
7955                 ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
7956
7957         sdp->isp_async_data_setup =
7958                 ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
7959
7960         if (isp->isp_type >= ISP_HA_SCSI_1040) {
7961                 if (sdp->isp_async_data_setup < 9) {
7962                         sdp->isp_async_data_setup = 9;
7963                 }
7964         } else {
7965                 if (sdp->isp_async_data_setup != 6) {
7966                         sdp->isp_async_data_setup = 6;
7967                 }
7968         }
7969
7970         sdp->isp_req_ack_active_neg =
7971                 ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
7972
7973         sdp->isp_data_line_active_neg =
7974                 ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
7975
7976         sdp->isp_data_dma_burst_enabl =
7977                 ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
7978
7979         sdp->isp_cmd_dma_burst_enable =
7980                 ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
7981
7982         sdp->isp_tag_aging =
7983                 ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
7984
7985         sdp->isp_selection_timeout =
7986                 ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
7987
7988         sdp->isp_max_queue_depth =
7989                 ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
7990
7991         sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
7992
7993         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7994                 sdp->isp_devparam[tgt].dev_enable =
7995                         ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
7996                 sdp->isp_devparam[tgt].exc_throttle =
7997                         ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
7998                 sdp->isp_devparam[tgt].nvrm_offset =
7999                         ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
8000                 sdp->isp_devparam[tgt].nvrm_period =
8001                         ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
8002                 /*
8003                  * We probably shouldn't lie about this, but it
8004                  * it makes it much safer if we limit NVRAM values
8005                  * to sanity.
8006                  */
8007                 if (isp->isp_type < ISP_HA_SCSI_1040) {
8008                         /*
8009                          * If we're not ultra, we can't possibly
8010                          * be a shorter period than this.
8011                          */
8012                         if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
8013                                 sdp->isp_devparam[tgt].nvrm_period = 0x19;
8014                         }
8015                         if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
8016                                 sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
8017                         }
8018                 } else {
8019                         if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
8020                                 sdp->isp_devparam[tgt].nvrm_offset = 0x8;
8021                         }
8022                 }
8023                 sdp->isp_devparam[tgt].nvrm_flags = 0;
8024                 if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
8025                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8026                 sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8027                 if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
8028                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8029                 if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
8030                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8031                 if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
8032                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8033                 if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
8034                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8035                 if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
8036                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8037                 sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
8038                 sdp->isp_devparam[tgt].goal_offset =
8039                     sdp->isp_devparam[tgt].nvrm_offset;
8040                 sdp->isp_devparam[tgt].goal_period =
8041                     sdp->isp_devparam[tgt].nvrm_period;
8042                 sdp->isp_devparam[tgt].goal_flags =
8043                     sdp->isp_devparam[tgt].nvrm_flags;
8044         }
8045 }
8046
8047 static void
8048 isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
8049 {
8050         sdparam *sdp = SDPARAM(isp, bus);
8051         int tgt;
8052
8053         sdp->isp_fifo_threshold =
8054             ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
8055
8056         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
8057                 sdp->isp_initiator_id =
8058                     ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
8059
8060         sdp->isp_bus_reset_delay =
8061             ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
8062
8063         sdp->isp_retry_count =
8064             ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
8065
8066         sdp->isp_retry_delay =
8067             ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
8068
8069         sdp->isp_async_data_setup =
8070             ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
8071
8072         sdp->isp_req_ack_active_neg =
8073             ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
8074
8075         sdp->isp_data_line_active_neg =
8076             ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
8077
8078         sdp->isp_data_dma_burst_enabl =
8079             ISP1080_NVRAM_BURST_ENABLE(nvram_data);
8080
8081         sdp->isp_cmd_dma_burst_enable =
8082             ISP1080_NVRAM_BURST_ENABLE(nvram_data);
8083
8084         sdp->isp_selection_timeout =
8085             ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
8086
8087         sdp->isp_max_queue_depth =
8088              ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
8089
8090         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8091                 sdp->isp_devparam[tgt].dev_enable =
8092                     ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
8093                 sdp->isp_devparam[tgt].exc_throttle =
8094                         ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
8095                 sdp->isp_devparam[tgt].nvrm_offset =
8096                         ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
8097                 sdp->isp_devparam[tgt].nvrm_period =
8098                         ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
8099                 sdp->isp_devparam[tgt].nvrm_flags = 0;
8100                 if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
8101                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8102                 sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8103                 if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
8104                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8105                 if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
8106                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8107                 if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
8108                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8109                 if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
8110                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8111                 if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
8112                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8113                 sdp->isp_devparam[tgt].actv_flags = 0;
8114                 sdp->isp_devparam[tgt].goal_offset =
8115                     sdp->isp_devparam[tgt].nvrm_offset;
8116                 sdp->isp_devparam[tgt].goal_period =
8117                     sdp->isp_devparam[tgt].nvrm_period;
8118                 sdp->isp_devparam[tgt].goal_flags =
8119                     sdp->isp_devparam[tgt].nvrm_flags;
8120         }
8121 }
8122
8123 static void
8124 isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
8125 {
8126         sdparam *sdp = SDPARAM(isp, bus);
8127         int tgt;
8128
8129         sdp->isp_fifo_threshold =
8130             ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
8131
8132         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
8133                 sdp->isp_initiator_id =
8134                     ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
8135
8136         sdp->isp_bus_reset_delay =
8137             ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
8138
8139         sdp->isp_retry_count =
8140             ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
8141
8142         sdp->isp_retry_delay =
8143             ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
8144
8145         sdp->isp_async_data_setup =
8146             ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
8147
8148         sdp->isp_req_ack_active_neg =
8149             ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
8150
8151         sdp->isp_data_line_active_neg =
8152             ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
8153
8154         sdp->isp_data_dma_burst_enabl =
8155             ISP12160_NVRAM_BURST_ENABLE(nvram_data);
8156
8157         sdp->isp_cmd_dma_burst_enable =
8158             ISP12160_NVRAM_BURST_ENABLE(nvram_data);
8159
8160         sdp->isp_selection_timeout =
8161             ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
8162
8163         sdp->isp_max_queue_depth =
8164              ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
8165
8166         for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8167                 sdp->isp_devparam[tgt].dev_enable =
8168                     ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
8169                 sdp->isp_devparam[tgt].exc_throttle =
8170                         ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
8171                 sdp->isp_devparam[tgt].nvrm_offset =
8172                         ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
8173                 sdp->isp_devparam[tgt].nvrm_period =
8174                         ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
8175                 sdp->isp_devparam[tgt].nvrm_flags = 0;
8176                 if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
8177                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8178                 sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8179                 if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
8180                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8181                 if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
8182                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8183                 if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
8184                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8185                 if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
8186                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8187                 if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
8188                         sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8189                 sdp->isp_devparam[tgt].actv_flags = 0;
8190                 sdp->isp_devparam[tgt].goal_offset =
8191                     sdp->isp_devparam[tgt].nvrm_offset;
8192                 sdp->isp_devparam[tgt].goal_period =
8193                     sdp->isp_devparam[tgt].nvrm_period;
8194                 sdp->isp_devparam[tgt].goal_flags =
8195                     sdp->isp_devparam[tgt].nvrm_flags;
8196         }
8197 }
8198
8199 static void
8200 isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
8201 {
8202         fcparam *fcp = FCPARAM(isp, 0);
8203         uint64_t wwn;
8204
8205         /*
8206          * There is NVRAM storage for both Port and Node entities-
8207          * but the Node entity appears to be unused on all the cards
8208          * I can find. However, we should account for this being set
8209          * at some point in the future.
8210          *
8211          * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
8212          * bits 48..60. In the case of the 2202, it appears that they do
8213          * use bit 48 to distinguish between the two instances on the card.
8214          * The 2204, which I've never seen, *probably* extends this method.
8215          */
8216         wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
8217         if (wwn) {
8218                 isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
8219                     (uint32_t) (wwn >> 32), (uint32_t) (wwn));
8220                 if ((wwn >> 60) == 0) {
8221                         wwn |= (((uint64_t) 2)<< 60);
8222                 }
8223         }
8224         fcp->isp_wwpn_nvram = wwn;
8225         if (IS_2200(isp) || IS_23XX(isp)) {
8226                 wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
8227                 if (wwn) {
8228                         isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
8229                             (uint32_t) (wwn >> 32),
8230                             (uint32_t) (wwn));
8231                         if ((wwn >> 60) == 0) {
8232                                 wwn |= (((uint64_t) 2)<< 60);
8233                         }
8234                 } else {
8235                         wwn = fcp->isp_wwpn_nvram & ~((uint64_t) 0xfff << 48);
8236                 }
8237         } else {
8238                 wwn &= ~((uint64_t) 0xfff << 48);
8239         }
8240         fcp->isp_wwnn_nvram = wwn;
8241
8242         fcp->isp_maxalloc = ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
8243         if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
8244                 DEFAULT_FRAMESIZE(isp) =
8245                     ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
8246         }
8247         fcp->isp_retry_delay = ISP2100_NVRAM_RETRY_DELAY(nvram_data);
8248         fcp->isp_retry_count = ISP2100_NVRAM_RETRY_COUNT(nvram_data);
8249         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
8250                 fcp->isp_loopid = ISP2100_NVRAM_HARDLOOPID(nvram_data);
8251         }
8252         if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
8253                 DEFAULT_EXEC_THROTTLE(isp) =
8254                         ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
8255         }
8256         fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
8257         isp_prt(isp, ISP_LOGDEBUG0,
8258             "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d",
8259             (uint32_t) (fcp->isp_wwnn_nvram >> 32),
8260             (uint32_t) fcp->isp_wwnn_nvram,
8261             (uint32_t) (fcp->isp_wwpn_nvram >> 32),
8262             (uint32_t) fcp->isp_wwpn_nvram,
8263             ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data),
8264             ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data));
8265         isp_prt(isp, ISP_LOGDEBUG0,
8266             "execthrottle %d fwoptions 0x%x hardloop %d tov %d",
8267             ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
8268             ISP2100_NVRAM_OPTIONS(nvram_data),
8269             ISP2100_NVRAM_HARDLOOPID(nvram_data),
8270             ISP2100_NVRAM_TOV(nvram_data));
8271         fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data);
8272         fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data);
8273         isp_prt(isp, ISP_LOGDEBUG0, "xfwoptions 0x%x zfw options 0x%x",
8274             ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data));
8275 }
8276
8277 static void
8278 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
8279 {
8280         fcparam *fcp = FCPARAM(isp, 0);
8281         uint64_t wwn;
8282
8283         isp_prt(isp, ISP_LOGDEBUG0,
8284             "NVRAM 0x%08x%08x 0x%08x%08x exchg_cnt %d maxframelen %d",
8285             (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
8286             (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
8287             (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
8288             (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
8289             ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data),
8290             ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
8291         isp_prt(isp, ISP_LOGDEBUG0,
8292             "NVRAM execthr %d loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
8293             ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data),
8294             ISP2400_NVRAM_HARDLOOPID(nvram_data),
8295             ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
8296             ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
8297             ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
8298
8299         wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
8300         fcp->isp_wwpn_nvram = wwn;
8301
8302         wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
8303         if (wwn) {
8304                 if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
8305                         wwn = 0;
8306                 }
8307         }
8308         if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
8309                 wwn = fcp->isp_wwpn_nvram;
8310                 wwn &= ~((uint64_t) 0xfff << 48);
8311         }
8312         fcp->isp_wwnn_nvram = wwn;
8313
8314         if (ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data)) {
8315                 fcp->isp_maxalloc = ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data);
8316         }
8317         if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
8318                 DEFAULT_FRAMESIZE(isp) =
8319                     ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
8320         }
8321         if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
8322                 fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
8323         }
8324         if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
8325                 DEFAULT_EXEC_THROTTLE(isp) =
8326                         ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data);
8327         }
8328         fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
8329         fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
8330         fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
8331 }