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