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