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