FreeBSD/Linux Kernel Cross Reference
sys/dev/isp/isp.c
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2009-2020 Alexander Motin <mav@FreeBSD.org>
5 * Copyright (c) 1997-2009 by Matthew Jacob
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 */
31
32 /*
33 * Machine and OS Independent (well, as best as possible)
34 * code for the Qlogic ISP SCSI and FC-SCSI adapters.
35 */
36
37 /*
38 * Inspiration and ideas about this driver are from Erik Moe's Linux driver
39 * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
40 * ideas dredged from the Solaris driver.
41 */
42
43 /*
44 * Include header file appropriate for platform we're building on.
45 */
46 #ifdef __NetBSD__
47 #include <sys/cdefs.h>
48 __KERNEL_RCSID(0, "$NetBSD$");
49 #include <dev/ic/isp_netbsd.h>
50 #endif
51 #ifdef __FreeBSD__
52 #include <sys/cdefs.h>
53 __FBSDID("$FreeBSD$");
54 #include <dev/isp/isp_freebsd.h>
55 #endif
56 #ifdef __OpenBSD__
57 #include <dev/ic/isp_openbsd.h>
58 #endif
59 #ifdef __linux__
60 #include "isp_linux.h"
61 #endif
62 #ifdef __svr4__
63 #include "isp_solaris.h"
64 #endif
65
66 /*
67 * Local static data
68 */
69 static const char notresp[] = "Unknown IOCB in RESPONSE Queue (type 0x%x) @ idx %d (next %d)";
70 static const char bun[] = "bad underrun (count %d, resid %d, status %s)";
71 static const char lipd[] = "Chan %d LIP destroyed %d active commands";
72 static const char sacq[] = "unable to acquire scratch area";
73
74 static const uint8_t alpa_map[] = {
75 0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda,
76 0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce,
77 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5,
78 0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3,
79 0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
80 0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b,
81 0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81,
82 0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73,
83 0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69,
84 0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
85 0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c,
86 0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c,
87 0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
88 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26,
89 0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
90 0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00
91 };
92
93 /*
94 * Local function prototypes.
95 */
96 static int isp_handle_control(ispsoftc_t *, isphdr_t *);
97 static void isp_handle_rpt_id_acq(ispsoftc_t *, isphdr_t *);
98 static void isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *);
99 static void isp_clear_portdb(ispsoftc_t *, int);
100 static void isp_mark_portdb(ispsoftc_t *, int);
101 static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int);
102 static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *);
103 static int isp_gethandles(ispsoftc_t *, int, uint16_t *, int *, int);
104 static void isp_dump_chip_portdb(ispsoftc_t *, int);
105 static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
106 static int isp_fclink_test(ispsoftc_t *, int, int);
107 static int isp_pdb_sync(ispsoftc_t *, int);
108 static int isp_scan_loop(ispsoftc_t *, int);
109 static int isp_gid_pt(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_features_24xx(ispsoftc_t *, int);
114 static int isp_register_port_name_24xx(ispsoftc_t *, int);
115 static int isp_register_node_name_24xx(ispsoftc_t *, int);
116 static uint16_t isp_next_handle(ispsoftc_t *, uint16_t *);
117 static int isp_fw_state(ispsoftc_t *, int);
118 static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
119
120 static void isp_setdfltfcparm(ispsoftc_t *, int);
121 static int isp_read_nvram(ispsoftc_t *, int);
122 static int isp_read_nvram_2400(ispsoftc_t *);
123 static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *);
124 static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
125
126 static void
127 isp_change_fw_state(ispsoftc_t *isp, int chan, int state)
128 {
129 fcparam *fcp = FCPARAM(isp, chan);
130
131 if (fcp->isp_fwstate == state)
132 return;
133 isp_prt(isp, ISP_LOGCONFIG|ISP_LOG_SANCFG,
134 "Chan %d Firmware state <%s->%s>", chan,
135 isp_fc_fw_statename(fcp->isp_fwstate), isp_fc_fw_statename(state));
136 fcp->isp_fwstate = state;
137 }
138
139 /*
140 * Reset Hardware.
141 *
142 * Hit the chip over the head, download new f/w if available and set it running.
143 *
144 * Locking done elsewhere.
145 */
146
147 void
148 isp_reset(ispsoftc_t *isp, int do_load_defaults)
149 {
150 mbreg_t mbs;
151 char *buf;
152 uint64_t fwt;
153 uint32_t code_org, val;
154 int loaded_fw, loops, i, dodnld = 1;
155 const char *btype = "????";
156 static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
157
158 isp->isp_state = ISP_NILSTATE;
159 ISP_DISABLE_INTS(isp);
160
161 /*
162 * Put the board into PAUSE mode (so we can read the SXP registers
163 * or write FPM/FBM registers).
164 */
165 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT);
166 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
167 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
168
169 switch (isp->isp_type) {
170 case ISP_HA_FC_2400:
171 btype = "2422";
172 break;
173 case ISP_HA_FC_2500:
174 btype = "2532";
175 break;
176 case ISP_HA_FC_2600:
177 btype = "2600";
178 break;
179 case ISP_HA_FC_2700:
180 btype = "2700";
181 break;
182 default:
183 break;
184 }
185
186 /*
187 * Stop DMA and wait for it to stop.
188 */
189 ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
190 for (loops = 0; loops < 100000; loops++) {
191 ISP_DELAY(10);
192 val = ISP_READ(isp, BIU2400_CSR);
193 if ((val & BIU2400_DMA_ACTIVE) == 0) {
194 break;
195 }
196 }
197 if (val & BIU2400_DMA_ACTIVE)
198 isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
199
200 /*
201 * Hold it in SOFT_RESET and STOP state for 100us.
202 */
203 ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
204 ISP_DELAY(100);
205 for (loops = 0; loops < 10000; loops++) {
206 ISP_DELAY(5);
207 val = ISP_READ(isp, OUTMAILBOX0);
208 if (val != 0x4)
209 break;
210 }
211 switch (val) {
212 case 0x0:
213 break;
214 case 0x4:
215 isp_prt(isp, ISP_LOGERR, "The ROM code is busy after 50ms.");
216 return;
217 case 0xf:
218 isp_prt(isp, ISP_LOGERR, "Board configuration error.");
219 return;
220 default:
221 isp_prt(isp, ISP_LOGERR, "Unknown RISC Status Code 0x%x.", val);
222 return;
223 }
224
225 /*
226 * Reset RISC Processor
227 */
228 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
229 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
230 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
231
232 /*
233 * Post-RISC Reset stuff.
234 */
235 for (loops = 0; loops < 10000; loops++) {
236 ISP_DELAY(5);
237 val = ISP_READ(isp, OUTMAILBOX0);
238 if (val != 0x4)
239 break;
240 }
241 switch (val) {
242 case 0x0:
243 break;
244 case 0x4:
245 isp_prt(isp, ISP_LOGERR, "The ROM code is busy after 50ms.");
246 return;
247 case 0xf:
248 isp_prt(isp, ISP_LOGERR, "Board configuration error.");
249 return;
250 default:
251 isp_prt(isp, ISP_LOGERR, "Unknown RISC Status Code 0x%x.", val);
252 return;
253 }
254
255 isp->isp_reqidx = isp->isp_reqodx = 0;
256 isp->isp_resodx = 0;
257 isp->isp_atioodx = 0;
258 ISP_WRITE(isp, BIU2400_REQINP, 0);
259 ISP_WRITE(isp, BIU2400_REQOUTP, 0);
260 ISP_WRITE(isp, BIU2400_RSPINP, 0);
261 ISP_WRITE(isp, BIU2400_RSPOUTP, 0);
262 if (!IS_26XX(isp)) {
263 ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
264 ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
265 }
266 ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
267 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
268
269 /*
270 * Up until this point we've done everything by just reading or
271 * setting registers. From this point on we rely on at least *some*
272 * kind of firmware running in the card.
273 */
274
275 /*
276 * Do some sanity checking by running a NOP command.
277 * If it succeeds, the ROM firmware is now running.
278 */
279 MBSINIT(&mbs, MBOX_NO_OP, MBLOGALL, 0);
280 isp_mboxcmd(isp, &mbs);
281 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
282 isp_prt(isp, ISP_LOGERR, "NOP command failed (%x)", mbs.param[0]);
283 return;
284 }
285
286 /*
287 * Do some operational tests
288 */
289 {
290 static const uint16_t patterns[MAX_MAILBOX] = {
291 0x0000, 0xdead, 0xbeef, 0xffff,
292 0xa5a5, 0x5a5a, 0x7f7f, 0x7ff7,
293 0x3421, 0xabcd, 0xdcba, 0xfeef,
294 0xbead, 0xdebe, 0x2222, 0x3333,
295 0x5555, 0x6666, 0x7777, 0xaaaa,
296 0xffff, 0xdddd, 0x9999, 0x1fbc,
297 0x6666, 0x6677, 0x1122, 0x33ff,
298 0x0000, 0x0001, 0x1000, 0x1010,
299 };
300 int nmbox = ISP_NMBOX(isp);
301 MBSINIT(&mbs, MBOX_MAILBOX_REG_TEST, MBLOGALL, 0);
302 for (i = 1; i < nmbox; i++) {
303 mbs.param[i] = patterns[i];
304 }
305 isp_mboxcmd(isp, &mbs);
306 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
307 return;
308 }
309 for (i = 1; i < nmbox; i++) {
310 if (mbs.param[i] != patterns[i]) {
311 isp_prt(isp, ISP_LOGERR, "Register Test Failed at Register %d: should have 0x%04x but got 0x%04x", i, patterns[i], mbs.param[i]);
312 return;
313 }
314 }
315 }
316
317 /*
318 * Download new Firmware, unless requested not to do so.
319 * This is made slightly trickier in some cases where the
320 * firmware of the ROM revision is newer than the revision
321 * compiled into the driver. So, where we used to compare
322 * versions of our f/w and the ROM f/w, now we just see
323 * whether we have f/w at all and whether a config flag
324 * has disabled our download.
325 */
326 if ((isp->isp_mdvec->dv_ispfw == NULL) || (isp->isp_confopts & ISP_CFG_NORELOAD)) {
327 dodnld = 0;
328 } else {
329
330 /*
331 * Set up DMA for the request and response queues.
332 * We do this now so we can use the request queue
333 * for dma to load firmware from.
334 */
335 if (ISP_MBOXDMASETUP(isp) != 0) {
336 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
337 return;
338 }
339 }
340
341 code_org = ISP_CODE_ORG_2400;
342 loaded_fw = 0;
343 if (dodnld) {
344 const uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
345 uint32_t la, wi, wl;
346
347 /*
348 * Keep loading until we run out of f/w.
349 */
350 code_org = ptr[2]; /* 1st load address is our start addr */
351 for (;;) {
352 isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], ptr[2]);
353
354 wi = 0;
355 la = ptr[2];
356 wl = ptr[3];
357 while (wi < ptr[3]) {
358 uint32_t *cp;
359 uint32_t nw;
360
361 nw = min(wl, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) / 4);
362 cp = isp->isp_rquest;
363 for (i = 0; i < nw; i++)
364 ISP_IOXPUT_32(isp, ptr[wi + i], &cp[i]);
365 MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1);
366 MBSINIT(&mbs, MBOX_LOAD_RISC_RAM, MBLOGALL, 0);
367 mbs.param[1] = la;
368 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
369 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
370 mbs.param[4] = nw >> 16;
371 mbs.param[5] = nw;
372 mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
373 mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
374 mbs.param[8] = la >> 16;
375 isp_prt(isp, ISP_LOGDEBUG0, "LOAD RISC RAM %u words at load address 0x%x", nw, la);
376 isp_mboxcmd(isp, &mbs);
377 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
378 isp_prt(isp, ISP_LOGERR, "F/W download failed");
379 return;
380 }
381 la += nw;
382 wi += nw;
383 wl -= nw;
384 }
385
386 if (ptr[1] == 0) {
387 break;
388 }
389 ptr += ptr[3];
390 }
391 loaded_fw = 1;
392 } else if (IS_26XX(isp)) {
393 isp_prt(isp, ISP_LOGDEBUG1, "loading firmware from flash");
394 MBSINIT(&mbs, MBOX_LOAD_FLASH_FIRMWARE, MBLOGALL, 5000000);
395 mbs.ibitm = 0x01;
396 mbs.obitm = 0x07;
397 isp_mboxcmd(isp, &mbs);
398 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
399 isp_prt(isp, ISP_LOGERR, "Flash F/W load failed");
400 return;
401 }
402 } else {
403 isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
404 }
405
406 /*
407 * If we loaded firmware, verify its checksum
408 */
409 if (loaded_fw) {
410 MBSINIT(&mbs, MBOX_VERIFY_CHECKSUM, MBLOGNONE, 0);
411 mbs.param[1] = code_org >> 16;
412 mbs.param[2] = code_org;
413 isp_mboxcmd(isp, &mbs);
414 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
415 isp_prt(isp, ISP_LOGERR, dcrc);
416 return;
417 }
418 }
419
420 /*
421 * Now start it rolling.
422 *
423 * If we didn't actually download f/w,
424 * we still need to (re)start it.
425 */
426 MBSINIT(&mbs, MBOX_EXEC_FIRMWARE, MBLOGALL, 5000000);
427 mbs.param[1] = code_org >> 16;
428 mbs.param[2] = code_org;
429 if (!IS_26XX(isp))
430 mbs.param[3] = loaded_fw ? 0 : 1;
431 isp_mboxcmd(isp, &mbs);
432 if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
433 return;
434
435 /*
436 * Ask the chip for the current firmware version.
437 * This should prove that the new firmware is working.
438 */
439 MBSINIT(&mbs, MBOX_ABOUT_FIRMWARE, MBLOGALL, 5000000);
440 isp_mboxcmd(isp, &mbs);
441 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
442 return;
443 }
444
445 isp->isp_fwrev[0] = mbs.param[1];
446 isp->isp_fwrev[1] = mbs.param[2];
447 isp->isp_fwrev[2] = mbs.param[3];
448 isp->isp_fwattr = mbs.param[6];
449 isp->isp_fwattr |= ((uint64_t) mbs.param[15]) << 16;
450 if (isp->isp_fwattr & ISP2400_FW_ATTR_EXTNDED) {
451 isp->isp_fwattr |=
452 (((uint64_t) mbs.param[16]) << 32) |
453 (((uint64_t) mbs.param[17]) << 48);
454 }
455
456 isp_prt(isp, ISP_LOGCONFIG, "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
457 btype, isp->isp_revision, dodnld? "loaded" : "resident", isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
458
459 fwt = isp->isp_fwattr;
460 buf = FCPARAM(isp, 0)->isp_scanscratch;
461 ISP_SNPRINTF(buf, ISP_FC_SCRLEN, "Attributes:");
462 if (fwt & ISP2400_FW_ATTR_CLASS2) {
463 fwt ^=ISP2400_FW_ATTR_CLASS2;
464 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s Class2", buf);
465 }
466 if (fwt & ISP2400_FW_ATTR_IP) {
467 fwt ^=ISP2400_FW_ATTR_IP;
468 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s IP", buf);
469 }
470 if (fwt & ISP2400_FW_ATTR_MULTIID) {
471 fwt ^=ISP2400_FW_ATTR_MULTIID;
472 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MultiID", buf);
473 }
474 if (fwt & ISP2400_FW_ATTR_SB2) {
475 fwt ^=ISP2400_FW_ATTR_SB2;
476 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SB2", buf);
477 }
478 if (fwt & ISP2400_FW_ATTR_T10CRC) {
479 fwt ^=ISP2400_FW_ATTR_T10CRC;
480 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s T10CRC", buf);
481 }
482 if (fwt & ISP2400_FW_ATTR_VI) {
483 fwt ^=ISP2400_FW_ATTR_VI;
484 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VI", buf);
485 }
486 if (fwt & ISP2400_FW_ATTR_MQ) {
487 fwt ^=ISP2400_FW_ATTR_MQ;
488 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MQ", buf);
489 }
490 if (fwt & ISP2400_FW_ATTR_MSIX) {
491 fwt ^=ISP2400_FW_ATTR_MSIX;
492 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MSIX", buf);
493 }
494 if (fwt & ISP2400_FW_ATTR_FCOE) {
495 fwt ^=ISP2400_FW_ATTR_FCOE;
496 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s FCOE", buf);
497 }
498 if (fwt & ISP2400_FW_ATTR_VP0) {
499 fwt ^= ISP2400_FW_ATTR_VP0;
500 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VP0_Decoupling", buf);
501 }
502 if (fwt & ISP2400_FW_ATTR_EXPFW) {
503 fwt ^= ISP2400_FW_ATTR_EXPFW;
504 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s (Experimental)", buf);
505 }
506 if (fwt & ISP2400_FW_ATTR_HOTFW) {
507 fwt ^= ISP2400_FW_ATTR_HOTFW;
508 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s HotFW", buf);
509 }
510 fwt &= ~ISP2400_FW_ATTR_EXTNDED;
511 if (fwt & ISP2400_FW_ATTR_EXTVP) {
512 fwt ^= ISP2400_FW_ATTR_EXTVP;
513 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ExtVP", buf);
514 }
515 if (fwt & ISP2400_FW_ATTR_VN2VN) {
516 fwt ^= ISP2400_FW_ATTR_VN2VN;
517 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VN2VN", buf);
518 }
519 if (fwt & ISP2400_FW_ATTR_EXMOFF) {
520 fwt ^= ISP2400_FW_ATTR_EXMOFF;
521 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s EXMOFF", buf);
522 }
523 if (fwt & ISP2400_FW_ATTR_NPMOFF) {
524 fwt ^= ISP2400_FW_ATTR_NPMOFF;
525 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NPMOFF", buf);
526 }
527 if (fwt & ISP2400_FW_ATTR_DIFCHOP) {
528 fwt ^= ISP2400_FW_ATTR_DIFCHOP;
529 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s DIFCHOP", buf);
530 }
531 if (fwt & ISP2400_FW_ATTR_SRIOV) {
532 fwt ^= ISP2400_FW_ATTR_SRIOV;
533 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SRIOV", buf);
534 }
535 if (fwt & ISP2400_FW_ATTR_ASICTMP) {
536 fwt ^= ISP2400_FW_ATTR_ASICTMP;
537 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ASICTMP", buf);
538 }
539 if (fwt & ISP2400_FW_ATTR_ATIOMQ) {
540 fwt ^= ISP2400_FW_ATTR_ATIOMQ;
541 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ATIOMQ", buf);
542 }
543 if (fwt) {
544 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s (unknown 0x%08x%08x)", buf,
545 (uint32_t) (fwt >> 32), (uint32_t) fwt);
546 }
547 isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
548
549 /*
550 * For the maximum number of commands take free exchange control block
551 * buffer count reported by firmware, limiting it to the maximum of our
552 * hardcoded handle format (16K now) minus some management reserve.
553 */
554 MBSINIT(&mbs, MBOX_GET_RESOURCE_COUNT, MBLOGALL, 0);
555 isp_mboxcmd(isp, &mbs);
556 if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
557 return;
558 isp->isp_maxcmds = MIN(mbs.param[3], ISP_HANDLE_MAX - ISP_HANDLE_RESERVE);
559 isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", isp->isp_maxcmds);
560
561 /*
562 * If we don't have Multi-ID f/w loaded, we need to restrict channels to one.
563 * Only make this check for non-SCSI cards (I'm not sure firmware attributes
564 * work for them).
565 */
566 if (isp->isp_nchan > 1) {
567 if (!ISP_CAP_MULTI_ID(isp)) {
568 isp_prt(isp, ISP_LOGWARN, "non-MULTIID f/w loaded, "
569 "only can enable 1 of %d channels", isp->isp_nchan);
570 isp->isp_nchan = 1;
571 } else if (!ISP_CAP_VP0(isp)) {
572 isp_prt(isp, ISP_LOGWARN, "We can not use MULTIID "
573 "feature properly without VP0_Decoupling");
574 isp->isp_nchan = 1;
575 }
576 }
577
578 /*
579 * Final DMA setup after we got isp_maxcmds.
580 */
581 if (ISP_MBOXDMASETUP(isp) != 0) {
582 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
583 return;
584 }
585
586 /*
587 * Setup interrupts.
588 */
589 if (ISP_IRQSETUP(isp) != 0) {
590 isp_prt(isp, ISP_LOGERR, "Cannot setup IRQ");
591 return;
592 }
593 ISP_ENABLE_INTS(isp);
594
595 for (i = 0; i < isp->isp_nchan; i++)
596 isp_change_fw_state(isp, i, FW_CONFIG_WAIT);
597
598 isp->isp_state = ISP_RESETSTATE;
599
600 /*
601 * We get some default values established. As a side
602 * effect, NVRAM is read here (unless overridden by
603 * a configuration flag).
604 */
605 if (do_load_defaults) {
606 for (i = 0; i < isp->isp_nchan; i++)
607 isp_setdfltfcparm(isp, i);
608 }
609 }
610
611 /*
612 * Clean firmware shutdown.
613 */
614 static int
615 isp_stop(ispsoftc_t *isp)
616 {
617 mbreg_t mbs;
618
619 isp->isp_state = ISP_NILSTATE;
620 MBSINIT(&mbs, MBOX_STOP_FIRMWARE, MBLOGALL, 500000);
621 mbs.param[1] = 0;
622 mbs.param[2] = 0;
623 mbs.param[3] = 0;
624 mbs.param[4] = 0;
625 mbs.param[5] = 0;
626 mbs.param[6] = 0;
627 mbs.param[7] = 0;
628 mbs.param[8] = 0;
629 isp_mboxcmd(isp, &mbs);
630 return (mbs.param[0] == MBOX_COMMAND_COMPLETE ? 0 : mbs.param[0]);
631 }
632
633 /*
634 * Hardware shutdown.
635 */
636 void
637 isp_shutdown(ispsoftc_t *isp)
638 {
639
640 if (isp->isp_state >= ISP_RESETSTATE)
641 isp_stop(isp);
642 ISP_DISABLE_INTS(isp);
643 ISP_WRITE(isp, BIU2400_ICR, 0);
644 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
645 }
646
647 /*
648 * Initialize Parameters of Hardware to a known state.
649 *
650 * Locks are held before coming here.
651 */
652 void
653 isp_init(ispsoftc_t *isp)
654 {
655 fcparam *fcp;
656 isp_icb_2400_t local, *icbp = &local;
657 mbreg_t mbs;
658 int chan;
659 int ownloopid = 0;
660
661 /*
662 * Check to see whether all channels have *some* kind of role
663 */
664 for (chan = 0; chan < isp->isp_nchan; chan++) {
665 fcp = FCPARAM(isp, chan);
666 if (fcp->role != ISP_ROLE_NONE) {
667 break;
668 }
669 }
670 if (chan == isp->isp_nchan) {
671 isp_prt(isp, ISP_LOG_WARN1, "all %d channels with role 'none'", chan);
672 return;
673 }
674
675 isp->isp_state = ISP_INITSTATE;
676
677 /*
678 * Start with channel 0.
679 */
680 fcp = FCPARAM(isp, 0);
681
682 /*
683 * Turn on LIP F8 async event (1)
684 */
685 MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
686 mbs.param[1] = 1;
687 isp_mboxcmd(isp, &mbs);
688 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
689 return;
690 }
691
692 ISP_MEMZERO(icbp, sizeof (*icbp));
693 icbp->icb_fwoptions1 = fcp->isp_fwoptions;
694 icbp->icb_fwoptions2 = fcp->isp_xfwoptions;
695 icbp->icb_fwoptions3 = fcp->isp_zfwoptions;
696 if (isp->isp_nchan > 1 && ISP_CAP_VP0(isp)) {
697 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
698 icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
699 } else {
700 if (fcp->role & ISP_ROLE_TARGET)
701 icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
702 else
703 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_TGT_ENABLE;
704 if (fcp->role & ISP_ROLE_INITIATOR)
705 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
706 else
707 icbp->icb_fwoptions1 |= ICB2400_OPT1_INI_DISABLE;
708 }
709
710 icbp->icb_version = ICB_VERSION1;
711 icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
712 if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
713 isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
714 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
715 }
716
717 if (!IS_26XX(isp))
718 icbp->icb_execthrottle = 0xffff;
719
720 #ifdef ISP_TARGET_MODE
721 /*
722 * Set target exchange count. Take half if we are supporting both roles.
723 */
724 if (icbp->icb_fwoptions1 & ICB2400_OPT1_TGT_ENABLE) {
725 if ((icbp->icb_fwoptions1 & ICB2400_OPT1_INI_DISABLE) == 0)
726 icbp->icb_xchgcnt = MIN(isp->isp_maxcmds / 2, ATPDPSIZE);
727 else
728 icbp->icb_xchgcnt = isp->isp_maxcmds;
729 }
730 #endif
731
732 ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
733 icbp->icb_hardaddr = fcp->isp_loopid;
734 if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
735 icbp->icb_hardaddr = 0;
736 ownloopid = 0;
737 }
738
739 if (ownloopid)
740 icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
741
742 if (isp->isp_confopts & ISP_CFG_NOFCTAPE) {
743 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_FCTAPE;
744 }
745 if (isp->isp_confopts & ISP_CFG_FCTAPE) {
746 icbp->icb_fwoptions2 |= ICB2400_OPT2_FCTAPE;
747 }
748
749 for (chan = 0; chan < isp->isp_nchan; chan++) {
750 if (icbp->icb_fwoptions2 & ICB2400_OPT2_FCTAPE)
751 FCPARAM(isp, chan)->fctape_enabled = 1;
752 else
753 FCPARAM(isp, chan)->fctape_enabled = 0;
754 }
755
756 switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
757 case ISP_CFG_LPORT_ONLY:
758 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
759 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY;
760 break;
761 case ISP_CFG_NPORT_ONLY:
762 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
763 icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY;
764 break;
765 case ISP_CFG_NPORT:
766 /* ISP_CFG_PTP_2_LOOP not available in 24XX/25XX */
767 case ISP_CFG_LPORT:
768 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
769 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
770 break;
771 default:
772 /* Let NVRAM settings define it if they are sane */
773 switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TOPO_MASK) {
774 case ICB2400_OPT2_LOOP_ONLY:
775 case ICB2400_OPT2_PTP_ONLY:
776 case ICB2400_OPT2_LOOP_2_PTP:
777 break;
778 default:
779 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
780 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
781 }
782 break;
783 }
784
785 switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) {
786 case ICB2400_OPT2_ZIO:
787 case ICB2400_OPT2_ZIO1:
788 icbp->icb_idelaytimer = 0;
789 break;
790 case 0:
791 break;
792 default:
793 isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field", icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
794 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK;
795 break;
796 }
797
798 if (IS_26XX(isp)) {
799 /* Use handshake to reduce global lock congestion. */
800 icbp->icb_fwoptions2 |= ICB2400_OPT2_ENA_IHR;
801 icbp->icb_fwoptions2 |= ICB2400_OPT2_ENA_IHA;
802 }
803
804 if ((icbp->icb_fwoptions3 & ICB2400_OPT3_RSPSZ_MASK) == 0) {
805 icbp->icb_fwoptions3 |= ICB2400_OPT3_RSPSZ_24;
806 }
807 if (isp->isp_confopts & ISP_CFG_1GB) {
808 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
809 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_1GB;
810 } else if (isp->isp_confopts & ISP_CFG_2GB) {
811 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
812 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_2GB;
813 } else if (isp->isp_confopts & ISP_CFG_4GB) {
814 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
815 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_4GB;
816 } else if (isp->isp_confopts & ISP_CFG_8GB) {
817 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
818 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_8GB;
819 } else if (isp->isp_confopts & ISP_CFG_16GB) {
820 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
821 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_16GB;
822 } else if (isp->isp_confopts & ISP_CFG_32GB) {
823 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
824 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_32GB;
825 } else {
826 switch (icbp->icb_fwoptions3 & ICB2400_OPT3_RATE_MASK) {
827 case ICB2400_OPT3_RATE_4GB:
828 case ICB2400_OPT3_RATE_8GB:
829 case ICB2400_OPT3_RATE_16GB:
830 case ICB2400_OPT3_RATE_32GB:
831 case ICB2400_OPT3_RATE_AUTO:
832 break;
833 case ICB2400_OPT3_RATE_2GB:
834 if (isp->isp_type <= ISP_HA_FC_2500)
835 break;
836 /*FALLTHROUGH*/
837 case ICB2400_OPT3_RATE_1GB:
838 if (isp->isp_type <= ISP_HA_FC_2400)
839 break;
840 /*FALLTHROUGH*/
841 default:
842 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
843 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
844 break;
845 }
846 }
847 if (ownloopid == 0) {
848 icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID;
849 }
850 icbp->icb_logintime = ICB_LOGIN_TOV;
851
852 if (fcp->isp_wwnn && fcp->isp_wwpn) {
853 icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
854 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
855 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
856 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)),
857 ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
858 } else if (fcp->isp_wwpn) {
859 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS;
860 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
861 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)));
862 } else {
863 isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
864 return;
865 }
866 icbp->icb_rspnsin = isp->isp_resodx;
867 icbp->icb_rqstout = isp->isp_reqidx;
868 icbp->icb_retry_count = fcp->isp_retry_count;
869
870 icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
871 if (icbp->icb_rqstqlen < 8) {
872 isp_prt(isp, ISP_LOGERR, "bad request queue length %d", icbp->icb_rqstqlen);
873 return;
874 }
875 icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
876 if (icbp->icb_rsltqlen < 8) {
877 isp_prt(isp, ISP_LOGERR, "bad result queue length %d",
878 icbp->icb_rsltqlen);
879 return;
880 }
881 icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
882 icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
883 icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
884 icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
885
886 icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
887 icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
888 icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
889 icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
890
891 #ifdef ISP_TARGET_MODE
892 /* unconditionally set up the ATIO queue if we support target mode */
893 icbp->icb_atio_in = isp->isp_atioodx;
894 icbp->icb_atioqlen = ATIO_QUEUE_LEN(isp);
895 if (icbp->icb_atioqlen < 8) {
896 isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d", icbp->icb_atioqlen);
897 return;
898 }
899 icbp->icb_atioqaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_atioq_dma);
900 icbp->icb_atioqaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_atioq_dma);
901 icbp->icb_atioqaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_atioq_dma);
902 icbp->icb_atioqaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_atioq_dma);
903 isp_prt(isp, ISP_LOGDEBUG0, "isp_init: atioq %04x%04x%04x%04x", DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma),
904 DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma));
905 #endif
906
907 if (ISP_CAP_MSIX(isp) && isp->isp_nirq >= 2) {
908 icbp->icb_msixresp = 1;
909 if (IS_26XX(isp) && isp->isp_nirq >= 3)
910 icbp->icb_msixatio = 2;
911 }
912
913 isp_prt(isp, ISP_LOGDEBUG0, "isp_init: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3);
914
915 isp_prt(isp, ISP_LOGDEBUG0, "isp_init: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x", DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma),
916 DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma), DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
917 DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
918
919 if (FC_SCRATCH_ACQUIRE(isp, 0)) {
920 isp_prt(isp, ISP_LOGERR, sacq);
921 return;
922 }
923 ISP_MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
924 isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
925 if (isp->isp_dblev & ISP_LOGDEBUG1) {
926 isp_print_bytes(isp, "isp_init",
927 sizeof (*icbp), fcp->isp_scratch);
928 }
929
930 /*
931 * Now fill in information about any additional channels
932 */
933 if (isp->isp_nchan > 1) {
934 isp_icb_2400_vpinfo_t vpinfo, *vdst;
935 vp_port_info_t pi, *pdst;
936 size_t amt = 0;
937 uint8_t *off;
938
939 vpinfo.vp_global_options = ICB2400_VPGOPT_GEN_RIDA;
940 if (ISP_CAP_VP0(isp)) {
941 vpinfo.vp_global_options |= ICB2400_VPGOPT_VP0_DECOUPLE;
942 vpinfo.vp_count = isp->isp_nchan;
943 chan = 0;
944 } else {
945 vpinfo.vp_count = isp->isp_nchan - 1;
946 chan = 1;
947 }
948 off = fcp->isp_scratch;
949 off += ICB2400_VPINFO_OFF;
950 vdst = (isp_icb_2400_vpinfo_t *) off;
951 isp_put_icb_2400_vpinfo(isp, &vpinfo, vdst);
952 amt = ICB2400_VPINFO_OFF + sizeof (isp_icb_2400_vpinfo_t);
953 for (; chan < isp->isp_nchan; chan++) {
954 fcparam *fcp2;
955
956 ISP_MEMZERO(&pi, sizeof (pi));
957 fcp2 = FCPARAM(isp, chan);
958 if (fcp2->role != ISP_ROLE_NONE) {
959 pi.vp_port_options = ICB2400_VPOPT_ENABLED |
960 ICB2400_VPOPT_ENA_SNSLOGIN;
961 if (fcp2->role & ISP_ROLE_INITIATOR)
962 pi.vp_port_options |= ICB2400_VPOPT_INI_ENABLE;
963 if ((fcp2->role & ISP_ROLE_TARGET) == 0)
964 pi.vp_port_options |= ICB2400_VPOPT_TGT_DISABLE;
965 if (fcp2->isp_loopid < LOCAL_LOOP_LIM) {
966 pi.vp_port_loopid = fcp2->isp_loopid;
967 if (isp->isp_confopts & ISP_CFG_OWNLOOPID)
968 pi.vp_port_options |= ICB2400_VPOPT_HARD_ADDRESS;
969 }
970
971 }
972 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname, fcp2->isp_wwpn);
973 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename, fcp2->isp_wwnn);
974 off = fcp->isp_scratch;
975 if (ISP_CAP_VP0(isp))
976 off += ICB2400_VPINFO_PORT_OFF(chan);
977 else
978 off += ICB2400_VPINFO_PORT_OFF(chan - 1);
979 pdst = (vp_port_info_t *) off;
980 isp_put_vp_port_info(isp, &pi, pdst);
981 amt += ICB2400_VPOPT_WRITE_SIZE;
982 }
983 if (isp->isp_dblev & ISP_LOGDEBUG1) {
984 isp_print_bytes(isp, "isp_init",
985 amt - ICB2400_VPINFO_OFF,
986 (char *)fcp->isp_scratch + ICB2400_VPINFO_OFF);
987 }
988 }
989
990 /*
991 * Init the firmware
992 */
993 MBSINIT(&mbs, 0, MBLOGALL, 30000000);
994 if (isp->isp_nchan > 1) {
995 mbs.param[0] = MBOX_INIT_FIRMWARE_MULTI_ID;
996 } else {
997 mbs.param[0] = MBOX_INIT_FIRMWARE;
998 }
999 mbs.param[1] = 0;
1000 mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1001 mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1002 mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1003 mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1004 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));
1005 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp), 0);
1006 isp_mboxcmd(isp, &mbs);
1007 FC_SCRATCH_RELEASE(isp, 0);
1008
1009 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1010 return;
1011 }
1012
1013 /*
1014 * Whatever happens, we're now committed to being here.
1015 */
1016 isp->isp_state = ISP_RUNSTATE;
1017 }
1018
1019 static int
1020 isp_fc_enable_vp(ispsoftc_t *isp, int chan)
1021 {
1022 fcparam *fcp = FCPARAM(isp, chan);
1023 vp_modify_t vp;
1024 int retval;
1025
1026 /* Build a VP MODIFY command in memory */
1027 ISP_MEMZERO(&vp, sizeof(vp));
1028 vp.vp_mod_hdr.rqs_entry_type = RQSTYPE_VP_MODIFY;
1029 vp.vp_mod_hdr.rqs_entry_count = 1;
1030 vp.vp_mod_cnt = 1;
1031 vp.vp_mod_idx0 = chan;
1032 vp.vp_mod_cmd = VP_MODIFY_ENA;
1033 vp.vp_mod_ports[0].options = ICB2400_VPOPT_ENABLED |
1034 ICB2400_VPOPT_ENA_SNSLOGIN;
1035 if (fcp->role & ISP_ROLE_INITIATOR)
1036 vp.vp_mod_ports[0].options |= ICB2400_VPOPT_INI_ENABLE;
1037 if ((fcp->role & ISP_ROLE_TARGET) == 0)
1038 vp.vp_mod_ports[0].options |= ICB2400_VPOPT_TGT_DISABLE;
1039 if (fcp->isp_loopid < LOCAL_LOOP_LIM) {
1040 vp.vp_mod_ports[0].loopid = fcp->isp_loopid;
1041 if (isp->isp_confopts & ISP_CFG_OWNLOOPID)
1042 vp.vp_mod_ports[0].options |= ICB2400_VPOPT_HARD_ADDRESS;
1043 }
1044 MAKE_NODE_NAME_FROM_WWN(vp.vp_mod_ports[0].wwpn, fcp->isp_wwpn);
1045 MAKE_NODE_NAME_FROM_WWN(vp.vp_mod_ports[0].wwnn, fcp->isp_wwnn);
1046
1047 retval = isp_exec_entry_queue(isp, &vp, &vp, 5);
1048 if (retval != 0) {
1049 isp_prt(isp, ISP_LOGERR, "%s: VP_MODIFY of chan %d error %d",
1050 __func__, chan, retval);
1051 return (retval);
1052 }
1053
1054 if (vp.vp_mod_hdr.rqs_flags != 0 || vp.vp_mod_status != VP_STS_OK) {
1055 isp_prt(isp, ISP_LOGERR,
1056 "%s: VP_MODIFY of Chan %d failed with flags %x status %d",
1057 __func__, chan, vp.vp_mod_hdr.rqs_flags, vp.vp_mod_status);
1058 return (EIO);
1059 }
1060 return (0);
1061 }
1062
1063 static int
1064 isp_fc_disable_vp(ispsoftc_t *isp, int chan)
1065 {
1066 vp_ctrl_info_t vp;
1067 int retval;
1068
1069 /* Build a VP CTRL command in memory */
1070 ISP_MEMZERO(&vp, sizeof(vp));
1071 vp.vp_ctrl_hdr.rqs_entry_type = RQSTYPE_VP_CTRL;
1072 vp.vp_ctrl_hdr.rqs_entry_count = 1;
1073 if (ISP_CAP_VP0(isp)) {
1074 vp.vp_ctrl_status = 1;
1075 } else {
1076 vp.vp_ctrl_status = 0;
1077 chan--; /* VP0 can not be controlled in this case. */
1078 }
1079 vp.vp_ctrl_command = VP_CTRL_CMD_DISABLE_VP_LOGO_ALL;
1080 vp.vp_ctrl_vp_count = 1;
1081 vp.vp_ctrl_idmap[chan / 16] |= (1 << chan % 16);
1082
1083 retval = isp_exec_entry_queue(isp, &vp, &vp, 5);
1084 if (retval != 0) {
1085 isp_prt(isp, ISP_LOGERR, "%s: VP_CTRL of chan %d error %d",
1086 __func__, chan, retval);
1087 return (retval);
1088 }
1089
1090 if (vp.vp_ctrl_hdr.rqs_flags != 0 || vp.vp_ctrl_status != 0) {
1091 isp_prt(isp, ISP_LOGERR,
1092 "%s: VP_CTRL of Chan %d failed with flags %x status %d %d",
1093 __func__, chan, vp.vp_ctrl_hdr.rqs_flags,
1094 vp.vp_ctrl_status, vp.vp_ctrl_index_fail);
1095 return (EIO);
1096 }
1097 return (0);
1098 }
1099
1100 static int
1101 isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role)
1102 {
1103 fcparam *fcp = FCPARAM(isp, chan);
1104 int i, was, res = 0;
1105
1106 if (chan >= isp->isp_nchan) {
1107 isp_prt(isp, ISP_LOGWARN, "%s: bad channel %d", __func__, chan);
1108 return (ENXIO);
1109 }
1110 if (fcp->role == new_role)
1111 return (0);
1112 for (was = 0, i = 0; i < isp->isp_nchan; i++) {
1113 if (FCPARAM(isp, i)->role != ISP_ROLE_NONE)
1114 was++;
1115 }
1116 if (was == 0 || (was == 1 && fcp->role != ISP_ROLE_NONE)) {
1117 fcp->role = new_role;
1118 return (isp_reinit(isp, 0));
1119 }
1120 if (fcp->role != ISP_ROLE_NONE) {
1121 res = isp_fc_disable_vp(isp, chan);
1122 isp_clear_portdb(isp, chan);
1123 }
1124 fcp->role = new_role;
1125 if (fcp->role != ISP_ROLE_NONE)
1126 res = isp_fc_enable_vp(isp, chan);
1127 return (res);
1128 }
1129
1130 static void
1131 isp_clear_portdb(ispsoftc_t *isp, int chan)
1132 {
1133 fcparam *fcp = FCPARAM(isp, chan);
1134 fcportdb_t *lp;
1135 int i;
1136
1137 for (i = 0; i < MAX_FC_TARG; i++) {
1138 lp = &fcp->portdb[i];
1139 switch (lp->state) {
1140 case FC_PORTDB_STATE_DEAD:
1141 case FC_PORTDB_STATE_CHANGED:
1142 case FC_PORTDB_STATE_VALID:
1143 lp->state = FC_PORTDB_STATE_NIL;
1144 isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
1145 break;
1146 case FC_PORTDB_STATE_NIL:
1147 case FC_PORTDB_STATE_NEW:
1148 lp->state = FC_PORTDB_STATE_NIL;
1149 break;
1150 case FC_PORTDB_STATE_ZOMBIE:
1151 break;
1152 default:
1153 panic("Don't know how to clear state %d\n", lp->state);
1154 }
1155 }
1156 }
1157
1158 static void
1159 isp_mark_portdb(ispsoftc_t *isp, int chan)
1160 {
1161 fcparam *fcp = FCPARAM(isp, chan);
1162 fcportdb_t *lp;
1163 int i;
1164
1165 for (i = 0; i < MAX_FC_TARG; i++) {
1166 lp = &fcp->portdb[i];
1167 if (lp->state == FC_PORTDB_STATE_NIL)
1168 continue;
1169 if (lp->portid >= DOMAIN_CONTROLLER_BASE &&
1170 lp->portid <= DOMAIN_CONTROLLER_END)
1171 continue;
1172 fcp->portdb[i].probational = 1;
1173 }
1174 }
1175
1176 /*
1177 * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards
1178 * or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
1179 */
1180 static int
1181 isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags)
1182 {
1183 isp_plogx_t pl;
1184 uint32_t sst, parm1;
1185 int retval, lev;
1186 const char *msg;
1187 char buf[64];
1188
1189 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d PLOGX %s PortID 0x%06x nphdl 0x%x",
1190 chan, (flags & PLOGX_FLG_CMD_MASK) == PLOGX_FLG_CMD_PLOGI ?
1191 "Login":"Logout", portid, handle);
1192
1193 ISP_MEMZERO(&pl, sizeof(pl));
1194 pl.plogx_header.rqs_entry_count = 1;
1195 pl.plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
1196 pl.plogx_nphdl = handle;
1197 pl.plogx_vphdl = chan;
1198 pl.plogx_portlo = portid;
1199 pl.plogx_rspsz_porthi = (portid >> 16) & 0xff;
1200 pl.plogx_flags = flags;
1201
1202 retval = isp_exec_entry_queue(isp, &pl, &pl, 3 * ICB_LOGIN_TOV);
1203 if (retval != 0) {
1204 isp_prt(isp, ISP_LOGERR, "%s: PLOGX of chan %d error %d",
1205 __func__, chan, retval);
1206 return (retval);
1207 }
1208
1209 if (pl.plogx_status == PLOGX_STATUS_OK) {
1210 return (0);
1211 } else if (pl.plogx_status != PLOGX_STATUS_IOCBERR) {
1212 isp_prt(isp, ISP_LOGWARN,
1213 "status 0x%x on port login IOCB channel %d",
1214 pl.plogx_status, chan);
1215 return (-1);
1216 }
1217
1218 sst = pl.plogx_ioparm[0].lo16 | (pl.plogx_ioparm[0].hi16 << 16);
1219 parm1 = pl.plogx_ioparm[1].lo16 | (pl.plogx_ioparm[1].hi16 << 16);
1220
1221 retval = -1;
1222 lev = ISP_LOGERR;
1223 msg = NULL;
1224
1225 switch (sst) {
1226 case PLOGX_IOCBERR_NOLINK:
1227 msg = "no link";
1228 break;
1229 case PLOGX_IOCBERR_NOIOCB:
1230 msg = "no IOCB buffer";
1231 break;
1232 case PLOGX_IOCBERR_NOXGHG:
1233 msg = "no Exchange Control Block";
1234 break;
1235 case PLOGX_IOCBERR_FAILED:
1236 ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff);
1237 msg = buf;
1238 break;
1239 case PLOGX_IOCBERR_NOFABRIC:
1240 msg = "no fabric";
1241 break;
1242 case PLOGX_IOCBERR_NOTREADY:
1243 msg = "firmware not ready";
1244 break;
1245 case PLOGX_IOCBERR_NOLOGIN:
1246 ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1);
1247 msg = buf;
1248 retval = MBOX_NOT_LOGGED_IN;
1249 break;
1250 case PLOGX_IOCBERR_REJECT:
1251 ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1);
1252 msg = buf;
1253 break;
1254 case PLOGX_IOCBERR_NOPCB:
1255 msg = "no PCB allocated";
1256 break;
1257 case PLOGX_IOCBERR_EINVAL:
1258 ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1);
1259 msg = buf;
1260 break;
1261 case PLOGX_IOCBERR_PORTUSED:
1262 lev = ISP_LOG_SANCFG|ISP_LOG_WARN1;
1263 ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1);
1264 msg = buf;
1265 retval = MBOX_PORT_ID_USED | (parm1 << 16);
1266 break;
1267 case PLOGX_IOCBERR_HNDLUSED:
1268 lev = ISP_LOG_SANCFG|ISP_LOG_WARN1;
1269 ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1);
1270 msg = buf;
1271 retval = MBOX_LOOP_ID_USED;
1272 break;
1273 case PLOGX_IOCBERR_NOHANDLE:
1274 msg = "no handle allocated";
1275 break;
1276 case PLOGX_IOCBERR_NOFLOGI:
1277 msg = "no FLOGI_ACC";
1278 break;
1279 default:
1280 ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", pl.plogx_status, flags);
1281 msg = buf;
1282 break;
1283 }
1284 if (msg) {
1285 isp_prt(isp, lev, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s",
1286 chan, portid, handle, msg);
1287 }
1288 return (retval);
1289 }
1290
1291 static int
1292 isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb)
1293 {
1294 mbreg_t mbs;
1295 union {
1296 isp_pdb_24xx_t bill;
1297 } un;
1298
1299 MBSINIT(&mbs, MBOX_GET_PORT_DB,
1300 MBLOGALL & ~MBLOGMASK(MBOX_COMMAND_PARAM_ERROR), 250000);
1301 mbs.ibits = (1 << 9)|(1 << 10);
1302 mbs.param[1] = id;
1303 mbs.param[2] = DMA_WD1(isp->isp_iocb_dma);
1304 mbs.param[3] = DMA_WD0(isp->isp_iocb_dma);
1305 mbs.param[6] = DMA_WD3(isp->isp_iocb_dma);
1306 mbs.param[7] = DMA_WD2(isp->isp_iocb_dma);
1307 mbs.param[9] = chan;
1308 MEMORYBARRIER(isp, SYNC_IFORDEV, 0, sizeof(un), chan);
1309
1310 isp_mboxcmd(isp, &mbs);
1311 if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
1312 return (mbs.param[0] | (mbs.param[1] << 16));
1313
1314 MEMORYBARRIER(isp, SYNC_IFORCPU, 0, sizeof(un), chan);
1315 isp_get_pdb_24xx(isp, isp->isp_iocb, &un.bill);
1316 pdb->handle = un.bill.pdb_handle;
1317 pdb->prli_word0 = un.bill.pdb_prli_svc0;
1318 pdb->prli_word3 = un.bill.pdb_prli_svc3;
1319 pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
1320 ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
1321 ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
1322 isp_prt(isp, ISP_LOGDEBUG0,
1323 "Chan %d handle 0x%x Port 0x%06x flags 0x%x curstate %x laststate %x",
1324 chan, id, pdb->portid, un.bill.pdb_flags,
1325 un.bill.pdb_curstate, un.bill.pdb_laststate);
1326
1327 if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE || un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) {
1328 mbs.param[0] = MBOX_NOT_LOGGED_IN;
1329 return (mbs.param[0]);
1330 }
1331 return (0);
1332 }
1333
1334 static int
1335 isp_gethandles(ispsoftc_t *isp, int chan, uint16_t *handles, int *num, int loop)
1336 {
1337 fcparam *fcp = FCPARAM(isp, chan);
1338 mbreg_t mbs;
1339 isp_pnhle_24xx_t el4, *elp4;
1340 int i, j;
1341 uint32_t p;
1342
1343 MBSINIT(&mbs, MBOX_GET_ID_LIST, MBLOGALL, 250000);
1344 mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1345 mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1346 mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1347 mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1348 mbs.param[8] = ISP_FC_SCRLEN;
1349 mbs.param[9] = chan;
1350 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
1351 isp_prt(isp, ISP_LOGERR, sacq);
1352 return (-1);
1353 }
1354 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, ISP_FC_SCRLEN, chan);
1355 isp_mboxcmd(isp, &mbs);
1356 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1357 FC_SCRATCH_RELEASE(isp, chan);
1358 return (mbs.param[0] | (mbs.param[1] << 16));
1359 }
1360 MEMORYBARRIER(isp, SYNC_SFORCPU, 0, ISP_FC_SCRLEN, chan);
1361 elp4 = fcp->isp_scratch;
1362 for (i = 0, j = 0; i < mbs.param[1] && j < *num; i++) {
1363 isp_get_pnhle_24xx(isp, &elp4[i], &el4);
1364 p = el4.pnhle_port_id_lo | (el4.pnhle_port_id_hi << 16);
1365 if (loop && (p >> 8) != (fcp->isp_portid >> 8))
1366 continue;
1367 handles[j++] = el4.pnhle_handle;
1368 }
1369 *num = j;
1370 FC_SCRATCH_RELEASE(isp, chan);
1371 return (0);
1372 }
1373
1374 static void
1375 isp_dump_chip_portdb(ispsoftc_t *isp, int chan)
1376 {
1377 isp_pdb_t pdb;
1378 uint16_t nphdl;
1379
1380 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d chip port dump", chan);
1381 for (nphdl = 0; nphdl != NPH_MAX_2K; nphdl++) {
1382 if (isp_getpdb(isp, chan, nphdl, &pdb)) {
1383 continue;
1384 }
1385 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d Handle 0x%04x "
1386 "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x",
1387 chan, nphdl, pdb.portid, pdb.portname[0], pdb.portname[1],
1388 pdb.portname[2], pdb.portname[3], pdb.portname[4],
1389 pdb.portname[5], pdb.portname[6], pdb.portname[7]);
1390 }
1391 }
1392
1393 static uint64_t
1394 isp_get_wwn(ispsoftc_t *isp, int chan, int nphdl, int nodename)
1395 {
1396 uint64_t wwn = INI_NONE;
1397 mbreg_t mbs;
1398
1399 MBSINIT(&mbs, MBOX_GET_PORT_NAME,
1400 MBLOGALL & ~MBLOGMASK(MBOX_COMMAND_PARAM_ERROR), 500000);
1401 mbs.param[1] = nphdl;
1402 if (nodename)
1403 mbs.param[10] = 1;
1404 mbs.param[9] = chan;
1405 isp_mboxcmd(isp, &mbs);
1406 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1407 return (wwn);
1408 }
1409 wwn = (((uint64_t)(mbs.param[2] >> 8)) << 56) |
1410 (((uint64_t)(mbs.param[2] & 0xff))<< 48) |
1411 (((uint64_t)(mbs.param[3] >> 8)) << 40) |
1412 (((uint64_t)(mbs.param[3] & 0xff))<< 32) |
1413 (((uint64_t)(mbs.param[6] >> 8)) << 24) |
1414 (((uint64_t)(mbs.param[6] & 0xff))<< 16) |
1415 (((uint64_t)(mbs.param[7] >> 8)) << 8) |
1416 (((uint64_t)(mbs.param[7] & 0xff)));
1417 return (wwn);
1418 }
1419
1420 /*
1421 * Make sure we have good FC link.
1422 */
1423
1424 static int
1425 isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
1426 {
1427 mbreg_t mbs;
1428 int i, r, topo;
1429 fcparam *fcp;
1430 isp_pdb_t pdb;
1431 NANOTIME_T hra, hrb;
1432
1433 fcp = FCPARAM(isp, chan);
1434
1435 if (fcp->isp_loopstate < LOOP_HAVE_LINK)
1436 return (-1);
1437 if (fcp->isp_loopstate >= LOOP_LTEST_DONE)
1438 return (0);
1439
1440 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test", chan);
1441
1442 /*
1443 * Wait up to N microseconds for F/W to go to a ready state.
1444 */
1445 GET_NANOTIME(&hra);
1446 while (1) {
1447 isp_change_fw_state(isp, chan, isp_fw_state(isp, chan));
1448 if (fcp->isp_fwstate == FW_READY) {
1449 break;
1450 }
1451 if (fcp->isp_loopstate < LOOP_HAVE_LINK)
1452 goto abort;
1453 GET_NANOTIME(&hrb);
1454 if ((NANOTIME_SUB(&hrb, &hra) / 1000 + 1000 >= usdelay))
1455 break;
1456 ISP_SLEEP(isp, 1000);
1457 }
1458 if (fcp->isp_fwstate != FW_READY) {
1459 isp_prt(isp, ISP_LOG_SANCFG,
1460 "Chan %d Firmware is not ready (%s)",
1461 chan, isp_fc_fw_statename(fcp->isp_fwstate));
1462 return (-1);
1463 }
1464
1465 /*
1466 * Get our Loop ID and Port ID.
1467 */
1468 MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0);
1469 mbs.param[9] = chan;
1470 isp_mboxcmd(isp, &mbs);
1471 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1472 return (-1);
1473 }
1474
1475 topo = (int) mbs.param[6];
1476 if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
1477 topo = TOPO_PTP_STUB;
1478 fcp->isp_topo = topo;
1479 fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
1480
1481 if (!TOPO_IS_FABRIC(fcp->isp_topo)) {
1482 fcp->isp_loopid = mbs.param[1] & 0xff;
1483 } else if (fcp->isp_topo != TOPO_F_PORT) {
1484 uint8_t alpa = fcp->isp_portid;
1485
1486 for (i = 0; alpa_map[i]; i++) {
1487 if (alpa_map[i] == alpa)
1488 break;
1489 }
1490 if (alpa_map[i])
1491 fcp->isp_loopid = i;
1492 }
1493
1494 #if 0
1495 fcp->isp_loopstate = LOOP_HAVE_ADDR;
1496 #endif
1497 fcp->isp_loopstate = LOOP_TESTING_LINK;
1498
1499 if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
1500 r = isp_getpdb(isp, chan, NPH_FL_ID, &pdb);
1501 if (r != 0 || pdb.portid == 0) {
1502 isp_prt(isp, ISP_LOGWARN,
1503 "fabric topology, but cannot get info about fabric controller (0x%x)", r);
1504 fcp->isp_topo = TOPO_PTP_STUB;
1505 goto not_on_fabric;
1506 }
1507
1508 fcp->isp_fabric_params = mbs.param[7];
1509 fcp->isp_sns_hdl = NPH_SNS_ID;
1510 r = isp_register_fc4_type(isp, chan);
1511 if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1512 goto abort;
1513 if (r != 0)
1514 goto not_on_fabric;
1515 r = isp_register_fc4_features_24xx(isp, chan);
1516 if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1517 goto abort;
1518 if (r != 0)
1519 goto not_on_fabric;
1520 r = isp_register_port_name_24xx(isp, chan);
1521 if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1522 goto abort;
1523 if (r != 0)
1524 goto not_on_fabric;
1525 isp_register_node_name_24xx(isp, chan);
1526 if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1527 goto abort;
1528 }
1529
1530 not_on_fabric:
1531 /* Get link speed. */
1532 fcp->isp_gbspeed = 1;
1533 MBSINIT(&mbs, MBOX_GET_SET_DATA_RATE, MBLOGALL, 3000000);
1534 mbs.param[1] = MBGSD_GET_RATE;
1535 /* mbs.param[2] undefined if we're just getting rate */
1536 isp_mboxcmd(isp, &mbs);
1537 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1538 if (mbs.param[1] == MBGSD_10GB)
1539 fcp->isp_gbspeed = 10;
1540 else if (mbs.param[1] == MBGSD_32GB)
1541 fcp->isp_gbspeed = 32;
1542 else if (mbs.param[1] == MBGSD_16GB)
1543 fcp->isp_gbspeed = 16;
1544 else if (mbs.param[1] == MBGSD_8GB)
1545 fcp->isp_gbspeed = 8;
1546 else if (mbs.param[1] == MBGSD_4GB)
1547 fcp->isp_gbspeed = 4;
1548 else if (mbs.param[1] == MBGSD_2GB)
1549 fcp->isp_gbspeed = 2;
1550 else if (mbs.param[1] == MBGSD_1GB)
1551 fcp->isp_gbspeed = 1;
1552 }
1553
1554 if (fcp->isp_loopstate < LOOP_TESTING_LINK) {
1555 abort:
1556 isp_prt(isp, ISP_LOG_SANCFG,
1557 "Chan %d FC link test aborted", chan);
1558 return (1);
1559 }
1560 fcp->isp_loopstate = LOOP_LTEST_DONE;
1561 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGCONFIG,
1562 "Chan %d WWPN %016jx WWNN %016jx",
1563 chan, (uintmax_t)fcp->isp_wwpn, (uintmax_t)fcp->isp_wwnn);
1564 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGCONFIG,
1565 "Chan %d %dGb %s PortID 0x%06x LoopID 0x%02x",
1566 chan, fcp->isp_gbspeed, isp_fc_toponame(fcp), fcp->isp_portid,
1567 fcp->isp_loopid);
1568 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test done", chan);
1569 return (0);
1570 }
1571
1572 /*
1573 * Complete the synchronization of our Port Database.
1574 *
1575 * At this point, we've scanned the local loop (if any) and the fabric
1576 * and performed fabric logins on all new devices.
1577 *
1578 * Our task here is to go through our port database removing any entities
1579 * that are still marked probational (issuing PLOGO for ones which we had
1580 * PLOGI'd into) or are dead, and notifying upper layers about new/changed
1581 * devices.
1582 */
1583 static int
1584 isp_pdb_sync(ispsoftc_t *isp, int chan)
1585 {
1586 fcparam *fcp = FCPARAM(isp, chan);
1587 fcportdb_t *lp;
1588 uint16_t dbidx;
1589
1590 if (fcp->isp_loopstate < LOOP_FSCAN_DONE)
1591 return (-1);
1592 if (fcp->isp_loopstate >= LOOP_READY)
1593 return (0);
1594
1595 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync", chan);
1596
1597 fcp->isp_loopstate = LOOP_SYNCING_PDB;
1598
1599 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
1600 lp = &fcp->portdb[dbidx];
1601
1602 if (lp->state == FC_PORTDB_STATE_NIL)
1603 continue;
1604 if (lp->probational && lp->state != FC_PORTDB_STATE_ZOMBIE)
1605 lp->state = FC_PORTDB_STATE_DEAD;
1606 switch (lp->state) {
1607 case FC_PORTDB_STATE_DEAD:
1608 lp->state = FC_PORTDB_STATE_NIL;
1609 isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
1610 if ((lp->portid & 0xffff00) != 0) {
1611 (void) isp_plogx(isp, chan, lp->handle,
1612 lp->portid,
1613 PLOGX_FLG_CMD_LOGO |
1614 PLOGX_FLG_IMPLICIT |
1615 PLOGX_FLG_FREE_NPHDL);
1616 }
1617 /*
1618 * Note that we might come out of this with our state
1619 * set to FC_PORTDB_STATE_ZOMBIE.
1620 */
1621 break;
1622 case FC_PORTDB_STATE_NEW:
1623 lp->state = FC_PORTDB_STATE_VALID;
1624 isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
1625 break;
1626 case FC_PORTDB_STATE_CHANGED:
1627 lp->state = FC_PORTDB_STATE_VALID;
1628 isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
1629 lp->portid = lp->new_portid;
1630 lp->prli_word0 = lp->new_prli_word0;
1631 lp->prli_word3 = lp->new_prli_word3;
1632 break;
1633 case FC_PORTDB_STATE_VALID:
1634 isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
1635 break;
1636 case FC_PORTDB_STATE_ZOMBIE:
1637 break;
1638 default:
1639 isp_prt(isp, ISP_LOGWARN,
1640 "isp_pdb_sync: state %d for idx %d",
1641 lp->state, dbidx);
1642 isp_dump_portdb(isp, chan);
1643 }
1644 }
1645
1646 if (fcp->isp_loopstate < LOOP_SYNCING_PDB) {
1647 isp_prt(isp, ISP_LOG_SANCFG,
1648 "Chan %d FC PDB sync aborted", chan);
1649 return (1);
1650 }
1651
1652 fcp->isp_loopstate = LOOP_READY;
1653 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync done", chan);
1654 return (0);
1655 }
1656
1657 static void
1658 isp_pdb_add_update(ispsoftc_t *isp, int chan, isp_pdb_t *pdb)
1659 {
1660 fcportdb_t *lp;
1661 uint64_t wwnn, wwpn;
1662
1663 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb->nodename);
1664 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb->portname);
1665
1666 /* Search port database for the same WWPN. */
1667 if (isp_find_pdb_by_wwpn(isp, chan, wwpn, &lp)) {
1668 if (!lp->probational) {
1669 isp_prt(isp, ISP_LOGERR,
1670 "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)",
1671 chan, lp->portid, lp->handle,
1672 FC_PORTDB_TGT(isp, chan, lp), lp->state);
1673 isp_dump_portdb(isp, chan);
1674 return;
1675 }
1676 lp->probational = 0;
1677 lp->node_wwn = wwnn;
1678
1679 /* Old device, nothing new. */
1680 if (lp->portid == pdb->portid &&
1681 lp->handle == pdb->handle &&
1682 lp->prli_word3 == pdb->prli_word3 &&
1683 ((pdb->prli_word0 & PRLI_WD0_EST_IMAGE_PAIR) ==
1684 (lp->prli_word0 & PRLI_WD0_EST_IMAGE_PAIR))) {
1685 if (lp->state != FC_PORTDB_STATE_NEW)
1686 lp->state = FC_PORTDB_STATE_VALID;
1687 isp_prt(isp, ISP_LOG_SANCFG,
1688 "Chan %d Port 0x%06x@0x%04x is valid",
1689 chan, pdb->portid, pdb->handle);
1690 return;
1691 }
1692
1693 /* Something has changed. */
1694 lp->state = FC_PORTDB_STATE_CHANGED;
1695 lp->handle = pdb->handle;
1696 lp->new_portid = pdb->portid;
1697 lp->new_prli_word0 = pdb->prli_word0;
1698 lp->new_prli_word3 = pdb->prli_word3;
1699 isp_prt(isp, ISP_LOG_SANCFG,
1700 "Chan %d Port 0x%06x@0x%04x is changed",
1701 chan, pdb->portid, pdb->handle);
1702 return;
1703 }
1704
1705 /* It seems like a new port. Find an empty slot for it. */
1706 if (!isp_find_pdb_empty(isp, chan, &lp)) {
1707 isp_prt(isp, ISP_LOGERR, "Chan %d out of portdb entries", chan);
1708 return;
1709 }
1710
1711 ISP_MEMZERO(lp, sizeof (fcportdb_t));
1712 lp->probational = 0;
1713 lp->state = FC_PORTDB_STATE_NEW;
1714 lp->portid = lp->new_portid = pdb->portid;
1715 lp->prli_word0 = lp->new_prli_word0 = pdb->prli_word0;
1716 lp->prli_word3 = lp->new_prli_word3 = pdb->prli_word3;
1717 lp->handle = pdb->handle;
1718 lp->port_wwn = wwpn;
1719 lp->node_wwn = wwnn;
1720 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Port 0x%06x@0x%04x is new",
1721 chan, pdb->portid, pdb->handle);
1722 }
1723
1724 /*
1725 * Scan local loop for devices.
1726 */
1727 static int
1728 isp_scan_loop(ispsoftc_t *isp, int chan)
1729 {
1730 fcparam *fcp = FCPARAM(isp, chan);
1731 int idx, lim, r;
1732 isp_pdb_t pdb;
1733 uint16_t *handles;
1734 uint16_t handle;
1735
1736 if (fcp->isp_loopstate < LOOP_LTEST_DONE)
1737 return (-1);
1738 if (fcp->isp_loopstate >= LOOP_LSCAN_DONE)
1739 return (0);
1740
1741 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan", chan);
1742 fcp->isp_loopstate = LOOP_SCANNING_LOOP;
1743 if (TOPO_IS_FABRIC(fcp->isp_topo)) {
1744 isp_prt(isp, ISP_LOG_SANCFG,
1745 "Chan %d FC loop scan done (no loop)", chan);
1746 fcp->isp_loopstate = LOOP_LSCAN_DONE;
1747 return (0);
1748 }
1749
1750 handles = (uint16_t *)fcp->isp_scanscratch;
1751 lim = ISP_FC_SCRLEN / 2;
1752 r = isp_gethandles(isp, chan, handles, &lim, 1);
1753 if (r != 0) {
1754 isp_prt(isp, ISP_LOG_SANCFG,
1755 "Chan %d Getting list of handles failed with %x", chan, r);
1756 isp_prt(isp, ISP_LOG_SANCFG,
1757 "Chan %d FC loop scan done (bad)", chan);
1758 return (-1);
1759 }
1760
1761 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Got %d handles",
1762 chan, lim);
1763
1764 /*
1765 * Run through the list and get the port database info for each one.
1766 */
1767 isp_mark_portdb(isp, chan);
1768 for (idx = 0; idx < lim; idx++) {
1769 handle = handles[idx];
1770
1771 /*
1772 * Don't scan "special" ids.
1773 */
1774 if (handle >= NPH_RESERVED)
1775 continue;
1776
1777 /*
1778 * Get the port database entity for this index.
1779 */
1780 r = isp_getpdb(isp, chan, handle, &pdb);
1781 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
1782 abort:
1783 isp_prt(isp, ISP_LOG_SANCFG,
1784 "Chan %d FC loop scan aborted", chan);
1785 return (1);
1786 }
1787 if (r != 0) {
1788 isp_prt(isp, ISP_LOGDEBUG1,
1789 "Chan %d FC Scan Loop handle %d returned %x",
1790 chan, handle, r);
1791 continue;
1792 }
1793
1794 isp_pdb_add_update(isp, chan, &pdb);
1795 }
1796 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
1797 goto abort;
1798 fcp->isp_loopstate = LOOP_LSCAN_DONE;
1799 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan done", chan);
1800 return (0);
1801 }
1802
1803 static int
1804 isp_ct_passthru(ispsoftc_t *isp, int chan, uint32_t cmd_bcnt, uint32_t rsp_bcnt)
1805 {
1806 fcparam *fcp = FCPARAM(isp, chan);
1807 isp_ct_pt_t pt;
1808 int retval;
1809
1810 if (isp->isp_dblev & ISP_LOGDEBUG1)
1811 isp_print_bytes(isp, "CT request", cmd_bcnt, fcp->isp_scratch);
1812
1813 /*
1814 * Build a Passthrough IOCB in memory.
1815 */
1816 ISP_MEMZERO(&pt, sizeof(pt));
1817 pt.ctp_header.rqs_entry_count = 1;
1818 pt.ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
1819 pt.ctp_nphdl = fcp->isp_sns_hdl;
1820 pt.ctp_cmd_cnt = 1;
1821 pt.ctp_vpidx = ISP_GET_VPIDX(isp, chan);
1822 pt.ctp_time = 10;
1823 pt.ctp_rsp_cnt = 1;
1824 pt.ctp_rsp_bcnt = rsp_bcnt;
1825 pt.ctp_cmd_bcnt = cmd_bcnt;
1826 pt.ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma);
1827 pt.ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma);
1828 pt.ctp_dataseg[0].ds_count = cmd_bcnt;
1829 pt.ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma);
1830 pt.ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma);
1831 pt.ctp_dataseg[1].ds_count = rsp_bcnt;
1832
1833 retval = isp_exec_entry_queue(isp, &pt, &pt, 2 * pt.ctp_time);
1834 if (retval != 0) {
1835 isp_prt(isp, ISP_LOGERR, "%s: CTP of chan %d error %d",
1836 __func__, chan, retval);
1837 return (retval);
1838 }
1839
1840 if (pt.ctp_status && pt.ctp_status != RQCS_DATA_UNDERRUN) {
1841 isp_prt(isp, ISP_LOGWARN,
1842 "Chan %d CT pass-through returned 0x%x",
1843 chan, pt.ctp_status);
1844 return (-1);
1845 }
1846
1847 if (isp->isp_dblev & ISP_LOGDEBUG1)
1848 isp_print_bytes(isp, "CT response", rsp_bcnt, fcp->isp_scratch);
1849
1850 return (0);
1851 }
1852
1853 /*
1854 * Scan the fabric for devices and add them to our port database.
1855 *
1856 * Use the GID_PT command to get list of all Nx_Port IDs SNS knows.
1857 * Use GFF_ID and GFT_ID to check port type (FCP) and features (target).
1858 *
1859 * We use CT Pass-through IOCB.
1860 */
1861 #define GIDLEN ISP_FC_SCRLEN
1862 #define NGENT ((GIDLEN - 16) >> 2)
1863
1864 static int
1865 isp_gid_pt(ispsoftc_t *isp, int chan)
1866 {
1867 fcparam *fcp = FCPARAM(isp, chan);
1868 ct_hdr_t ct;
1869 uint8_t *scp = fcp->isp_scratch;
1870
1871 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GID_PT", chan);
1872 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
1873 isp_prt(isp, ISP_LOGERR, sacq);
1874 return (-1);
1875 }
1876
1877 /* Build the CT command and execute via pass-through. */
1878 ISP_MEMZERO(&ct, sizeof (ct));
1879 ct.ct_revision = CT_REVISION;
1880 ct.ct_fcs_type = CT_FC_TYPE_FC;
1881 ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS;
1882 ct.ct_cmd_resp = SNS_GID_PT;
1883 ct.ct_bcnt_resid = (GIDLEN - 16) >> 2;
1884 isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp);
1885 scp[sizeof(ct)] = 0x7f; /* Port Type = Nx_Port */
1886 scp[sizeof(ct)+1] = 0; /* Domain_ID = any */
1887 scp[sizeof(ct)+2] = 0; /* Area_ID = any */
1888 scp[sizeof(ct)+3] = 0; /* Flags = no Area_ID */
1889
1890 if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), GIDLEN)) {
1891 FC_SCRATCH_RELEASE(isp, chan);
1892 return (-1);
1893 }
1894
1895 isp_get_gid_xx_response(isp, (sns_gid_xx_rsp_t *)scp,
1896 (sns_gid_xx_rsp_t *)fcp->isp_scanscratch, NGENT);
1897 FC_SCRATCH_RELEASE(isp, chan);
1898 return (0);
1899 }
1900
1901 static int
1902 isp_gff_id(ispsoftc_t *isp, int chan, uint32_t portid)
1903 {
1904 fcparam *fcp = FCPARAM(isp, chan);
1905 ct_hdr_t ct;
1906 uint32_t *rp;
1907 uint8_t *scp = fcp->isp_scratch;
1908 sns_gff_id_rsp_t rsp;
1909 int i, res = -1;
1910
1911 if (!fcp->isp_use_gff_id) /* User may block GFF_ID use. */
1912 return (res);
1913
1914 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GFF_ID", chan);
1915 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
1916 isp_prt(isp, ISP_LOGERR, sacq);
1917 return (res);
1918 }
1919
1920 /* Build the CT command and execute via pass-through. */
1921 ISP_MEMZERO(&ct, sizeof (ct));
1922 ct.ct_revision = CT_REVISION;
1923 ct.ct_fcs_type = CT_FC_TYPE_FC;
1924 ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS;
1925 ct.ct_cmd_resp = SNS_GFF_ID;
1926 ct.ct_bcnt_resid = (SNS_GFF_ID_RESP_SIZE - sizeof(ct)) / 4;
1927 isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp);
1928 rp = (uint32_t *) &scp[sizeof(ct)];
1929 ISP_IOZPUT_32(isp, portid, rp);
1930
1931 if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t),
1932 SNS_GFF_ID_RESP_SIZE)) {
1933 FC_SCRATCH_RELEASE(isp, chan);
1934 return (res);
1935 }
1936
1937 isp_get_gff_id_response(isp, (sns_gff_id_rsp_t *)scp, &rsp);
1938 if (rsp.snscb_cthdr.ct_cmd_resp == LS_ACC) {
1939 for (i = 0; i < 32; i++) {
1940 if (rsp.snscb_fc4_features[i] != 0) {
1941 res = 0;
1942 break;
1943 }
1944 }
1945 if (((rsp.snscb_fc4_features[FC4_SCSI / 8] >>
1946 ((FC4_SCSI % 8) * 4)) & 0x01) != 0)
1947 res = 1;
1948 /* Workaround for broken Brocade firmware. */
1949 if (((ISP_SWAP32(isp, rsp.snscb_fc4_features[FC4_SCSI / 8]) >>
1950 ((FC4_SCSI % 8) * 4)) & 0x01) != 0)
1951 res = 1;
1952 }
1953 FC_SCRATCH_RELEASE(isp, chan);
1954 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GFF_ID result is %d", chan, res);
1955 return (res);
1956 }
1957
1958 static int
1959 isp_gft_id(ispsoftc_t *isp, int chan, uint32_t portid)
1960 {
1961 fcparam *fcp = FCPARAM(isp, chan);
1962 ct_hdr_t ct;
1963 uint32_t *rp;
1964 uint8_t *scp = fcp->isp_scratch;
1965 sns_gft_id_rsp_t rsp;
1966 int i, res = -1;
1967
1968 if (!fcp->isp_use_gft_id) /* User may block GFT_ID use. */
1969 return (res);
1970
1971 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GFT_ID", chan);
1972 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
1973 isp_prt(isp, ISP_LOGERR, sacq);
1974 return (res);
1975 }
1976
1977 /* Build the CT command and execute via pass-through. */
1978 ISP_MEMZERO(&ct, sizeof (ct));
1979 ct.ct_revision = CT_REVISION;
1980 ct.ct_fcs_type = CT_FC_TYPE_FC;
1981 ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS;
1982 ct.ct_cmd_resp = SNS_GFT_ID;
1983 ct.ct_bcnt_resid = (SNS_GFT_ID_RESP_SIZE - sizeof(ct)) / 4;
1984 isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp);
1985 rp = (uint32_t *) &scp[sizeof(ct)];
1986 ISP_IOZPUT_32(isp, portid, rp);
1987
1988 if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t),
1989 SNS_GFT_ID_RESP_SIZE)) {
1990 FC_SCRATCH_RELEASE(isp, chan);
1991 return (res);
1992 }
1993
1994 isp_get_gft_id_response(isp, (sns_gft_id_rsp_t *)scp, &rsp);
1995 if (rsp.snscb_cthdr.ct_cmd_resp == LS_ACC) {
1996 for (i = 0; i < 8; i++) {
1997 if (rsp.snscb_fc4_types[i] != 0) {
1998 res = 0;
1999 break;
2000 }
2001 }
2002 if (((rsp.snscb_fc4_types[FC4_SCSI / 32] >>
2003 (FC4_SCSI % 32)) & 0x01) != 0)
2004 res = 1;
2005 }
2006 FC_SCRATCH_RELEASE(isp, chan);
2007 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GFT_ID result is %d", chan, res);
2008 return (res);
2009 }
2010
2011 static int
2012 isp_scan_fabric(ispsoftc_t *isp, int chan)
2013 {
2014 fcparam *fcp = FCPARAM(isp, chan);
2015 fcportdb_t *lp;
2016 uint32_t portid;
2017 isp_pdb_t pdb;
2018 int portidx, portlim, r;
2019 sns_gid_xx_rsp_t *rs;
2020
2021 if (fcp->isp_loopstate < LOOP_LSCAN_DONE)
2022 return (-1);
2023 if (fcp->isp_loopstate >= LOOP_FSCAN_DONE)
2024 return (0);
2025
2026 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan", chan);
2027 fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
2028 if (!TOPO_IS_FABRIC(fcp->isp_topo)) {
2029 fcp->isp_loopstate = LOOP_FSCAN_DONE;
2030 isp_prt(isp, ISP_LOG_SANCFG,
2031 "Chan %d FC fabric scan done (no fabric)", chan);
2032 return (0);
2033 }
2034
2035 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
2036 abort:
2037 FC_SCRATCH_RELEASE(isp, chan);
2038 isp_prt(isp, ISP_LOG_SANCFG,
2039 "Chan %d FC fabric scan aborted", chan);
2040 return (1);
2041 }
2042
2043 /*
2044 * Make sure we still are logged into the fabric controller.
2045 */
2046 r = isp_getpdb(isp, chan, NPH_FL_ID, &pdb);
2047 if ((r & 0xffff) == MBOX_NOT_LOGGED_IN) {
2048 isp_dump_chip_portdb(isp, chan);
2049 }
2050 if (r) {
2051 fcp->isp_loopstate = LOOP_LTEST_DONE;
2052 fail:
2053 isp_prt(isp, ISP_LOG_SANCFG,
2054 "Chan %d FC fabric scan done (bad)", chan);
2055 return (-1);
2056 }
2057
2058 /* Get list of port IDs from SNS. */
2059 r = isp_gid_pt(isp, chan);
2060 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2061 goto abort;
2062 if (r > 0) {
2063 fcp->isp_loopstate = LOOP_FSCAN_DONE;
2064 return (-1);
2065 } else if (r < 0) {
2066 fcp->isp_loopstate = LOOP_LTEST_DONE; /* try again */
2067 return (-1);
2068 }
2069
2070 rs = (sns_gid_xx_rsp_t *) fcp->isp_scanscratch;
2071 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2072 goto abort;
2073 if (rs->snscb_cthdr.ct_cmd_resp != LS_ACC) {
2074 int level;
2075 /* FC-4 Type and Port Type not registered are not errors. */
2076 if (rs->snscb_cthdr.ct_reason == 9 &&
2077 (rs->snscb_cthdr.ct_explanation == 0x07 ||
2078 rs->snscb_cthdr.ct_explanation == 0x0a)) {
2079 level = ISP_LOG_SANCFG;
2080 } else {
2081 level = ISP_LOGWARN;
2082 }
2083 isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_PT"
2084 " (Reason=0x%x Expl=0x%x)", chan,
2085 rs->snscb_cthdr.ct_reason,
2086 rs->snscb_cthdr.ct_explanation);
2087 fcp->isp_loopstate = LOOP_FSCAN_DONE;
2088 return (-1);
2089 }
2090
2091 /* Check our buffer was big enough to get the full list. */
2092 for (portidx = 0; portidx < NGENT-1; portidx++) {
2093 if (rs->snscb_ports[portidx].control & 0x80)
2094 break;
2095 }
2096 if ((rs->snscb_ports[portidx].control & 0x80) == 0) {
2097 isp_prt(isp, ISP_LOGWARN,
2098 "fabric too big for scratch area: increase ISP_FC_SCRLEN");
2099 }
2100 portlim = portidx + 1;
2101 isp_prt(isp, ISP_LOG_SANCFG,
2102 "Chan %d Got %d ports back from name server", chan, portlim);
2103
2104 /* Go through the list and remove duplicate port ids. */
2105 for (portidx = 0; portidx < portlim; portidx++) {
2106 int npidx;
2107
2108 portid =
2109 ((rs->snscb_ports[portidx].portid[0]) << 16) |
2110 ((rs->snscb_ports[portidx].portid[1]) << 8) |
2111 ((rs->snscb_ports[portidx].portid[2]));
2112
2113 for (npidx = portidx + 1; npidx < portlim; npidx++) {
2114 uint32_t new_portid =
2115 ((rs->snscb_ports[npidx].portid[0]) << 16) |
2116 ((rs->snscb_ports[npidx].portid[1]) << 8) |
2117 ((rs->snscb_ports[npidx].portid[2]));
2118 if (new_portid == portid) {
2119 break;
2120 }
2121 }
2122
2123 if (npidx < portlim) {
2124 rs->snscb_ports[npidx].portid[0] = 0;
2125 rs->snscb_ports[npidx].portid[1] = 0;
2126 rs->snscb_ports[npidx].portid[2] = 0;
2127 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d removing duplicate PortID 0x%06x entry from list", chan, portid);
2128 }
2129 }
2130
2131 /*
2132 * We now have a list of Port IDs for all FC4 SCSI devices
2133 * that the Fabric Name server knows about.
2134 *
2135 * For each entry on this list go through our port database looking
2136 * for probational entries- if we find one, then an old entry is
2137 * maybe still this one. We get some information to find out.
2138 *
2139 * Otherwise, it's a new fabric device, and we log into it
2140 * (unconditionally). After searching the entire database
2141 * again to make sure that we never ever ever ever have more
2142 * than one entry that has the same PortID or the same
2143 * WWNN/WWPN duple, we enter the device into our database.
2144 */
2145 isp_mark_portdb(isp, chan);
2146 for (portidx = 0; portidx < portlim; portidx++) {
2147 portid = ((rs->snscb_ports[portidx].portid[0]) << 16) |
2148 ((rs->snscb_ports[portidx].portid[1]) << 8) |
2149 ((rs->snscb_ports[portidx].portid[2]));
2150 isp_prt(isp, ISP_LOG_SANCFG,
2151 "Chan %d Checking fabric port 0x%06x", chan, portid);
2152 if (portid == 0) {
2153 isp_prt(isp, ISP_LOG_SANCFG,
2154 "Chan %d Port at idx %d is zero",
2155 chan, portidx);
2156 continue;
2157 }
2158 if (portid == fcp->isp_portid) {
2159 isp_prt(isp, ISP_LOG_SANCFG,
2160 "Chan %d Port 0x%06x is our", chan, portid);
2161 continue;
2162 }
2163
2164 /* Now search the entire port database for the same portid. */
2165 if (isp_find_pdb_by_portid(isp, chan, portid, &lp)) {
2166 if (!lp->probational) {
2167 isp_prt(isp, ISP_LOGERR,
2168 "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)",
2169 chan, lp->portid, lp->handle,
2170 FC_PORTDB_TGT(isp, chan, lp), lp->state);
2171 isp_dump_portdb(isp, chan);
2172 goto fail;
2173 }
2174
2175 if (lp->state == FC_PORTDB_STATE_ZOMBIE)
2176 goto relogin;
2177
2178 /*
2179 * See if we're still logged into it.
2180 *
2181 * If we aren't, mark it as a dead device and
2182 * leave the new portid in the database entry
2183 * for somebody further along to decide what to
2184 * do (policy choice).
2185 *
2186 * If we are, check to see if it's the same
2187 * device still (it should be). If for some
2188 * reason it isn't, mark it as a changed device
2189 * and leave the new portid and role in the
2190 * database entry for somebody further along to
2191 * decide what to do (policy choice).
2192 */
2193 r = isp_getpdb(isp, chan, lp->handle, &pdb);
2194 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2195 goto abort;
2196 if (r != 0) {
2197 lp->state = FC_PORTDB_STATE_DEAD;
2198 isp_prt(isp, ISP_LOG_SANCFG,
2199 "Chan %d Port 0x%06x handle 0x%x is dead (%d)",
2200 chan, portid, lp->handle, r);
2201 goto relogin;
2202 }
2203
2204 isp_pdb_add_update(isp, chan, &pdb);
2205 continue;
2206 }
2207
2208 relogin:
2209 if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
2210 isp_prt(isp, ISP_LOG_SANCFG,
2211 "Chan %d Port 0x%06x is not logged in", chan, portid);
2212 continue;
2213 }
2214
2215 r = isp_gff_id(isp, chan, portid);
2216 if (r == 0) {
2217 isp_prt(isp, ISP_LOG_SANCFG,
2218 "Chan %d Port 0x%06x is not an FCP target", chan, portid);
2219 continue;
2220 }
2221 if (r < 0)
2222 r = isp_gft_id(isp, chan, portid);
2223 if (r == 0) {
2224 isp_prt(isp, ISP_LOG_SANCFG,
2225 "Chan %d Port 0x%06x is not FCP", chan, portid);
2226 continue;
2227 }
2228
2229 if (isp_login_device(isp, chan, portid, &pdb,
2230 &FCPARAM(isp, 0)->isp_lasthdl)) {
2231 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2232 goto abort;
2233 continue;
2234 }
2235
2236 isp_pdb_add_update(isp, chan, &pdb);
2237 }
2238
2239 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2240 goto abort;
2241 fcp->isp_loopstate = LOOP_FSCAN_DONE;
2242 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan done", chan);
2243 return (0);
2244 }
2245
2246 /*
2247 * Find an unused handle and try and use to login to a port.
2248 */
2249 static int
2250 isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
2251 {
2252 int i, r;
2253 uint16_t handle;
2254
2255 handle = isp_next_handle(isp, ohp);
2256 for (i = 0; i < NPH_MAX_2K; i++) {
2257 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
2258 return (-1);
2259
2260 /* Check if this handle is free. */
2261 r = isp_getpdb(isp, chan, handle, p);
2262 if (r == 0) {
2263 if (p->portid != portid) {
2264 /* This handle is busy, try next one. */
2265 handle = isp_next_handle(isp, ohp);
2266 continue;
2267 }
2268 break;
2269 }
2270 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
2271 return (-1);
2272
2273 /*
2274 * Now try and log into the device
2275 */
2276 r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
2277 if (r == 0) {
2278 break;
2279 } else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
2280 /*
2281 * If we get here, then the firmwware still thinks we're logged into this device, but with a different
2282 * handle. We need to break that association. We used to try and just substitute the handle, but then
2283 * failed to get any data via isp_getpdb (below).
2284 */
2285 if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL)) {
2286 isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16);
2287 }
2288 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
2289 return (-1);
2290 r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
2291 if (r != 0)
2292 i = NPH_MAX_2K;
2293 break;
2294 } else if ((r & 0xffff) == MBOX_LOOP_ID_USED) {
2295 /* Try the next handle. */
2296 handle = isp_next_handle(isp, ohp);
2297 } else {
2298 /* Give up. */
2299 i = NPH_MAX_2K;
2300 break;
2301 }
2302 }
2303
2304 if (i == NPH_MAX_2K) {
2305 isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid);
2306 return (-1);
2307 }
2308
2309 /*
2310 * If we successfully logged into it, get the PDB for it
2311 * so we can crosscheck that it is still what we think it
2312 * is and that we also have the role it plays
2313 */
2314 r = isp_getpdb(isp, chan, handle, p);
2315 if (r != 0) {
2316 isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
2317 return (-1);
2318 }
2319
2320 if (p->handle != handle || p->portid != portid) {
2321 isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
2322 chan, portid, handle, p->portid, p->handle);
2323 return (-1);
2324 }
2325 return (0);
2326 }
2327
2328 static int
2329 isp_register_fc4_type(ispsoftc_t *isp, int chan)
2330 {
2331 fcparam *fcp = FCPARAM(isp, chan);
2332 rft_id_t rp;
2333 ct_hdr_t *ct = &rp.rftid_hdr;
2334 uint8_t *scp = fcp->isp_scratch;
2335
2336 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2337 isp_prt(isp, ISP_LOGERR, sacq);
2338 return (-1);
2339 }
2340
2341 /* Build the CT command and execute via pass-through. */
2342 ISP_MEMZERO(&rp, sizeof(rp));
2343 ct->ct_revision = CT_REVISION;
2344 ct->ct_fcs_type = CT_FC_TYPE_FC;
2345 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2346 ct->ct_cmd_resp = SNS_RFT_ID;
2347 ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
2348 rp.rftid_portid[0] = fcp->isp_portid >> 16;
2349 rp.rftid_portid[1] = fcp->isp_portid >> 8;
2350 rp.rftid_portid[2] = fcp->isp_portid;
2351 rp.rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
2352 isp_put_rft_id(isp, &rp, (rft_id_t *)scp);
2353
2354 if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) {
2355 FC_SCRATCH_RELEASE(isp, chan);
2356 return (-1);
2357 }
2358
2359 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2360 FC_SCRATCH_RELEASE(isp, chan);
2361 if (ct->ct_cmd_resp == LS_RJT) {
2362 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "Chan %d Register FC4 Type rejected", chan);
2363 return (-1);
2364 } else if (ct->ct_cmd_resp == LS_ACC) {
2365 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Register FC4 Type accepted", chan);
2366 } else {
2367 isp_prt(isp, ISP_LOGWARN, "Chan %d Register FC4 Type: 0x%x", chan, ct->ct_cmd_resp);
2368 return (-1);
2369 }
2370 return (0);
2371 }
2372
2373 static int
2374 isp_register_fc4_features_24xx(ispsoftc_t *isp, int chan)
2375 {
2376 fcparam *fcp = FCPARAM(isp, chan);
2377 ct_hdr_t *ct;
2378 rff_id_t rp;
2379 uint8_t *scp = fcp->isp_scratch;
2380
2381 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2382 isp_prt(isp, ISP_LOGERR, sacq);
2383 return (-1);
2384 }
2385
2386 /*
2387 * Build the CT header and command in memory.
2388 */
2389 ISP_MEMZERO(&rp, sizeof(rp));
2390 ct = &rp.rffid_hdr;
2391 ct->ct_revision = CT_REVISION;
2392 ct->ct_fcs_type = CT_FC_TYPE_FC;
2393 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2394 ct->ct_cmd_resp = SNS_RFF_ID;
2395 ct->ct_bcnt_resid = (sizeof (rff_id_t) - sizeof (ct_hdr_t)) >> 2;
2396 rp.rffid_portid[0] = fcp->isp_portid >> 16;
2397 rp.rffid_portid[1] = fcp->isp_portid >> 8;
2398 rp.rffid_portid[2] = fcp->isp_portid;
2399 rp.rffid_fc4features = 0;
2400 if (fcp->role & ISP_ROLE_TARGET)
2401 rp.rffid_fc4features |= 1;
2402 if (fcp->role & ISP_ROLE_INITIATOR)
2403 rp.rffid_fc4features |= 2;
2404 rp.rffid_fc4type = FC4_SCSI;
2405 isp_put_rff_id(isp, &rp, (rff_id_t *)scp);
2406 if (isp->isp_dblev & ISP_LOGDEBUG1)
2407 isp_print_bytes(isp, "CT request", sizeof(rft_id_t), scp);
2408
2409 if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) {
2410 FC_SCRATCH_RELEASE(isp, chan);
2411 return (-1);
2412 }
2413
2414 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2415 FC_SCRATCH_RELEASE(isp, chan);
2416 if (ct->ct_cmd_resp == LS_RJT) {
2417 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
2418 "Chan %d Register FC4 Features rejected", chan);
2419 return (-1);
2420 } else if (ct->ct_cmd_resp == LS_ACC) {
2421 isp_prt(isp, ISP_LOG_SANCFG,
2422 "Chan %d Register FC4 Features accepted", chan);
2423 } else {
2424 isp_prt(isp, ISP_LOGWARN,
2425 "Chan %d Register FC4 Features: 0x%x", chan, ct->ct_cmd_resp);
2426 return (-1);
2427 }
2428 return (0);
2429 }
2430
2431 static int
2432 isp_register_port_name_24xx(ispsoftc_t *isp, int chan)
2433 {
2434 fcparam *fcp = FCPARAM(isp, chan);
2435 ct_hdr_t *ct;
2436 rspn_id_t rp;
2437 uint8_t *scp = fcp->isp_scratch;
2438 int len;
2439
2440 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2441 isp_prt(isp, ISP_LOGERR, sacq);
2442 return (-1);
2443 }
2444
2445 /*
2446 * Build the CT header and command in memory.
2447 */
2448 ISP_MEMZERO(&rp, sizeof(rp));
2449 ct = &rp.rspnid_hdr;
2450 ct->ct_revision = CT_REVISION;
2451 ct->ct_fcs_type = CT_FC_TYPE_FC;
2452 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2453 ct->ct_cmd_resp = SNS_RSPN_ID;
2454 rp.rspnid_portid[0] = fcp->isp_portid >> 16;
2455 rp.rspnid_portid[1] = fcp->isp_portid >> 8;
2456 rp.rspnid_portid[2] = fcp->isp_portid;
2457 rp.rspnid_length = 0;
2458 len = offsetof(rspn_id_t, rspnid_name);
2459 mtx_lock(&prison0.pr_mtx);
2460 rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length],
2461 "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD");
2462 mtx_unlock(&prison0.pr_mtx);
2463 rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length],
2464 ":%s", device_get_nameunit(isp->isp_dev));
2465 if (chan != 0) {
2466 rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length],
2467 "/%d", chan);
2468 }
2469 len += rp.rspnid_length;
2470 ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2;
2471 isp_put_rspn_id(isp, &rp, (rspn_id_t *)scp);
2472
2473 if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) {
2474 FC_SCRATCH_RELEASE(isp, chan);
2475 return (-1);
2476 }
2477
2478 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2479 FC_SCRATCH_RELEASE(isp, chan);
2480 if (ct->ct_cmd_resp == LS_RJT) {
2481 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
2482 "Chan %d Register Symbolic Port Name rejected", chan);
2483 return (-1);
2484 } else if (ct->ct_cmd_resp == LS_ACC) {
2485 isp_prt(isp, ISP_LOG_SANCFG,
2486 "Chan %d Register Symbolic Port Name accepted", chan);
2487 } else {
2488 isp_prt(isp, ISP_LOGWARN,
2489 "Chan %d Register Symbolic Port Name: 0x%x", chan, ct->ct_cmd_resp);
2490 return (-1);
2491 }
2492 return (0);
2493 }
2494
2495 static int
2496 isp_register_node_name_24xx(ispsoftc_t *isp, int chan)
2497 {
2498 fcparam *fcp = FCPARAM(isp, chan);
2499 ct_hdr_t *ct;
2500 rsnn_nn_t rp;
2501 uint8_t *scp = fcp->isp_scratch;
2502 int len;
2503
2504 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2505 isp_prt(isp, ISP_LOGERR, sacq);
2506 return (-1);
2507 }
2508
2509 /*
2510 * Build the CT header and command in memory.
2511 */
2512 ISP_MEMZERO(&rp, sizeof(rp));
2513 ct = &rp.rsnnnn_hdr;
2514 ct->ct_revision = CT_REVISION;
2515 ct->ct_fcs_type = CT_FC_TYPE_FC;
2516 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2517 ct->ct_cmd_resp = SNS_RSNN_NN;
2518 MAKE_NODE_NAME_FROM_WWN(rp.rsnnnn_nodename, fcp->isp_wwnn);
2519 rp.rsnnnn_length = 0;
2520 len = offsetof(rsnn_nn_t, rsnnnn_name);
2521 mtx_lock(&prison0.pr_mtx);
2522 rp.rsnnnn_length += sprintf(&scp[len + rp.rsnnnn_length],
2523 "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD");
2524 mtx_unlock(&prison0.pr_mtx);
2525 len += rp.rsnnnn_length;
2526 ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2;
2527 isp_put_rsnn_nn(isp, &rp, (rsnn_nn_t *)scp);
2528
2529 if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) {
2530 FC_SCRATCH_RELEASE(isp, chan);
2531 return (-1);
2532 }
2533
2534 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2535 FC_SCRATCH_RELEASE(isp, chan);
2536 if (ct->ct_cmd_resp == LS_RJT) {
2537 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
2538 "Chan %d Register Symbolic Node Name rejected", chan);
2539 return (-1);
2540 } else if (ct->ct_cmd_resp == LS_ACC) {
2541 isp_prt(isp, ISP_LOG_SANCFG,
2542 "Chan %d Register Symbolic Node Name accepted", chan);
2543 } else {
2544 isp_prt(isp, ISP_LOGWARN,
2545 "Chan %d Register Symbolic Node Name: 0x%x", chan, ct->ct_cmd_resp);
2546 return (-1);
2547 }
2548 return (0);
2549 }
2550
2551 static uint16_t
2552 isp_next_handle(ispsoftc_t *isp, uint16_t *ohp)
2553 {
2554 fcparam *fcp;
2555 int i, chan, wrap;
2556 uint16_t handle;
2557
2558 handle = *ohp;
2559 wrap = 0;
2560
2561 next:
2562 if (handle == NIL_HANDLE) {
2563 handle = 0;
2564 } else {
2565 handle++;
2566 if (handle > NPH_RESERVED - 1) {
2567 if (++wrap >= 2) {
2568 isp_prt(isp, ISP_LOGERR, "Out of port handles!");
2569 return (NIL_HANDLE);
2570 }
2571 handle = 0;
2572 }
2573 }
2574 for (chan = 0; chan < isp->isp_nchan; chan++) {
2575 fcp = FCPARAM(isp, chan);
2576 if (fcp->role == ISP_ROLE_NONE)
2577 continue;
2578 for (i = 0; i < MAX_FC_TARG; i++) {
2579 if (fcp->portdb[i].state != FC_PORTDB_STATE_NIL &&
2580 fcp->portdb[i].handle == handle)
2581 goto next;
2582 }
2583 }
2584 *ohp = handle;
2585 return (handle);
2586 }
2587
2588 /*
2589 * Start a command. Locking is assumed done in the caller.
2590 */
2591
2592 int
2593 isp_start(XS_T *xs)
2594 {
2595 ispsoftc_t *isp;
2596 fcparam *fcp;
2597 uint32_t cdblen;
2598 ispreqt7_t local, *reqp = &local;
2599 void *qep;
2600 fcportdb_t *lp;
2601 int target, dmaresult;
2602
2603 XS_INITERR(xs);
2604 isp = XS_ISP(xs);
2605
2606 /*
2607 * Check command CDB length, etc.. We really are limited to 16 bytes
2608 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
2609 * but probably only if we're running fairly new firmware (we'll
2610 * let the old f/w choke on an extended command queue entry).
2611 */
2612
2613 if (XS_CDBLEN(xs) > 16 || XS_CDBLEN(xs) == 0) {
2614 isp_prt(isp, ISP_LOGERR, "unsupported cdb length (%d, CDB[0]=0x%x)", XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
2615 XS_SETERR(xs, HBA_REQINVAL);
2616 return (CMD_COMPLETE);
2617 }
2618
2619 /*
2620 * Translate the target to device handle as appropriate, checking
2621 * for correct device state as well.
2622 */
2623 target = XS_TGT(xs);
2624 fcp = FCPARAM(isp, XS_CHANNEL(xs));
2625
2626 if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
2627 isp_prt(isp, ISP_LOG_WARN1,
2628 "%d.%d.%jx I am not an initiator",
2629 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
2630 XS_SETERR(xs, HBA_SELTIMEOUT);
2631 return (CMD_COMPLETE);
2632 }
2633
2634 if (isp->isp_state != ISP_RUNSTATE) {
2635 isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
2636 XS_SETERR(xs, HBA_BOTCH);
2637 return (CMD_COMPLETE);
2638 }
2639
2640 isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d", target);
2641 lp = &fcp->portdb[target];
2642 if (target < 0 || target >= MAX_FC_TARG ||
2643 lp->is_target == 0) {
2644 XS_SETERR(xs, HBA_SELTIMEOUT);
2645 return (CMD_COMPLETE);
2646 }
2647 if (fcp->isp_loopstate != LOOP_READY) {
2648 isp_prt(isp, ISP_LOGDEBUG1,
2649 "%d.%d.%jx loop is not ready",
2650 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
2651 return (CMD_RQLATER);
2652 }
2653 if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
2654 isp_prt(isp, ISP_LOGDEBUG1,
2655 "%d.%d.%jx target zombie",
2656 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
2657 return (CMD_RQLATER);
2658 }
2659 if (lp->state != FC_PORTDB_STATE_VALID) {
2660 isp_prt(isp, ISP_LOGDEBUG1,
2661 "%d.%d.%jx bad db port state 0x%x",
2662 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs), lp->state);
2663 XS_SETERR(xs, HBA_SELTIMEOUT);
2664 return (CMD_COMPLETE);
2665 }
2666
2667 start_again:
2668
2669 qep = isp_getrqentry(isp);
2670 if (qep == NULL) {
2671 isp_prt(isp, ISP_LOG_WARN1, "Request Queue Overflow");
2672 XS_SETERR(xs, HBA_BOTCH);
2673 return (CMD_EAGAIN);
2674 }
2675 XS_SETERR(xs, HBA_NOERROR);
2676
2677 /*
2678 * Now see if we need to synchronize the ISP with respect to anything.
2679 * We do dual duty here (cough) for synchronizing for buses other
2680 * than which we got here to send a command to.
2681 */
2682 ISP_MEMZERO(reqp, QENTRY_LEN);
2683 if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) {
2684 isp_marker_24xx_t *m = (isp_marker_24xx_t *) reqp;
2685 m->mrk_header.rqs_entry_count = 1;
2686 m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
2687 m->mrk_modifier = SYNC_ALL;
2688 m->mrk_vphdl = XS_CHANNEL(xs);
2689 isp_put_marker_24xx(isp, m, qep);
2690 ISP_SYNC_REQUEST(isp);
2691 ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0);
2692 goto start_again;
2693 }
2694
2695 /*
2696 * NB: we do not support long CDBs (yet)
2697 */
2698 cdblen = XS_CDBLEN(xs);
2699 if (cdblen > sizeof (reqp->req_cdb)) {
2700 isp_prt(isp, ISP_LOGERR, "Command Length %u too long for this chip", cdblen);
2701 XS_SETERR(xs, HBA_REQINVAL);
2702 return (CMD_COMPLETE);
2703 }
2704
2705 reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
2706 reqp->req_header.rqs_entry_count = 1;
2707 reqp->req_nphdl = lp->handle;
2708 reqp->req_time = XS_TIME(xs);
2709 be64enc(reqp->req_lun, CAM_EXTLUN_BYTE_SWIZZLE(XS_LUN(xs)));
2710 if (XS_XFRIN(xs))
2711 reqp->req_alen_datadir = FCP_CMND_DATA_READ;
2712 else if (XS_XFROUT(xs))
2713 reqp->req_alen_datadir = FCP_CMND_DATA_WRITE;
2714 if (XS_TAG_P(xs))
2715 reqp->req_task_attribute = XS_TAG_TYPE(xs);
2716 else
2717 reqp->req_task_attribute = FCP_CMND_TASK_ATTR_SIMPLE;
2718 reqp->req_task_attribute |= (XS_PRIORITY(xs) << FCP_CMND_PRIO_SHIFT) &
2719 FCP_CMND_PRIO_MASK;
2720 if (FCPARAM(isp, XS_CHANNEL(xs))->fctape_enabled && (lp->prli_word3 & PRLI_WD3_RETRY)) {
2721 if (FCP_NEXT_CRN(isp, &reqp->req_crn, xs)) {
2722 isp_prt(isp, ISP_LOG_WARN1,
2723 "%d.%d.%jx cannot generate next CRN",
2724 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
2725 XS_SETERR(xs, HBA_BOTCH);
2726 return (CMD_EAGAIN);
2727 }
2728 }
2729 ISP_MEMCPY(reqp->req_cdb, XS_CDBP(xs), cdblen);
2730 reqp->req_dl = XS_XFRLEN(xs);
2731 reqp->req_tidlo = lp->portid;
2732 reqp->req_tidhi = lp->portid >> 16;
2733 reqp->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs));
2734
2735 /* Whew. Thankfully the same for type 7 requests */
2736 reqp->req_handle = isp_allocate_handle(isp, xs, ISP_HANDLE_INITIATOR);
2737 if (reqp->req_handle == 0) {
2738 isp_prt(isp, ISP_LOG_WARN1, "out of xflist pointers");
2739 XS_SETERR(xs, HBA_BOTCH);
2740 return (CMD_EAGAIN);
2741 }
2742
2743 /*
2744 * Set up DMA and/or do any platform dependent swizzling of the request entry
2745 * so that the Qlogic F/W understands what is being asked of it.
2746 *
2747 * The callee is responsible for adding all requests at this point.
2748 */
2749 dmaresult = ISP_DMASETUP(isp, xs, reqp);
2750 if (dmaresult != 0) {
2751 isp_destroy_handle(isp, reqp->req_handle);
2752 /*
2753 * dmasetup sets actual error in packet, and
2754 * return what we were given to return.
2755 */
2756 return (dmaresult);
2757 }
2758 isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "START cmd cdb[0]=0x%x datalen %ld", XS_CDBP(xs)[0], (long) XS_XFRLEN(xs));
2759 return (0);
2760 }
2761
2762 /*
2763 * isp control
2764 * Locks (ints blocked) assumed held.
2765 */
2766
2767 int
2768 isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
2769 {
2770 fcparam *fcp;
2771 fcportdb_t *lp;
2772 XS_T *xs;
2773 mbreg_t *mbr;
2774 int chan, tgt;
2775 uint32_t handle;
2776 va_list ap;
2777 uint8_t local[QENTRY_LEN];
2778
2779 switch (ctl) {
2780 case ISPCTL_RESET_BUS:
2781 /*
2782 * Issue a bus reset.
2783 */
2784 isp_prt(isp, ISP_LOGERR, "BUS RESET NOT IMPLEMENTED");
2785 break;
2786
2787 case ISPCTL_RESET_DEV:
2788 {
2789 isp24xx_tmf_t *tmf;
2790 isp24xx_statusreq_t *sp;
2791
2792 va_start(ap, ctl);
2793 chan = va_arg(ap, int);
2794 tgt = va_arg(ap, int);
2795 va_end(ap);
2796 fcp = FCPARAM(isp, chan);
2797
2798 if (tgt < 0 || tgt >= MAX_FC_TARG) {
2799 isp_prt(isp, ISP_LOGWARN, "Chan %d trying to reset bad target %d", chan, tgt);
2800 break;
2801 }
2802 lp = &fcp->portdb[tgt];
2803 if (lp->is_target == 0 || lp->state != FC_PORTDB_STATE_VALID) {
2804 isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
2805 break;
2806 }
2807
2808 tmf = (isp24xx_tmf_t *) local;
2809 ISP_MEMZERO(tmf, QENTRY_LEN);
2810 tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
2811 tmf->tmf_header.rqs_entry_count = 1;
2812 tmf->tmf_nphdl = lp->handle;
2813 tmf->tmf_delay = 2;
2814 tmf->tmf_timeout = 4;
2815 tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
2816 tmf->tmf_tidlo = lp->portid;
2817 tmf->tmf_tidhi = lp->portid >> 16;
2818 tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
2819 fcp->sendmarker = 1;
2820 isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
2821
2822 sp = (isp24xx_statusreq_t *) local;
2823 if (isp_exec_entry_mbox(isp, tmf, sp, 2 * tmf->tmf_timeout))
2824 break;
2825
2826 if (sp->req_completion_status == 0)
2827 return (0);
2828 isp_prt(isp, ISP_LOGWARN, "Chan %d reset of target %d returned 0x%x", chan, tgt, sp->req_completion_status);
2829 break;
2830 }
2831 case ISPCTL_ABORT_CMD:
2832 {
2833 isp24xx_abrt_t *ab = (isp24xx_abrt_t *)&local;
2834
2835 va_start(ap, ctl);
2836 xs = va_arg(ap, XS_T *);
2837 va_end(ap);
2838
2839 tgt = XS_TGT(xs);
2840 chan = XS_CHANNEL(xs);
2841
2842 handle = isp_find_handle(isp, xs);
2843 if (handle == 0) {
2844 isp_prt(isp, ISP_LOGWARN, "cannot find handle for command to abort");
2845 break;
2846 }
2847
2848 fcp = FCPARAM(isp, chan);
2849 if (tgt < 0 || tgt >= MAX_FC_TARG) {
2850 isp_prt(isp, ISP_LOGWARN, "Chan %d trying to abort bad target %d", chan, tgt);
2851 break;
2852 }
2853 lp = &fcp->portdb[tgt];
2854 if (lp->is_target == 0 || lp->state != FC_PORTDB_STATE_VALID) {
2855 isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
2856 break;
2857 }
2858 isp_prt(isp, ISP_LOGALL, "Chan %d Abort Cmd for N-Port 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
2859 ISP_MEMZERO(ab, QENTRY_LEN);
2860 ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
2861 ab->abrt_header.rqs_entry_count = 1;
2862 ab->abrt_handle = lp->handle;
2863 ab->abrt_cmd_handle = handle;
2864 ab->abrt_tidlo = lp->portid;
2865 ab->abrt_tidhi = lp->portid >> 16;
2866 ab->abrt_vpidx = ISP_GET_VPIDX(isp, chan);
2867
2868 if (isp_exec_entry_mbox(isp, ab, ab, 5))
2869 break;
2870
2871 if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY)
2872 return (0);
2873 isp_prt(isp, ISP_LOGWARN, "Chan %d handle %d abort returned 0x%x", chan, tgt, ab->abrt_nphdl);
2874 }
2875 case ISPCTL_FCLINK_TEST:
2876 {
2877 int usdelay;
2878
2879 va_start(ap, ctl);
2880 chan = va_arg(ap, int);
2881 usdelay = va_arg(ap, int);
2882 va_end(ap);
2883 if (usdelay == 0)
2884 usdelay = 250000;
2885 return (isp_fclink_test(isp, chan, usdelay));
2886 }
2887 case ISPCTL_SCAN_FABRIC:
2888
2889 va_start(ap, ctl);
2890 chan = va_arg(ap, int);
2891 va_end(ap);
2892 return (isp_scan_fabric(isp, chan));
2893
2894 case ISPCTL_SCAN_LOOP:
2895
2896 va_start(ap, ctl);
2897 chan = va_arg(ap, int);
2898 va_end(ap);
2899 return (isp_scan_loop(isp, chan));
2900
2901 case ISPCTL_PDB_SYNC:
2902
2903 va_start(ap, ctl);
2904 chan = va_arg(ap, int);
2905 va_end(ap);
2906 return (isp_pdb_sync(isp, chan));
2907
2908 case ISPCTL_SEND_LIP:
2909 break;
2910
2911 case ISPCTL_GET_PDB:
2912 {
2913 isp_pdb_t *pdb;
2914 va_start(ap, ctl);
2915 chan = va_arg(ap, int);
2916 tgt = va_arg(ap, int);
2917 pdb = va_arg(ap, isp_pdb_t *);
2918 va_end(ap);
2919 return (isp_getpdb(isp, chan, tgt, pdb));
2920 }
2921 case ISPCTL_GET_NAMES:
2922 {
2923 uint64_t *wwnn, *wwnp;
2924 va_start(ap, ctl);
2925 chan = va_arg(ap, int);
2926 tgt = va_arg(ap, int);
2927 wwnn = va_arg(ap, uint64_t *);
2928 wwnp = va_arg(ap, uint64_t *);
2929 va_end(ap);
2930 if (wwnn == NULL && wwnp == NULL) {
2931 break;
2932 }
2933 if (wwnn) {
2934 *wwnn = isp_get_wwn(isp, chan, tgt, 1);
2935 if (*wwnn == INI_NONE) {
2936 break;
2937 }
2938 }
2939 if (wwnp) {
2940 *wwnp = isp_get_wwn(isp, chan, tgt, 0);
2941 if (*wwnp == INI_NONE) {
2942 break;
2943 }
2944 }
2945 return (0);
2946 }
2947 case ISPCTL_RUN_MBOXCMD:
2948 {
2949 va_start(ap, ctl);
2950 mbr = va_arg(ap, mbreg_t *);
2951 va_end(ap);
2952 isp_mboxcmd(isp, mbr);
2953 return (0);
2954 }
2955 case ISPCTL_PLOGX:
2956 {
2957 isp_plcmd_t *p;
2958 int r;
2959
2960 va_start(ap, ctl);
2961 p = va_arg(ap, isp_plcmd_t *);
2962 va_end(ap);
2963
2964 if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
2965 return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags));
2966 }
2967 do {
2968 isp_next_handle(isp, &p->handle);
2969 r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags);
2970 if ((r & 0xffff) == MBOX_PORT_ID_USED) {
2971 p->handle = r >> 16;
2972 r = 0;
2973 break;
2974 }
2975 } while ((r & 0xffff) == MBOX_LOOP_ID_USED);
2976 return (r);
2977 }
2978 case ISPCTL_CHANGE_ROLE:
2979 {
2980 int role;
2981
2982 va_start(ap, ctl);
2983 chan = va_arg(ap, int);
2984 role = va_arg(ap, int);
2985 va_end(ap);
2986 return (isp_fc_change_role(isp, chan, role));
2987 }
2988 default:
2989 isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
2990 break;
2991
2992 }
2993 return (-1);
2994 }
2995
2996 /*
2997 * Interrupt Service Routine(s).
2998 *
2999 * External (OS) framework has done the appropriate locking,
3000 * and the locking will be held throughout this function.
3001 */
3002
3003 #ifdef ISP_TARGET_MODE
3004 void
3005 isp_intr_atioq(ispsoftc_t *isp)
3006 {
3007 void *addr;
3008 uint32_t iptr, optr, oop;
3009
3010 iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
3011 optr = isp->isp_atioodx;
3012 while (optr != iptr) {
3013 oop = optr;
3014 MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1);
3015 addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
3016 switch (((isphdr_t *)addr)->rqs_entry_type) {
3017 case RQSTYPE_NOTIFY:
3018 case RQSTYPE_ATIO:
3019 case RQSTYPE_NOTIFY_ACK: /* Can be set to ATIO queue.*/
3020 case RQSTYPE_ABTS_RCVD: /* Can be set to ATIO queue.*/
3021 (void) isp_target_notify(isp, addr, &oop,
3022 ATIO_QUEUE_LEN(isp));
3023 break;
3024 case RQSTYPE_RPT_ID_ACQ: /* Can be set to ATIO queue.*/
3025 default:
3026 isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
3027 break;
3028 }
3029 optr = ISP_NXT_QENTRY(oop, ATIO_QUEUE_LEN(isp));
3030 }
3031 if (isp->isp_atioodx != optr) {
3032 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
3033 isp->isp_atioodx = optr;
3034 }
3035 }
3036 #endif
3037
3038 void
3039 isp_intr_mbox(ispsoftc_t *isp, uint16_t mbox0)
3040 {
3041 int i, obits;
3042
3043 if (!isp->isp_mboxbsy) {
3044 isp_prt(isp, ISP_LOGWARN, "mailbox 0x%x with no waiters", mbox0);
3045 return;
3046 }
3047 obits = isp->isp_obits;
3048 isp->isp_mboxtmp[0] = mbox0;
3049 for (i = 1; i < ISP_NMBOX(isp); i++) {
3050 if ((obits & (1 << i)) == 0)
3051 continue;
3052 isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
3053 }
3054 isp->isp_mboxbsy = 0;
3055 }
3056
3057 void
3058 isp_intr_respq(ispsoftc_t *isp)
3059 {
3060 XS_T *xs, *cont_xs;
3061 uint8_t qe[QENTRY_LEN];
3062 isp24xx_statusreq_t *sp = (isp24xx_statusreq_t *)qe;
3063 ispstatus_cont_t *scp = (ispstatus_cont_t *)qe;
3064 isphdr_t *hp;
3065 uint8_t *resp, *snsp, etype;
3066 uint16_t scsi_status;
3067 uint32_t iptr, cont = 0, cptr, optr, rlen, slen, totslen;
3068 #ifdef ISP_TARGET_MODE
3069 uint32_t sptr;
3070 #endif
3071
3072 /*
3073 * We can't be getting this now.
3074 */
3075 if (isp->isp_state != ISP_RUNSTATE) {
3076 isp_prt(isp, ISP_LOGINFO, "respq interrupt when not ready");
3077 return;
3078 }
3079
3080 iptr = ISP_READ(isp, BIU2400_RSPINP);
3081 optr = isp->isp_resodx;
3082 while (optr != iptr) {
3083 cptr = optr;
3084 #ifdef ISP_TARGET_MODE
3085 sptr = optr;
3086 #endif
3087 hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, cptr);
3088 optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
3089
3090 /*
3091 * Synchronize our view of this response queue entry.
3092 */
3093 MEMORYBARRIER(isp, SYNC_RESULT, cptr, QENTRY_LEN, -1);
3094 if (isp->isp_dblev & ISP_LOGDEBUG1)
3095 isp_print_qentry(isp, "Response Queue Entry", cptr, hp);
3096 isp_get_hdr(isp, hp, &sp->req_header);
3097
3098 /*
3099 * Log IOCBs rejected by the firmware. We can't really do
3100 * much more about them, since it just should not happen.
3101 */
3102 if (sp->req_header.rqs_flags & RQSFLAG_BADTYPE) {
3103 isp_print_qentry(isp, "invalid entry type", cptr, hp);
3104 continue;
3105 }
3106 if (sp->req_header.rqs_flags & RQSFLAG_BADPARAM) {
3107 isp_print_qentry(isp, "invalid entry parameter", cptr, hp);
3108 continue;
3109 }
3110 if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
3111 isp_print_qentry(isp, "invalid entry count", cptr, hp);
3112 continue;
3113 }
3114 if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
3115 isp_print_qentry(isp, "invalid entry order", cptr, hp);
3116 continue;
3117 }
3118
3119 etype = sp->req_header.rqs_entry_type;
3120
3121 /* We expected Status Continuation, but got different IOCB. */
3122 if (cont > 0 && etype != RQSTYPE_STATUS_CONT) {
3123 cont = 0;
3124 isp_done(cont_xs);
3125 }
3126
3127 if (isp_handle_control(isp, hp)) {
3128 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3129 continue;
3130 }
3131
3132 switch (etype) {
3133 case RQSTYPE_RESPONSE:
3134 isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp);
3135 break;
3136 case RQSTYPE_MARKER:
3137 isp_prt(isp, ISP_LOG_WARN1, "Marker Response");
3138 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3139 continue;
3140 case RQSTYPE_STATUS_CONT:
3141 isp_get_cont_response(isp, (ispstatus_cont_t *)hp, scp);
3142 if (cont > 0) {
3143 slen = min(cont, sizeof(scp->req_sense_data));
3144 XS_SENSE_APPEND(cont_xs, scp->req_sense_data, slen);
3145 cont -= slen;
3146 if (cont == 0) {
3147 isp_done(cont_xs);
3148 } else {
3149 isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN,
3150 "Expecting Status Continuations for %u bytes",
3151 cont);
3152 }
3153 } else {
3154 isp_prt(isp, ISP_LOG_WARN1, "Ignored Continuation Response");
3155 }
3156 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3157 continue;
3158 #ifdef ISP_TARGET_MODE
3159 case RQSTYPE_NOTIFY_ACK: /* Can be set to ATIO queue. */
3160 case RQSTYPE_CTIO7:
3161 case RQSTYPE_ABTS_RCVD: /* Can be set to ATIO queue. */
3162 case RQSTYPE_ABTS_RSP:
3163 isp_target_notify(isp, hp, &cptr, RESULT_QUEUE_LEN(isp));
3164 /* More then one IOCB could be consumed. */
3165 while (sptr != cptr) {
3166 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3167 sptr = ISP_NXT_QENTRY(sptr, RESULT_QUEUE_LEN(isp));
3168 hp = (isphdr_t *)ISP_QUEUE_ENTRY(isp->isp_result, sptr);
3169 }
3170 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3171 optr = ISP_NXT_QENTRY(cptr, RESULT_QUEUE_LEN(isp));
3172 continue;
3173 #endif
3174 case RQSTYPE_RPT_ID_ACQ: /* Can be set to ATIO queue.*/
3175 isp_handle_rpt_id_acq(isp, hp);
3176 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3177 continue;
3178 default:
3179 /* We don't know what was this -- log and skip. */
3180 isp_prt(isp, ISP_LOGERR, notresp, etype, cptr, optr);
3181 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3182 continue;
3183 }
3184
3185 xs = isp_find_xs(isp, sp->req_handle);
3186 if (xs == NULL) {
3187 /*
3188 * Only whine if this isn't the expected fallout of
3189 * aborting the command or resetting the target.
3190 */
3191 if (sp->req_completion_status != RQCS_ABORTED &&
3192 sp->req_completion_status != RQCS_RESET_OCCURRED)
3193 isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)",
3194 sp->req_handle, sp->req_completion_status);
3195 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3196 continue;
3197 }
3198
3199 resp = snsp = sp->req_rsp_sense;
3200 rlen = slen = totslen = 0;
3201 scsi_status = sp->req_scsi_status;
3202 if (scsi_status & RQCS_RV) {
3203 rlen = sp->req_response_len;
3204 snsp += rlen;
3205 }
3206 if (scsi_status & RQCS_SV) {
3207 totslen = sp->req_sense_len;
3208 slen = MIN(totslen, sizeof(sp->req_rsp_sense) - rlen);
3209 }
3210 *XS_STSP(xs) = scsi_status & 0xff;
3211 if (scsi_status & RQCS_RESID)
3212 XS_SET_RESID(xs, sp->req_fcp_residual);
3213 else
3214 XS_SET_RESID(xs, 0);
3215
3216 if (rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
3217 const char *ptr;
3218 char lb[64];
3219 const char *rnames[10] = {
3220 "Task Management function complete",
3221 "FCP_DATA length different than FCP_BURST_LEN",
3222 "FCP_CMND fields invalid",
3223 "FCP_DATA parameter mismatch with FCP_DATA_RO",
3224 "Task Management function rejected",
3225 "Task Management function failed",
3226 NULL,
3227 NULL,
3228 "Task Management function succeeded",
3229 "Task Management function incorrect logical unit number",
3230 };
3231 uint8_t code = resp[FCP_RSPNS_CODE_OFFSET];
3232 if (code >= nitems(rnames) || rnames[code] == NULL) {
3233 ISP_SNPRINTF(lb, sizeof(lb),
3234 "Unknown FCP Response Code 0x%x", code);
3235 ptr = lb;
3236 } else {
3237 ptr = rnames[code];
3238 }
3239 isp_xs_prt(isp, xs, ISP_LOGWARN,
3240 "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x",
3241 rlen, ptr, XS_CDBP(xs)[0] & 0xff);
3242 if (code != FCP_RSPNS_TMF_DONE &&
3243 code != FCP_RSPNS_TMF_SUCCEEDED)
3244 XS_SETERR(xs, HBA_BOTCH);
3245 }
3246 isp_parse_status_24xx(isp, sp, xs);
3247 if (slen > 0) {
3248 XS_SAVE_SENSE(xs, snsp, slen);
3249 if (totslen > slen) {
3250 cont = totslen - slen;
3251 cont_xs = xs;
3252 isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN,
3253 "Expecting Status Continuations for %u bytes",
3254 cont);
3255 }
3256 }
3257
3258 ISP_DMAFREE(isp, xs);
3259 isp_destroy_handle(isp, sp->req_handle);
3260 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3261
3262 /* Complete command if we expect no Status Continuations. */
3263 if (cont == 0)
3264 isp_done(xs);
3265 }
3266
3267 /* We haven't received all Status Continuations, but that is it. */
3268 if (cont > 0)
3269 isp_done(cont_xs);
3270
3271 /* If we processed any IOCBs, let ISP know about it. */
3272 if (optr != isp->isp_resodx) {
3273 ISP_WRITE(isp, BIU2400_RSPOUTP, optr);
3274 isp->isp_resodx = optr;
3275 }
3276 }
3277
3278
3279 void
3280 isp_intr_async(ispsoftc_t *isp, uint16_t mbox)
3281 {
3282 fcparam *fcp;
3283 uint16_t chan;
3284
3285 isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
3286
3287 switch (mbox) {
3288 case ASYNC_SYSTEM_ERROR:
3289 isp->isp_state = ISP_CRASHED;
3290 for (chan = 0; chan < isp->isp_nchan; chan++) {
3291 FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
3292 isp_change_fw_state(isp, chan, FW_CONFIG_WAIT);
3293 }
3294 /*
3295 * Were we waiting for a mailbox command to complete?
3296 * If so, it's dead, so wake up the waiter.
3297 */
3298 if (isp->isp_mboxbsy) {
3299 isp->isp_obits = 1;
3300 isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
3301 isp->isp_mboxbsy = 0;
3302 }
3303 /*
3304 * It's up to the handler for isp_async to reinit stuff and
3305 * restart the firmware
3306 */
3307 isp_async(isp, ISPASYNC_FW_CRASH);
3308 break;
3309
3310 case ASYNC_RQS_XFER_ERR:
3311 isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
3312 break;
3313
3314 case ASYNC_RSP_XFER_ERR:
3315 isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
3316 break;
3317
3318 case ASYNC_ATIO_XFER_ERR:
3319 isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
3320 break;
3321
3322 case ASYNC_LIP_OCCURRED:
3323 case ASYNC_LIP_NOS_OLS_RECV:
3324 case ASYNC_LIP_ERROR:
3325 case ASYNC_PTPMODE:
3326 /*
3327 * These are broadcast events that have to be sent across
3328 * all active channels.
3329 */
3330 for (chan = 0; chan < isp->isp_nchan; chan++) {
3331 fcp = FCPARAM(isp, chan);
3332 int topo = fcp->isp_topo;
3333
3334 if (fcp->role == ISP_ROLE_NONE)
3335 continue;
3336 if (fcp->isp_loopstate > LOOP_HAVE_LINK)
3337 fcp->isp_loopstate = LOOP_HAVE_LINK;
3338 ISP_SET_SENDMARKER(isp, chan, 1);
3339 isp_async(isp, ISPASYNC_LIP, chan);
3340 #ifdef ISP_TARGET_MODE
3341 isp_target_async(isp, chan, mbox);
3342 #endif
3343 /*
3344 * We've had problems with data corruption occurring on
3345 * commands that complete (with no apparent error) after
3346 * we receive a LIP. This has been observed mostly on
3347 * Local Loop topologies. To be safe, let's just mark
3348 * all active initiator commands as dead.
3349 */
3350 if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
3351 int i, j;
3352 for (i = j = 0; i < ISP_HANDLE_NUM(isp); i++) {
3353 XS_T *xs;
3354 isp_hdl_t *hdp;
3355
3356 hdp = &isp->isp_xflist[i];
3357 if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) {
3358 continue;
3359 }
3360 xs = hdp->cmd;
3361 if (XS_CHANNEL(xs) != chan) {
3362 continue;
3363 }
3364 j++;
3365 isp_prt(isp, ISP_LOG_WARN1,
3366 "%d.%d.%jx bus reset set at %s:%u",
3367 XS_CHANNEL(xs), XS_TGT(xs),
3368 (uintmax_t)XS_LUN(xs),
3369 __func__, __LINE__);
3370 XS_SETERR(xs, HBA_BUSRESET);
3371 }
3372 if (j) {
3373 isp_prt(isp, ISP_LOGERR, lipd, chan, j);
3374 }
3375 }
3376 }
3377 break;
3378
3379 case ASYNC_LOOP_UP:
3380 /*
3381 * This is a broadcast event that has to be sent across
3382 * all active channels.
3383 */
3384 for (chan = 0; chan < isp->isp_nchan; chan++) {
3385 fcp = FCPARAM(isp, chan);
3386 if (fcp->role == ISP_ROLE_NONE)
3387 continue;
3388 fcp->isp_linkstate = 1;
3389 if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3390 fcp->isp_loopstate = LOOP_HAVE_LINK;
3391 ISP_SET_SENDMARKER(isp, chan, 1);
3392 isp_async(isp, ISPASYNC_LOOP_UP, chan);
3393 #ifdef ISP_TARGET_MODE
3394 isp_target_async(isp, chan, mbox);
3395 #endif
3396 }
3397 break;
3398
3399 case ASYNC_LOOP_DOWN:
3400 /*
3401 * This is a broadcast event that has to be sent across
3402 * all active channels.
3403 */
3404 for (chan = 0; chan < isp->isp_nchan; chan++) {
3405 fcp = FCPARAM(isp, chan);
3406 if (fcp->role == ISP_ROLE_NONE)
3407 continue;
3408 ISP_SET_SENDMARKER(isp, chan, 1);
3409 fcp->isp_linkstate = 0;
3410 fcp->isp_loopstate = LOOP_NIL;
3411 isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
3412 #ifdef ISP_TARGET_MODE
3413 isp_target_async(isp, chan, mbox);
3414 #endif
3415 }
3416 break;
3417
3418 case ASYNC_LOOP_RESET:
3419 /*
3420 * This is a broadcast event that has to be sent across
3421 * all active channels.
3422 */
3423 for (chan = 0; chan < isp->isp_nchan; chan++) {
3424 fcp = FCPARAM(isp, chan);
3425 if (fcp->role == ISP_ROLE_NONE)
3426 continue;
3427 ISP_SET_SENDMARKER(isp, chan, 1);
3428 if (fcp->isp_loopstate > LOOP_HAVE_LINK)
3429 fcp->isp_loopstate = LOOP_HAVE_LINK;
3430 isp_async(isp, ISPASYNC_LOOP_RESET, chan);
3431 #ifdef ISP_TARGET_MODE
3432 isp_target_async(isp, chan, mbox);
3433 #endif
3434 }
3435 break;
3436
3437 case ASYNC_PDB_CHANGED:
3438 {
3439 int echan, nphdl, nlstate, reason;
3440
3441 nphdl = ISP_READ(isp, OUTMAILBOX1);
3442 nlstate = ISP_READ(isp, OUTMAILBOX2);
3443 reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
3444 if (ISP_CAP_MULTI_ID(isp)) {
3445 chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;
3446 if (chan == 0xff || nphdl == NIL_HANDLE) {
3447 chan = 0;
3448 echan = isp->isp_nchan - 1;
3449 } else if (chan >= isp->isp_nchan) {
3450 break;
3451 } else {
3452 echan = chan;
3453 }
3454 } else {
3455 chan = echan = 0;
3456 }
3457 for (; chan <= echan; chan++) {
3458 fcp = FCPARAM(isp, chan);
3459 if (fcp->role == ISP_ROLE_NONE)
3460 continue;
3461 if (fcp->isp_loopstate > LOOP_LTEST_DONE) {
3462 if (nphdl != NIL_HANDLE &&
3463 nphdl == fcp->isp_login_hdl &&
3464 reason == PDB24XX_AE_OPN_2)
3465 continue;
3466 fcp->isp_loopstate = LOOP_LTEST_DONE;
3467 } else if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3468 fcp->isp_loopstate = LOOP_HAVE_LINK;
3469 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
3470 ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
3471 }
3472 break;
3473 }
3474 case ASYNC_CHANGE_NOTIFY:
3475 {
3476 int portid;
3477
3478 portid = ((ISP_READ(isp, OUTMAILBOX1) & 0xff) << 16) |
3479 ISP_READ(isp, OUTMAILBOX2);
3480 if (ISP_CAP_MULTI_ID(isp)) {
3481 chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;
3482 if (chan >= isp->isp_nchan)
3483 break;
3484 } else {
3485 chan = 0;
3486 }
3487 fcp = FCPARAM(isp, chan);
3488 if (fcp->role == ISP_ROLE_NONE)
3489 break;
3490 if (fcp->isp_loopstate > LOOP_LTEST_DONE)
3491 fcp->isp_loopstate = LOOP_LTEST_DONE;
3492 else if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3493 fcp->isp_loopstate = LOOP_HAVE_LINK;
3494 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
3495 ISPASYNC_CHANGE_SNS, portid);
3496 break;
3497 }
3498 case ASYNC_ERR_LOGGING_DISABLED:
3499 isp_prt(isp, ISP_LOGWARN, "Error logging disabled (reason 0x%x)",
3500 ISP_READ(isp, OUTMAILBOX1));
3501 break;
3502 case ASYNC_P2P_INIT_ERR:
3503 isp_prt(isp, ISP_LOGWARN, "P2P init error (reason 0x%x)",
3504 ISP_READ(isp, OUTMAILBOX1));
3505 break;
3506 case ASYNC_RCV_ERR:
3507 isp_prt(isp, ISP_LOGWARN, "Receive Error");
3508 break;
3509 case ASYNC_RJT_SENT: /* same as ASYNC_QFULL_SENT */
3510 isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
3511 break;
3512 case ASYNC_FW_RESTART_COMPLETE:
3513 isp_prt(isp, ISP_LOGDEBUG0, "FW restart complete");
3514 break;
3515 case ASYNC_TEMPERATURE_ALERT:
3516 isp_prt(isp, ISP_LOGERR, "Temperature alert (subcode 0x%x)",
3517 ISP_READ(isp, OUTMAILBOX1));
3518 break;
3519 case ASYNC_INTER_DRIVER_COMP:
3520 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication complete");
3521 break;
3522 case ASYNC_INTER_DRIVER_NOTIFY:
3523 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication notification");
3524 break;
3525 case ASYNC_INTER_DRIVER_TIME_EXT:
3526 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication time extended");
3527 break;
3528 case ASYNC_TRANSCEIVER_INSERTION:
3529 isp_prt(isp, ISP_LOGDEBUG0, "Transceiver insertion (0x%x)",
3530 ISP_READ(isp, OUTMAILBOX1));
3531 break;
3532 case ASYNC_TRANSCEIVER_REMOVAL:
3533 isp_prt(isp, ISP_LOGDEBUG0, "Transceiver removal");
3534 break;
3535 case ASYNC_NIC_FW_STATE_CHANGE:
3536 isp_prt(isp, ISP_LOGDEBUG0, "NIC Firmware State Change");
3537 break;
3538 case ASYNC_AUTOLOAD_FW_COMPLETE:
3539 isp_prt(isp, ISP_LOGDEBUG0, "Autoload FW init complete");
3540 break;
3541 case ASYNC_AUTOLOAD_FW_FAILURE:
3542 isp_prt(isp, ISP_LOGERR, "Autoload FW init failure");
3543 break;
3544 default:
3545 isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
3546 break;
3547 }
3548 }
3549
3550 /*
3551 * Handle completions with control handles by waking up waiting threads.
3552 */
3553 static int
3554 isp_handle_control(ispsoftc_t *isp, isphdr_t *hp)
3555 {
3556 uint32_t hdl;
3557 void *ptr;
3558
3559 switch (hp->rqs_entry_type) {
3560 case RQSTYPE_RESPONSE:
3561 case RQSTYPE_MARKER:
3562 case RQSTYPE_NOTIFY_ACK:
3563 case RQSTYPE_CTIO7:
3564 case RQSTYPE_TSK_MGMT:
3565 case RQSTYPE_CT_PASSTHRU:
3566 case RQSTYPE_VP_MODIFY:
3567 case RQSTYPE_VP_CTRL:
3568 case RQSTYPE_ABORT_IO:
3569 case RQSTYPE_MBOX:
3570 case RQSTYPE_LOGIN:
3571 case RQSTYPE_ELS_PASSTHRU:
3572 ISP_IOXGET_32(isp, (uint32_t *)(hp + 1), hdl);
3573 if (ISP_H2HT(hdl) != ISP_HANDLE_CTRL)
3574 break;
3575 ptr = isp_find_xs(isp, hdl);
3576 if (ptr != NULL) {
3577 isp_destroy_handle(isp, hdl);
3578 memcpy(ptr, hp, QENTRY_LEN);
3579 wakeup(ptr);
3580 }
3581 return (1);
3582 }
3583 return (0);
3584 }
3585
3586 static void
3587 isp_handle_rpt_id_acq(ispsoftc_t *isp, isphdr_t *hp)
3588 {
3589 fcparam *fcp;
3590 isp_ridacq_t rid;
3591 int chan, c;
3592 uint32_t portid;
3593
3594 isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
3595 portid = (uint32_t)rid.ridacq_vp_port_hi << 16 |
3596 rid.ridacq_vp_port_lo;
3597 if (rid.ridacq_format == 0) {
3598 for (chan = 0; chan < isp->isp_nchan; chan++) {
3599 fcp = FCPARAM(isp, chan);
3600 if (fcp->role == ISP_ROLE_NONE)
3601 continue;
3602 c = (chan == 0) ? 127 : (chan - 1);
3603 if (rid.ridacq_map[c / 16] & (1 << (c % 16)) ||
3604 chan == 0) {
3605 fcp->isp_loopstate = LOOP_HAVE_LINK;
3606 isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
3607 chan, ISPASYNC_CHANGE_OTHER);
3608 } else {
3609 fcp->isp_loopstate = LOOP_NIL;
3610 isp_async(isp, ISPASYNC_LOOP_DOWN,
3611 chan);
3612 }
3613 }
3614 } else {
3615 fcp = FCPARAM(isp, rid.ridacq_vp_index);
3616 if (rid.ridacq_vp_status == RIDACQ_STS_COMPLETE ||
3617 rid.ridacq_vp_status == RIDACQ_STS_CHANGED) {
3618 fcp->isp_topo = (rid.ridacq_map[0] >> 9) & 0x7;
3619 fcp->isp_portid = portid;
3620 fcp->isp_loopstate = LOOP_HAVE_ADDR;
3621 isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
3622 rid.ridacq_vp_index, ISPASYNC_CHANGE_OTHER);
3623 } else {
3624 fcp->isp_loopstate = LOOP_NIL;
3625 isp_async(isp, ISPASYNC_LOOP_DOWN,
3626 rid.ridacq_vp_index);
3627 }
3628 }
3629 }
3630
3631 static void
3632 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs)
3633 {
3634 int ru_marked, sv_marked;
3635 int chan = XS_CHANNEL(xs);
3636
3637 switch (sp->req_completion_status) {
3638 case RQCS_COMPLETE:
3639 return;
3640
3641 case RQCS_DMA_ERROR:
3642 isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error");
3643 if (XS_NOERR(xs))
3644 XS_SETERR(xs, HBA_BOTCH);
3645 break;
3646
3647 case RQCS_TRANSPORT_ERROR:
3648 isp_xs_prt(isp, xs, ISP_LOGERR, "Transport Error");
3649 if (XS_NOERR(xs))
3650 XS_SETERR(xs, HBA_BOTCH);
3651 break;
3652
3653 case RQCS_RESET_OCCURRED:
3654 isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command");
3655 FCPARAM(isp, chan)->sendmarker = 1;
3656 if (XS_NOERR(xs))
3657 XS_SETERR(xs, HBA_BUSRESET);
3658 return;
3659
3660 case RQCS_ABORTED:
3661 isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
3662 FCPARAM(isp, chan)->sendmarker = 1;
3663 if (XS_NOERR(xs))
3664 XS_SETERR(xs, HBA_ABORTED);
3665 return;
3666
3667 case RQCS_TIMEOUT:
3668 isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out");
3669 if (XS_NOERR(xs))
3670 XS_SETERR(xs, HBA_CMDTIMEOUT);
3671 return;
3672
3673 case RQCS_DATA_OVERRUN:
3674 XS_SET_RESID(xs, sp->req_resid);
3675 isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun");
3676 if (XS_NOERR(xs))
3677 XS_SETERR(xs, HBA_DATAOVR);
3678 return;
3679
3680 case RQCS_DRE: /* data reassembly error */
3681 isp_prt(isp, ISP_LOGERR, "Chan %d data reassembly error for target %d", chan, XS_TGT(xs));
3682 if (XS_NOERR(xs))
3683 XS_SETERR(xs, HBA_BOTCH);
3684 return;
3685
3686 case RQCS_TABORT: /* aborted by target */
3687 isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS", chan, XS_TGT(xs));
3688 if (XS_NOERR(xs))
3689 XS_SETERR(xs, HBA_ABORTED);
3690 return;
3691
3692 case RQCS_DATA_UNDERRUN:
3693 ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
3694 /*
3695 * We can get an underrun w/o things being marked
3696 * if we got a non-zero status.
3697 */
3698 sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
3699 if ((ru_marked == 0 && sv_marked == 0) ||
3700 (sp->req_resid > XS_XFRLEN(xs))) {
3701 isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
3702 if (XS_NOERR(xs))
3703 XS_SETERR(xs, HBA_BOTCH);
3704 return;
3705 }
3706 XS_SET_RESID(xs, sp->req_resid);
3707 isp_xs_prt(isp, xs, ISP_LOG_WARN1, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff);
3708 return;
3709
3710 case RQCS_PORT_UNAVAILABLE:
3711 /*
3712 * No such port on the loop. Moral equivalent of SELTIMEO
3713 */
3714 case RQCS_PORT_LOGGED_OUT:
3715 {
3716 const char *reason;
3717 uint8_t sts = sp->req_completion_status & 0xff;
3718 fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
3719 fcportdb_t *lp;
3720
3721 /*
3722 * It was there (maybe)- treat as a selection timeout.
3723 */
3724 if (sts == RQCS_PORT_UNAVAILABLE) {
3725 reason = "unavailable";
3726 } else {
3727 reason = "logout";
3728 }
3729
3730 isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d",
3731 chan, reason, XS_TGT(xs));
3732
3733 /* XXX: Should we trigger rescan or FW announce change? */
3734
3735 if (XS_NOERR(xs)) {
3736 lp = &fcp->portdb[XS_TGT(xs)];
3737 if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
3738 *XS_STSP(xs) = SCSI_BUSY;
3739 XS_SETERR(xs, HBA_TGTBSY);
3740 } else
3741 XS_SETERR(xs, HBA_SELTIMEOUT);
3742 }
3743 return;
3744 }
3745 case RQCS_PORT_CHANGED:
3746 isp_prt(isp, ISP_LOGWARN, "port changed for target %d chan %d", XS_TGT(xs), chan);
3747 if (XS_NOERR(xs)) {
3748 *XS_STSP(xs) = SCSI_BUSY;
3749 XS_SETERR(xs, HBA_TGTBSY);
3750 }
3751 return;
3752
3753 case RQCS_ENOMEM: /* f/w resource unavailable */
3754 isp_prt(isp, ISP_LOGWARN, "f/w resource unavailable for target %d chan %d", XS_TGT(xs), chan);
3755 if (XS_NOERR(xs)) {
3756 *XS_STSP(xs) = SCSI_BUSY;
3757 XS_SETERR(xs, HBA_TGTBSY);
3758 }
3759 return;
3760
3761 case RQCS_TMO: /* task management overrun */
3762 isp_prt(isp, ISP_LOGWARN, "command for target %d overlapped task management for chan %d", XS_TGT(xs), chan);
3763 if (XS_NOERR(xs)) {
3764 *XS_STSP(xs) = SCSI_BUSY;
3765 XS_SETERR(xs, HBA_TGTBSY);
3766 }
3767 return;
3768
3769 default:
3770 isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x on chan %d", sp->req_completion_status, chan);
3771 break;
3772 }
3773 if (XS_NOERR(xs))
3774 XS_SETERR(xs, HBA_BOTCH);
3775 }
3776
3777 #define ISP_FC_IBITS(op) ((mbpfc[((op)<<3) + 0] << 24) | (mbpfc[((op)<<3) + 1] << 16) | (mbpfc[((op)<<3) + 2] << 8) | (mbpfc[((op)<<3) + 3]))
3778 #define ISP_FC_OBITS(op) ((mbpfc[((op)<<3) + 4] << 24) | (mbpfc[((op)<<3) + 5] << 16) | (mbpfc[((op)<<3) + 6] << 8) | (mbpfc[((op)<<3) + 7]))
3779
3780 #define ISP_FC_OPMAP(in0, out0) 0, 0, 0, in0, 0, 0, 0, out0
3781 #define ISP_FC_OPMAP_HALF(in1, in0, out1, out0) 0, 0, in1, in0, 0, 0, out1, out0
3782 #define ISP_FC_OPMAP_FULL(in3, in2, in1, in0, out3, out2, out1, out0) in3, in2, in1, in0, out3, out2, out1, out0
3783 static const uint32_t mbpfc[] = {
3784 ISP_FC_OPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */
3785 ISP_FC_OPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */
3786 ISP_FC_OPMAP_HALF(0x07, 0xff, 0x00, 0x1f), /* 0x02: MBOX_EXEC_FIRMWARE */
3787 ISP_FC_OPMAP(0xdf, 0x01), /* 0x03: MBOX_DUMP_RAM */
3788 ISP_FC_OPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */
3789 ISP_FC_OPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */
3790 ISP_FC_OPMAP_FULL(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff), /* 0x06: MBOX_MAILBOX_REG_TEST */
3791 ISP_FC_OPMAP(0x07, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */
3792 ISP_FC_OPMAP_FULL(0x0, 0x0, 0x0, 0x01, 0x0, 0x3, 0x80, 0x7f), /* 0x08: MBOX_ABOUT_FIRMWARE */
3793 ISP_FC_OPMAP(0xdf, 0x01), /* 0x09: MBOX_LOAD_RISC_RAM_2100 */
3794 ISP_FC_OPMAP(0xdf, 0x01), /* 0x0a: DUMP RAM */
3795 ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x01), /* 0x0b: MBOX_LOAD_RISC_RAM */
3796 ISP_FC_OPMAP(0x00, 0x00), /* 0x0c: */
3797 ISP_FC_OPMAP_HALF(0x1, 0x0f, 0x0, 0x01), /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
3798 ISP_FC_OPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */
3799 ISP_FC_OPMAP_HALF(0x1, 0x03, 0x0, 0x0d), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
3800 ISP_FC_OPMAP(0x1f, 0x11), /* 0x10: MBOX_INIT_REQ_QUEUE */
3801 ISP_FC_OPMAP(0x2f, 0x21), /* 0x11: MBOX_INIT_RES_QUEUE */
3802 ISP_FC_OPMAP(0x0f, 0x01), /* 0x12: MBOX_EXECUTE_IOCB */
3803 ISP_FC_OPMAP(0x03, 0x03), /* 0x13: MBOX_WAKE_UP */
3804 ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x03), /* 0x14: MBOX_STOP_FIRMWARE */
3805 ISP_FC_OPMAP(0x4f, 0x01), /* 0x15: MBOX_ABORT */
3806 ISP_FC_OPMAP(0x07, 0x01), /* 0x16: MBOX_ABORT_DEVICE */
3807 ISP_FC_OPMAP(0x07, 0x01), /* 0x17: MBOX_ABORT_TARGET */
3808 ISP_FC_OPMAP(0x03, 0x03), /* 0x18: MBOX_BUS_RESET */
3809 ISP_FC_OPMAP(0x07, 0x05), /* 0x19: MBOX_STOP_QUEUE */
3810 ISP_FC_OPMAP(0x07, 0x05), /* 0x1a: MBOX_START_QUEUE */
3811 ISP_FC_OPMAP(0x07, 0x05), /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
3812 ISP_FC_OPMAP(0x07, 0x05), /* 0x1c: MBOX_ABORT_QUEUE */
3813 ISP_FC_OPMAP(0x07, 0x03), /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
3814 ISP_FC_OPMAP(0x00, 0x00), /* 0x1e: */
3815 ISP_FC_OPMAP(0x01, 0x07), /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
3816 ISP_FC_OPMAP_HALF(0x2, 0x01, 0x7e, 0xcf), /* 0x20: MBOX_GET_LOOP_ID */
3817 ISP_FC_OPMAP(0x00, 0x00), /* 0x21: */
3818 ISP_FC_OPMAP(0x03, 0x4b), /* 0x22: MBOX_GET_TIMEOUT_PARAMS */
3819 ISP_FC_OPMAP(0x00, 0x00), /* 0x23: */
3820 ISP_FC_OPMAP(0x00, 0x00), /* 0x24: */
3821 ISP_FC_OPMAP(0x00, 0x00), /* 0x25: */
3822 ISP_FC_OPMAP(0x00, 0x00), /* 0x26: */
3823 ISP_FC_OPMAP(0x00, 0x00), /* 0x27: */
3824 ISP_FC_OPMAP(0x01, 0x03), /* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
3825 ISP_FC_OPMAP(0x03, 0x07), /* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
3826 ISP_FC_OPMAP(0x00, 0x00), /* 0x2a: */
3827 ISP_FC_OPMAP(0x00, 0x00), /* 0x2b: */
3828 ISP_FC_OPMAP(0x00, 0x00), /* 0x2c: */
3829 ISP_FC_OPMAP(0x00, 0x00), /* 0x2d: */
3830 ISP_FC_OPMAP(0x00, 0x00), /* 0x2e: */
3831 ISP_FC_OPMAP(0x00, 0x00), /* 0x2f: */
3832 ISP_FC_OPMAP(0x00, 0x00), /* 0x30: */
3833 ISP_FC_OPMAP(0x00, 0x00), /* 0x31: */
3834 ISP_FC_OPMAP(0x4b, 0x4b), /* 0x32: MBOX_SET_TIMEOUT_PARAMS */
3835 ISP_FC_OPMAP(0x00, 0x00), /* 0x33: */
3836 ISP_FC_OPMAP(0x00, 0x00), /* 0x34: */
3837 ISP_FC_OPMAP(0x00, 0x00), /* 0x35: */
3838 ISP_FC_OPMAP(0x00, 0x00), /* 0x36: */
3839 ISP_FC_OPMAP(0x00, 0x00), /* 0x37: */
3840 ISP_FC_OPMAP(0x0f, 0x01), /* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
3841 ISP_FC_OPMAP(0x0f, 0x07), /* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
3842 ISP_FC_OPMAP(0x00, 0x00), /* 0x3a: */
3843 ISP_FC_OPMAP(0x00, 0x00), /* 0x3b: */
3844 ISP_FC_OPMAP(0x00, 0x00), /* 0x3c: */
3845 ISP_FC_OPMAP(0x00, 0x00), /* 0x3d: */
3846 ISP_FC_OPMAP(0x00, 0x00), /* 0x3e: */
3847 ISP_FC_OPMAP(0x00, 0x00), /* 0x3f: */
3848 ISP_FC_OPMAP(0x03, 0x01), /* 0x40: MBOX_LOOP_PORT_BYPASS */
3849 ISP_FC_OPMAP(0x03, 0x01), /* 0x41: MBOX_LOOP_PORT_ENABLE */
3850 ISP_FC_OPMAP_HALF(0x0, 0x01, 0x1f, 0xcf), /* 0x42: MBOX_GET_RESOURCE_COUNT */
3851 ISP_FC_OPMAP(0x01, 0x01), /* 0x43: MBOX_REQUEST_OFFLINE_MODE */
3852 ISP_FC_OPMAP(0x00, 0x00), /* 0x44: */
3853 ISP_FC_OPMAP(0x00, 0x00), /* 0x45: */
3854 ISP_FC_OPMAP(0x00, 0x00), /* 0x46: */
3855 ISP_FC_OPMAP(0xcf, 0x03), /* 0x47: GET PORT_DATABASE ENHANCED */
3856 ISP_FC_OPMAP(0xcf, 0x0f), /* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */
3857 ISP_FC_OPMAP(0xcd, 0x01), /* 0x49: MBOX_GET_VP_DATABASE */
3858 ISP_FC_OPMAP_HALF(0x2, 0xcd, 0x0, 0x01), /* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */
3859 ISP_FC_OPMAP(0x00, 0x00), /* 0x4b: */
3860 ISP_FC_OPMAP(0x00, 0x00), /* 0x4c: */
3861 ISP_FC_OPMAP(0x00, 0x00), /* 0x4d: */
3862 ISP_FC_OPMAP(0x00, 0x00), /* 0x4e: */
3863 ISP_FC_OPMAP(0x00, 0x00), /* 0x4f: */
3864 ISP_FC_OPMAP(0x00, 0x00), /* 0x50: */
3865 ISP_FC_OPMAP(0x00, 0x00), /* 0x51: */
3866 ISP_FC_OPMAP(0x00, 0x00), /* 0x52: */
3867 ISP_FC_OPMAP(0x00, 0x00), /* 0x53: */
3868 ISP_FC_OPMAP(0xcf, 0x01), /* 0x54: EXECUTE IOCB A64 */
3869 ISP_FC_OPMAP(0x00, 0x00), /* 0x55: */
3870 ISP_FC_OPMAP(0x00, 0x00), /* 0x56: */
3871 ISP_FC_OPMAP(0x00, 0x00), /* 0x57: */
3872 ISP_FC_OPMAP(0x00, 0x00), /* 0x58: */
3873 ISP_FC_OPMAP(0x00, 0x00), /* 0x59: */
3874 ISP_FC_OPMAP(0x00, 0x00), /* 0x5a: */
3875 ISP_FC_OPMAP(0x03, 0x01), /* 0x5b: MBOX_DRIVER_HEARTBEAT */
3876 ISP_FC_OPMAP(0xcf, 0x01), /* 0x5c: MBOX_FW_HEARTBEAT */
3877 ISP_FC_OPMAP(0x07, 0x1f), /* 0x5d: MBOX_GET_SET_DATA_RATE */
3878 ISP_FC_OPMAP(0x00, 0x00), /* 0x5e: */
3879 ISP_FC_OPMAP(0x00, 0x00), /* 0x5f: */
3880 ISP_FC_OPMAP(0xcf, 0x0f), /* 0x60: MBOX_INIT_FIRMWARE */
3881 ISP_FC_OPMAP(0x00, 0x00), /* 0x61: */
3882 ISP_FC_OPMAP(0x01, 0x01), /* 0x62: MBOX_INIT_LIP */
3883 ISP_FC_OPMAP(0xcd, 0x03), /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
3884 ISP_FC_OPMAP(0xcf, 0x01), /* 0x64: MBOX_GET_PORT_DB */
3885 ISP_FC_OPMAP(0x07, 0x01), /* 0x65: MBOX_CLEAR_ACA */
3886 ISP_FC_OPMAP(0x07, 0x01), /* 0x66: MBOX_TARGET_RESET */
3887 ISP_FC_OPMAP(0x07, 0x01), /* 0x67: MBOX_CLEAR_TASK_SET */
3888 ISP_FC_OPMAP(0x07, 0x01), /* 0x68: MBOX_ABORT_TASK_SET */
3889 ISP_FC_OPMAP_HALF(0x00, 0x01, 0x0f, 0x1f), /* 0x69: MBOX_GET_FW_STATE */
3890 ISP_FC_OPMAP_HALF(0x6, 0x03, 0x0, 0xcf), /* 0x6a: MBOX_GET_PORT_NAME */
3891 ISP_FC_OPMAP(0xcf, 0x01), /* 0x6b: MBOX_GET_LINK_STATUS */
3892 ISP_FC_OPMAP(0x0f, 0x01), /* 0x6c: MBOX_INIT_LIP_RESET */
3893 ISP_FC_OPMAP(0x00, 0x00), /* 0x6d: */
3894 ISP_FC_OPMAP(0xcf, 0x03), /* 0x6e: MBOX_SEND_SNS */
3895 ISP_FC_OPMAP(0x0f, 0x07), /* 0x6f: MBOX_FABRIC_LOGIN */
3896 ISP_FC_OPMAP_HALF(0x02, 0x03, 0x00, 0x03), /* 0x70: MBOX_SEND_CHANGE_REQUEST */
3897 ISP_FC_OPMAP(0x03, 0x03), /* 0x71: MBOX_FABRIC_LOGOUT */
3898 ISP_FC_OPMAP(0x0f, 0x0f), /* 0x72: MBOX_INIT_LIP_LOGIN */
3899 ISP_FC_OPMAP(0x00, 0x00), /* 0x73: */
3900 ISP_FC_OPMAP(0x07, 0x01), /* 0x74: LOGIN LOOP PORT */
3901 ISP_FC_OPMAP_HALF(0x03, 0xcf, 0x00, 0x07), /* 0x75: GET PORT/NODE NAME LIST */
3902 ISP_FC_OPMAP(0x4f, 0x01), /* 0x76: SET VENDOR ID */
3903 ISP_FC_OPMAP(0xcd, 0x01), /* 0x77: INITIALIZE IP MAILBOX */
3904 ISP_FC_OPMAP(0x00, 0x00), /* 0x78: */
3905 ISP_FC_OPMAP(0x00, 0x00), /* 0x79: */
3906 ISP_FC_OPMAP(0x00, 0x00), /* 0x7a: */
3907 ISP_FC_OPMAP(0x00, 0x00), /* 0x7b: */
3908 ISP_FC_OPMAP_HALF(0x03, 0x4f, 0x00, 0x07), /* 0x7c: Get ID List */
3909 ISP_FC_OPMAP(0xcf, 0x01), /* 0x7d: SEND LFA */
3910 ISP_FC_OPMAP(0x0f, 0x01) /* 0x7e: LUN RESET */
3911 };
3912 #define MAX_FC_OPCODE 0x7e
3913 /*
3914 * Footnotes
3915 *
3916 * (1): this sets bits 21..16 in mailbox register #8, which we nominally
3917 * do not access at this time in the core driver. The caller is
3918 * responsible for setting this register first (Gross!). The assumption
3919 * is that we won't overflow.
3920 */
3921
3922 static const char *fc_mbcmd_names[] = {
3923 "NO-OP", /* 00h */
3924 "LOAD RAM",
3925 "EXEC FIRMWARE",
3926 "DUMP RAM",
3927 "WRITE RAM WORD",
3928 "READ RAM WORD",
3929 "MAILBOX REG TEST",
3930 "VERIFY CHECKSUM",
3931 "ABOUT FIRMWARE",
3932 "LOAD RAM (2100)",
3933 "DUMP RAM",
3934 "LOAD RISC RAM",
3935 "DUMP RISC RAM",
3936 "WRITE RAM WORD EXTENDED",
3937 "CHECK FIRMWARE",
3938 "READ RAM WORD EXTENDED",
3939 "INIT REQUEST QUEUE", /* 10h */
3940 "INIT RESULT QUEUE",
3941 "EXECUTE IOCB",
3942 "WAKE UP",
3943 "STOP FIRMWARE",
3944 "ABORT",
3945 "ABORT DEVICE",
3946 "ABORT TARGET",
3947 "BUS RESET",
3948 "STOP QUEUE",
3949 "START QUEUE",
3950 "SINGLE STEP QUEUE",
3951 "ABORT QUEUE",
3952 "GET DEV QUEUE STATUS",
3953 NULL,
3954 "GET FIRMWARE STATUS",
3955 "GET LOOP ID", /* 20h */
3956 NULL,
3957 "GET TIMEOUT PARAMS",
3958 NULL,
3959 NULL,
3960 NULL,
3961 NULL,
3962 NULL,
3963 "GET FIRMWARE OPTIONS",
3964 "GET PORT QUEUE PARAMS",
3965 "GENERATE SYSTEM ERROR",
3966 NULL,
3967 NULL,
3968 NULL,
3969 NULL,
3970 NULL,
3971 "WRITE SFP", /* 30h */
3972 "READ SFP",
3973 "SET TIMEOUT PARAMS",
3974 NULL,
3975 NULL,
3976 NULL,
3977 NULL,
3978 NULL,
3979 "SET FIRMWARE OPTIONS",
3980 "SET PORT QUEUE PARAMS",
3981 NULL,
3982 "SET FC LED CONF",
3983 NULL,
3984 "RESTART NIC FIRMWARE",
3985 "ACCESS CONTROL",
3986 NULL,
3987 "LOOP PORT BYPASS", /* 40h */
3988 "LOOP PORT ENABLE",
3989 "GET RESOURCE COUNT",
3990 "REQUEST NON PARTICIPATING MODE",
3991 "DIAGNOSTIC ECHO TEST",
3992 "DIAGNOSTIC LOOPBACK",
3993 NULL,
3994 "GET PORT DATABASE ENHANCED",
3995 "INIT FIRMWARE MULTI ID",
3996 "GET VP DATABASE",
3997 "GET VP DATABASE ENTRY",
3998 NULL,
3999 NULL,
4000 NULL,
4001 NULL,
4002 NULL,
4003 "GET FCF LIST", /* 50h */
4004 "GET DCBX PARAMETERS",
4005 NULL,
4006 "HOST MEMORY COPY",
4007 "EXECUTE IOCB A64",
4008 NULL,
4009 NULL,
4010 "SEND RNID",
4011 NULL,
4012 "SET PARAMETERS",
4013 "GET PARAMETERS",
4014 "DRIVER HEARTBEAT",
4015 "FIRMWARE HEARTBEAT",
4016 "GET/SET DATA RATE",
4017 "SEND RNFT",
4018 NULL,
4019 "INIT FIRMWARE", /* 60h */
4020 "GET INIT CONTROL BLOCK",
4021 "INIT LIP",
4022 "GET FC-AL POSITION MAP",
4023 "GET PORT DATABASE",
4024 "CLEAR ACA",
4025 "TARGET RESET",
4026 "CLEAR TASK SET",
4027 "ABORT TASK SET",
4028 "GET FW STATE",
4029 "GET PORT NAME",
4030 "GET LINK STATUS",
4031 "INIT LIP RESET",
4032 "GET LINK STATS & PRIVATE DATA CNTS",
4033 "SEND SNS",
4034 "FABRIC LOGIN",
4035 "SEND CHANGE REQUEST", /* 70h */
4036 "FABRIC LOGOUT",
4037 "INIT LIP LOGIN",
4038 NULL,
4039 "LOGIN LOOP PORT",
4040 "GET PORT/NODE NAME LIST",
4041 "SET VENDOR ID",
4042 "INITIALIZE IP MAILBOX",
4043 NULL,
4044 NULL,
4045 "GET XGMAC STATS",
4046 NULL,
4047 "GET ID LIST",
4048 "SEND LFA",
4049 "LUN RESET"
4050 };
4051
4052 static void
4053 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
4054 {
4055 const char *cname, *xname, *sname;
4056 char tname[16], mname[16];
4057 unsigned int ibits, obits, box, opcode, t, to;
4058
4059 opcode = mbp->param[0];
4060 if (opcode > MAX_FC_OPCODE) {
4061 mbp->param[0] = MBOX_INVALID_COMMAND;
4062 isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
4063 return;
4064 }
4065 cname = fc_mbcmd_names[opcode];
4066 ibits = ISP_FC_IBITS(opcode);
4067 obits = ISP_FC_OBITS(opcode);
4068 if (cname == NULL) {
4069 cname = tname;
4070 ISP_SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
4071 }
4072 isp_prt(isp, ISP_LOGDEBUG3, "Mailbox Command '%s'", cname);
4073
4074 /*
4075 * Pick up any additional bits that the caller might have set.
4076 */
4077 ibits |= mbp->ibits;
4078 obits |= mbp->obits;
4079
4080 /*
4081 * Mask any bits that the caller wants us to mask
4082 */
4083 ibits &= mbp->ibitm;
4084 obits &= mbp->obitm;
4085
4086
4087 if (ibits == 0 && obits == 0) {
4088 mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
4089 isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
4090 return;
4091 }
4092
4093 for (box = 0; box < ISP_NMBOX(isp); box++) {
4094 if (ibits & (1 << box)) {
4095 isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box,
4096 mbp->param[box]);
4097 ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
4098 }
4099 isp->isp_mboxtmp[box] = mbp->param[box] = 0;
4100 }
4101
4102 isp->isp_obits = obits;
4103 isp->isp_mboxbsy = 1;
4104
4105 /*
4106 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
4107 */
4108 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
4109
4110 /*
4111 * While we haven't finished the command, spin our wheels here.
4112 */
4113 to = (mbp->timeout == 0) ? MBCMD_DEFAULT_TIMEOUT : mbp->timeout;
4114 for (t = 0; t < to; t += 100) {
4115 if (!isp->isp_mboxbsy)
4116 break;
4117 ISP_RUN_ISR(isp);
4118 if (!isp->isp_mboxbsy)
4119 break;
4120 ISP_DELAY(100);
4121 }
4122
4123 /*
4124 * Did the command time out?
4125 */
4126 if (isp->isp_mboxbsy) {
4127 isp->isp_mboxbsy = 0;
4128 isp_prt(isp, ISP_LOGWARN, "Mailbox Command (0x%x) Timeout (%uus) (%s:%d)",
4129 opcode, to, mbp->func, mbp->lineno);
4130 mbp->param[0] = MBOX_TIMEOUT;
4131 goto out;
4132 }
4133
4134 /*
4135 * Copy back output registers.
4136 */
4137 for (box = 0; box < ISP_NMBOX(isp); box++) {
4138 if (obits & (1 << box)) {
4139 mbp->param[box] = isp->isp_mboxtmp[box];
4140 isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box,
4141 mbp->param[box]);
4142 }
4143 }
4144
4145 out:
4146 if (mbp->logval == 0 || mbp->param[0] == MBOX_COMMAND_COMPLETE)
4147 return;
4148
4149 if ((mbp->param[0] & 0xbfe0) == 0 &&
4150 (mbp->logval & MBLOGMASK(mbp->param[0])) == 0)
4151 return;
4152
4153 xname = NULL;
4154 sname = "";
4155 switch (mbp->param[0]) {
4156 case MBOX_INVALID_COMMAND:
4157 xname = "INVALID COMMAND";
4158 break;
4159 case MBOX_HOST_INTERFACE_ERROR:
4160 xname = "HOST INTERFACE ERROR";
4161 break;
4162 case MBOX_TEST_FAILED:
4163 xname = "TEST FAILED";
4164 break;
4165 case MBOX_COMMAND_ERROR:
4166 xname = "COMMAND ERROR";
4167 ISP_SNPRINTF(mname, sizeof(mname), " subcode 0x%x",
4168 mbp->param[1]);
4169 sname = mname;
4170 break;
4171 case MBOX_COMMAND_PARAM_ERROR:
4172 xname = "COMMAND PARAMETER ERROR";
4173 break;
4174 case MBOX_PORT_ID_USED:
4175 xname = "PORT ID ALREADY IN USE";
4176 break;
4177 case MBOX_LOOP_ID_USED:
4178 xname = "LOOP ID ALREADY IN USE";
4179 break;
4180 case MBOX_ALL_IDS_USED:
4181 xname = "ALL LOOP IDS IN USE";
4182 break;
4183 case MBOX_NOT_LOGGED_IN:
4184 xname = "NOT LOGGED IN";
4185 break;
4186 case MBOX_LINK_DOWN_ERROR:
4187 xname = "LINK DOWN ERROR";
4188 break;
4189 case MBOX_LOOPBACK_ERROR:
4190 xname = "LOOPBACK ERROR";
4191 break;
4192 case MBOX_CHECKSUM_ERROR:
4193 xname = "CHECKSUM ERROR";
4194 break;
4195 case MBOX_INVALID_PRODUCT_KEY:
4196 xname = "INVALID PRODUCT KEY";
4197 break;
4198 case MBOX_REGS_BUSY:
4199 xname = "REGISTERS BUSY";
4200 break;
4201 case MBOX_TIMEOUT:
4202 xname = "TIMEOUT";
4203 break;
4204 default:
4205 ISP_SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
4206 xname = mname;
4207 break;
4208 }
4209 if (xname) {
4210 isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s%s)",
4211 cname, xname, sname);
4212 }
4213 }
4214
4215 static int
4216 isp_fw_state(ispsoftc_t *isp, int chan)
4217 {
4218 mbreg_t mbs;
4219
4220 MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0);
4221 isp_mboxcmd(isp, &mbs);
4222 if (mbs.param[0] == MBOX_COMMAND_COMPLETE)
4223 return (mbs.param[1]);
4224 return (FW_ERROR);
4225 }
4226
4227 static void
4228 isp_setdfltfcparm(ispsoftc_t *isp, int chan)
4229 {
4230 fcparam *fcp = FCPARAM(isp, chan);
4231
4232 /*
4233 * Establish some default parameters.
4234 */
4235 fcp->role = DEFAULT_ROLE(isp, chan);
4236 fcp->isp_retry_delay = ICB_DFLT_RDELAY;
4237 fcp->isp_retry_count = ICB_DFLT_RCOUNT;
4238 fcp->isp_loopid = DEFAULT_LOOPID(isp, chan);
4239 fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
4240 fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
4241 fcp->isp_fwoptions = 0;
4242 fcp->isp_xfwoptions = 0;
4243 fcp->isp_zfwoptions = 0;
4244 fcp->isp_lasthdl = NIL_HANDLE;
4245 fcp->isp_login_hdl = NIL_HANDLE;
4246
4247 fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS;
4248 fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS;
4249 if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
4250 fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
4251 fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
4252 fcp->isp_xfwoptions |= ICB2400_OPT2_LOOP_2_PTP;
4253 fcp->isp_zfwoptions |= ICB2400_OPT3_RATE_AUTO;
4254
4255 /*
4256 * Now try and read NVRAM unless told to not do so.
4257 * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
4258 */
4259 if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
4260 int i, j = 0;
4261 /*
4262 * Give a couple of tries at reading NVRAM.
4263 */
4264 for (i = 0; i < 2; i++) {
4265 j = isp_read_nvram(isp, chan);
4266 if (j == 0) {
4267 break;
4268 }
4269 }
4270 if (j) {
4271 isp->isp_confopts |= ISP_CFG_NONVRAM;
4272 }
4273 }
4274
4275 fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan);
4276 fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan);
4277 isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s",
4278 chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn),
4279 (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn),
4280 isp_class3_roles[fcp->role]);
4281 }
4282
4283 /*
4284 * Re-initialize the ISP and complete all orphaned commands
4285 * with a 'botched' notice. The reset/init routines should
4286 * not disturb an already active list of commands.
4287 */
4288
4289 int
4290 isp_reinit(ispsoftc_t *isp, int do_load_defaults)
4291 {
4292 int i, res = 0;
4293
4294 if (isp->isp_state > ISP_RESETSTATE)
4295 isp_stop(isp);
4296 if (isp->isp_state != ISP_RESETSTATE)
4297 isp_reset(isp, do_load_defaults);
4298 if (isp->isp_state != ISP_RESETSTATE) {
4299 res = EIO;
4300 isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
4301 goto cleanup;
4302 }
4303
4304 isp_init(isp);
4305 if (isp->isp_state > ISP_RESETSTATE &&
4306 isp->isp_state != ISP_RUNSTATE) {
4307 res = EIO;
4308 isp_prt(isp, ISP_LOGERR, "%s: cannot init card", __func__);
4309 ISP_DISABLE_INTS(isp);
4310 }
4311
4312 cleanup:
4313 isp_clear_commands(isp);
4314 for (i = 0; i < isp->isp_nchan; i++)
4315 isp_clear_portdb(isp, i);
4316 return (res);
4317 }
4318
4319 /*
4320 * NVRAM Routines
4321 */
4322 static int
4323 isp_read_nvram(ispsoftc_t *isp, int bus)
4324 {
4325
4326 return (isp_read_nvram_2400(isp));
4327 }
4328
4329 static int
4330 isp_read_nvram_2400(ispsoftc_t *isp)
4331 {
4332 int retval = 0;
4333 uint32_t addr, csum, lwrds, *dptr;
4334 uint8_t nvram_data[ISP2400_NVRAM_SIZE];
4335
4336 addr = ISP2400_NVRAM_PORT_ADDR(isp->isp_port);
4337 dptr = (uint32_t *) nvram_data;
4338 for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
4339 isp_rd_2400_nvram(isp, addr++, dptr++);
4340 }
4341 if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
4342 nvram_data[2] != 'P') {
4343 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
4344 nvram_data[0], nvram_data[1], nvram_data[2]);
4345 retval = -1;
4346 goto out;
4347 }
4348 dptr = (uint32_t *) nvram_data;
4349 for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
4350 uint32_t tmp;
4351 ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
4352 csum += tmp;
4353 }
4354 if (csum != 0) {
4355 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
4356 retval = -1;
4357 goto out;
4358 }
4359 isp_parse_nvram_2400(isp, nvram_data);
4360 out:
4361 return (retval);
4362 }
4363
4364 static void
4365 isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
4366 {
4367 int loops = 0;
4368 uint32_t base = 0x7ffe0000;
4369 uint32_t tmp = 0;
4370
4371 if (IS_26XX(isp)) {
4372 base = 0x7fe7c000; /* XXX: Observation, may be wrong. */
4373 } else if (IS_25XX(isp)) {
4374 base = 0x7ff00000 | 0x48000;
4375 }
4376 ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
4377 for (loops = 0; loops < 5000; loops++) {
4378 ISP_DELAY(10);
4379 tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
4380 if ((tmp & (1U << 31)) != 0) {
4381 break;
4382 }
4383 }
4384 if (tmp & (1U << 31)) {
4385 *rp = ISP_READ(isp, BIU2400_FLASH_DATA);
4386 ISP_SWIZZLE_NVRAM_LONG(isp, rp);
4387 } else {
4388 *rp = 0xffffffff;
4389 }
4390 }
4391
4392 static void
4393 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
4394 {
4395 fcparam *fcp = FCPARAM(isp, 0);
4396 uint64_t wwn;
4397
4398 isp_prt(isp, ISP_LOGDEBUG0,
4399 "NVRAM 0x%08x%08x 0x%08x%08x maxframelen %d",
4400 (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
4401 (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
4402 (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
4403 (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
4404 ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
4405 isp_prt(isp, ISP_LOGDEBUG0,
4406 "NVRAM loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
4407 ISP2400_NVRAM_HARDLOOPID(nvram_data),
4408 ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
4409 ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
4410 ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
4411
4412 wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
4413 fcp->isp_wwpn_nvram = wwn;
4414
4415 wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
4416 if (wwn) {
4417 if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
4418 wwn = 0;
4419 }
4420 }
4421 if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
4422 wwn = fcp->isp_wwpn_nvram;
4423 wwn &= ~((uint64_t) 0xfff << 48);
4424 }
4425 fcp->isp_wwnn_nvram = wwn;
4426
4427 if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
4428 DEFAULT_FRAMESIZE(isp) =
4429 ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
4430 }
4431 if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
4432 fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
4433 }
4434 fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
4435 fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
4436 fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
4437 }
Cache object: 267e0748e45f2174afa7124f8ee7d0c4
|