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