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