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