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