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