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