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