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