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