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