Annotation of sys/dev/ic/isp.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: isp.c,v 1.39 2007/05/23 01:32:25 ray Exp $ */
2: /*
3: * Machine and OS Independent (well, as best as possible)
4: * code for the Qlogic ISP SCSI adapters.
5: *
6: * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob
7: * Feral Software
8: * All rights reserved.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice immediately at the beginning of the file, without modification,
15: * this list of conditions, and the following disclaimer.
16: * 2. The name of the author may not be used to endorse or promote products
17: * derived from this software without specific prior written permission.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29: * SUCH DAMAGE.
30: */
31:
32: /*
33: * Inspiration and ideas about this driver are from Erik Moe's Linux driver
34: * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
35: * ideas dredged from the Solaris driver.
36: */
37:
38: /*
39: * Include header file appropriate for platform we're building on.
40: */
41:
42: #ifdef __NetBSD__
43: #include <dev/ic/isp_netbsd.h>
44: #endif
45: #ifdef __FreeBSD__
46: #include <dev/isp/isp_freebsd.h>
47: #endif
48: #ifdef __OpenBSD__
49: #include <dev/ic/isp_openbsd.h>
50: #endif
51: #ifdef __linux__
52: #include "isp_linux.h"
53: #endif
54: #ifdef __svr4__
55: #include "isp_solaris.h"
56: #endif
57:
58: /*
59: * General defines
60: */
61:
62: #define MBOX_DELAY_COUNT 1000000 / 100
63:
64: /*
65: * Local static data
66: */
67: static const char portshift[] =
68: "Target %d Loop ID 0x%x (Port 0x%x) => Loop 0x%x (Port 0x%x)";
69: static const char portdup[] =
70: "Target %d duplicates Target %d- killing off both";
71: static const char retained[] =
72: "Retaining Loop ID 0x%x for Target %d (Port 0x%x)";
73: static const char lretained[] =
74: "Retained login of Target %d (Loop ID 0x%x) Port 0x%x";
75: static const char plogout[] =
76: "Logging out Target %d at Loop ID 0x%x (Port 0x%x)";
77: static const char plogierr[] =
78: "Command Error in PLOGI for Port 0x%x (0x%x)";
79: static const char nopdb[] =
80: "Could not get PDB for Device @ Port 0x%x";
81: static const char pdbmfail1[] =
82: "PDB Loop ID info for Device @ Port 0x%x does not match up (0x%x)";
83: static const char pdbmfail2[] =
84: "PDB Port info for Device @ Port 0x%x does not match up (0x%x)";
85: static const char ldumped[] =
86: "Target %d (Loop ID 0x%x) Port 0x%x dumped after login info mismatch";
87: static const char notresp[] =
88: "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
89: static const char xact1[] =
90: "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
91: static const char xact2[] =
92: "HBA attempted queued transaction to target routine %d on target %d bus %d";
93: static const char xact3[] =
94: "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
95: static const char pskip[] =
96: "SCSI phase skipped for target %d.%d.%d";
97: static const char topology[] =
98: "Loop ID %d, AL_PA 0x%x, Port ID 0x%x, Loop State 0x%x, Topology '%s'";
99: static const char swrej[] =
100: "Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x";
101: static const char finmsg[] =
102: "(%d.%d.%d): FIN dl%d resid %lu STS 0x%x SKEY %c XS_ERR=0x%x";
103: static const char sc0[] =
104: "%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x";
105: static const char sc1[] =
106: "%s RAAN 0x%x DLAN 0x%x DDMAB 0x%x CDMAB 0x%x SELTIME %d MQD %d";
107: static const char sc2[] = "%s CHAN %d TGT %d FLAGS 0x%x 0x%x/0x%x";
108: static const char sc3[] = "Generated";
109: static const char sc4[] = "NVRAM";
110: static const char bun[] =
111: "bad underrun for %d.%d (count %d, resid %d, status %s)";
112:
113: /*
114: * Local function prototypes.
115: */
116: static int isp_parse_async(struct ispsoftc *, u_int16_t);
117: static int isp_handle_other_response(struct ispsoftc *, int, isphdr_t *,
118: u_int16_t *);
119: static void
120: isp_parse_status(struct ispsoftc *, ispstatusreq_t *, XS_T *);
121: static void isp_fastpost_complete(struct ispsoftc *, u_int16_t);
122: static int isp_mbox_continue(struct ispsoftc *);
123: static void isp_scsi_init(struct ispsoftc *);
124: static void isp_scsi_channel_init(struct ispsoftc *, int);
125: static void isp_fibre_init(struct ispsoftc *);
126: static void isp_mark_getpdb_all(struct ispsoftc *);
127: static int isp_getmap(struct ispsoftc *, fcpos_map_t *);
128: static int isp_getpdb(struct ispsoftc *, int, isp_pdb_t *);
129: static u_int64_t isp_get_portname(struct ispsoftc *, int, int);
130: static int isp_fclink_test(struct ispsoftc *, int);
131: static char *isp2100_fw_statename(int);
132: static int isp_pdb_sync(struct ispsoftc *);
133: static int isp_scan_loop(struct ispsoftc *);
134: static int isp_fabric_mbox_cmd(struct ispsoftc *, mbreg_t *);
135: static int isp_scan_fabric(struct ispsoftc *, int);
136: static void isp_register_fc4_type(struct ispsoftc *);
137: static void isp_fw_state(struct ispsoftc *);
138: static void isp_mboxcmd_qnw(struct ispsoftc *, mbreg_t *, int);
139: static void isp_mboxcmd(struct ispsoftc *, mbreg_t *, int);
140:
141: static void isp_update(struct ispsoftc *);
142: static void isp_update_bus(struct ispsoftc *, int);
143: static void isp_setdfltparm(struct ispsoftc *, int);
144: static int isp_read_nvram(struct ispsoftc *);
145: static void isp_rdnvram_word(struct ispsoftc *, int, u_int16_t *);
146: static void isp_parse_nvram_1020(struct ispsoftc *, u_int8_t *);
147: static void isp_parse_nvram_1080(struct ispsoftc *, int, u_int8_t *);
148: static void isp_parse_nvram_12160(struct ispsoftc *, int, u_int8_t *);
149: static void isp_parse_nvram_2100(struct ispsoftc *, u_int8_t *);
150:
151: /*
152: * Reset Hardware.
153: *
154: * Hit the chip over the head, download new f/w if available and set it running.
155: *
156: * Locking done elsewhere.
157: */
158:
159: void
160: isp_reset(struct ispsoftc *isp)
161: {
162: mbreg_t mbs;
163: u_int16_t code_org;
164: int loops, i, dodnld = 1;
165: char *btype = "????";
166:
167: isp->isp_state = ISP_NILSTATE;
168:
169: /*
170: * Basic types (SCSI, FibreChannel and PCI or SBus)
171: * have been set in the MD code. We figure out more
172: * here. Possibly more refined types based upon PCI
173: * identification. Chip revision has been gathered.
174: *
175: * After we've fired this chip up, zero out the conf1 register
176: * for SCSI adapters and do other settings for the 2100.
177: */
178:
179: /*
180: * Get the current running firmware revision out of the
181: * chip before we hit it over the head (if this is our
182: * first time through). Note that we store this as the
183: * 'ROM' firmware revision- which it may not be. In any
184: * case, we don't really use this yet, but we may in
185: * the future.
186: */
187: if (isp->isp_touched == 0) {
188: /*
189: * First see whether or not we're sitting in the ISP PROM.
190: * If we've just been reset, we'll have the string "ISP "
191: * spread through outgoing mailbox registers 1-3. We do
192: * this for PCI cards because otherwise we really don't
193: * know what state the card is in and we could hang if
194: * we try this command otherwise.
195: *
196: * For SBus cards, we just do this because they almost
197: * certainly will be running firmware by now.
198: */
199: if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 ||
200: ISP_READ(isp, OUTMAILBOX2) != 0x5020 ||
201: ISP_READ(isp, OUTMAILBOX3) != 0x2020) {
202: /*
203: * Just in case it was paused...
204: */
205: ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
206: mbs.param[0] = MBOX_ABOUT_FIRMWARE;
207: isp_mboxcmd(isp, &mbs, MBLOGNONE);
208: if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
209: isp->isp_romfw_rev[0] = mbs.param[1];
210: isp->isp_romfw_rev[1] = mbs.param[2];
211: isp->isp_romfw_rev[2] = mbs.param[3];
212: }
213: }
214: isp->isp_touched = 1;
215: }
216:
217: DISABLE_INTS(isp);
218:
219: /*
220: * Set up default request/response queue in-pointer/out-pointer
221: * register indices.
222: */
223: if (IS_23XX(isp)) {
224: isp->isp_rqstinrp = BIU_REQINP;
225: isp->isp_rqstoutrp = BIU_REQOUTP;
226: isp->isp_respinrp = BIU_RSPINP;
227: isp->isp_respoutrp = BIU_RSPOUTP;
228: } else {
229: isp->isp_rqstinrp = INMAILBOX4;
230: isp->isp_rqstoutrp = OUTMAILBOX4;
231: isp->isp_respinrp = OUTMAILBOX5;
232: isp->isp_respoutrp = INMAILBOX5;
233: }
234:
235: /*
236: * Put the board into PAUSE mode (so we can read the SXP registers
237: * or write FPM/FBM registers).
238: */
239: ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
240:
241: if (IS_FC(isp)) {
242: switch (isp->isp_type) {
243: case ISP_HA_FC_2100:
244: btype = "2100";
245: break;
246: case ISP_HA_FC_2200:
247: btype = "2200";
248: break;
249: case ISP_HA_FC_2300:
250: btype = "2300";
251: break;
252: case ISP_HA_FC_2312:
253: btype = "2312";
254: break;
255: default:
256: break;
257: }
258: /*
259: * While we're paused, reset the FPM module and FBM fifos.
260: */
261: ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
262: ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
263: ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
264: ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
265: ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
266: } else if (IS_1240(isp)) {
267: sdparam *sdp = isp->isp_param;
268: btype = "1240";
269: isp->isp_clock = 60;
270: sdp->isp_ultramode = 1;
271: sdp++;
272: sdp->isp_ultramode = 1;
273: /*
274: * XXX: Should probably do some bus sensing.
275: */
276: } else if (IS_ULTRA2(isp)) {
277: static const char m[] = "bus %d is in %s Mode";
278: u_int16_t l;
279: sdparam *sdp = isp->isp_param;
280:
281: isp->isp_clock = 100;
282:
283: if (IS_1280(isp))
284: btype = "1280";
285: else if (IS_1080(isp))
286: btype = "1080";
287: else if (IS_10160(isp))
288: btype = "10160";
289: else if (IS_12160(isp))
290: btype = "12160";
291: else
292: btype = "<UNKLVD>";
293:
294: l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
295: switch (l) {
296: case ISP1080_LVD_MODE:
297: sdp->isp_lvdmode = 1;
298: isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
299: break;
300: case ISP1080_HVD_MODE:
301: sdp->isp_diffmode = 1;
302: isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
303: break;
304: case ISP1080_SE_MODE:
305: sdp->isp_ultramode = 1;
306: isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
307: break;
308: default:
309: isp_prt(isp, ISP_LOGERR,
310: "unknown mode on bus %d (0x%x)", 0, l);
311: break;
312: }
313:
314: if (IS_DUALBUS(isp)) {
315: sdp++;
316: l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
317: l &= ISP1080_MODE_MASK;
318: switch(l) {
319: case ISP1080_LVD_MODE:
320: sdp->isp_lvdmode = 1;
321: isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
322: break;
323: case ISP1080_HVD_MODE:
324: sdp->isp_diffmode = 1;
325: isp_prt(isp, ISP_LOGCONFIG,
326: m, 1, "Differential");
327: break;
328: case ISP1080_SE_MODE:
329: sdp->isp_ultramode = 1;
330: isp_prt(isp, ISP_LOGCONFIG,
331: m, 1, "Single-Ended");
332: break;
333: default:
334: isp_prt(isp, ISP_LOGERR,
335: "unknown mode on bus %d (0x%x)", 1, l);
336: break;
337: }
338: }
339: } else {
340: sdparam *sdp = isp->isp_param;
341: i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
342: switch (i) {
343: default:
344: isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
345: /* FALLTHROUGH */
346: case 1:
347: btype = "1020";
348: isp->isp_type = ISP_HA_SCSI_1020;
349: isp->isp_clock = 40;
350: break;
351: case 2:
352: /*
353: * Some 1020A chips are Ultra Capable, but don't
354: * run the clock rate up for that unless told to
355: * do so by the Ultra Capable bits being set.
356: */
357: btype = "1020A";
358: isp->isp_type = ISP_HA_SCSI_1020A;
359: isp->isp_clock = 40;
360: break;
361: case 3:
362: btype = "1040";
363: isp->isp_type = ISP_HA_SCSI_1040;
364: isp->isp_clock = 60;
365: break;
366: case 4:
367: btype = "1040A";
368: isp->isp_type = ISP_HA_SCSI_1040A;
369: isp->isp_clock = 60;
370: break;
371: case 5:
372: btype = "1040B";
373: isp->isp_type = ISP_HA_SCSI_1040B;
374: isp->isp_clock = 60;
375: break;
376: case 6:
377: btype = "1040C";
378: isp->isp_type = ISP_HA_SCSI_1040C;
379: isp->isp_clock = 60;
380: break;
381: }
382: /*
383: * Now, while we're at it, gather info about ultra
384: * and/or differential mode.
385: */
386: if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
387: isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
388: sdp->isp_diffmode = 1;
389: } else {
390: sdp->isp_diffmode = 0;
391: }
392: i = ISP_READ(isp, RISC_PSR);
393: if (isp->isp_bustype == ISP_BT_SBUS) {
394: i &= RISC_PSR_SBUS_ULTRA;
395: } else {
396: i &= RISC_PSR_PCI_ULTRA;
397: }
398: if (i != 0) {
399: isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
400: sdp->isp_ultramode = 1;
401: /*
402: * If we're in Ultra Mode, we have to be 60MHz clock-
403: * even for the SBus version.
404: */
405: isp->isp_clock = 60;
406: } else {
407: sdp->isp_ultramode = 0;
408: /*
409: * Clock is known. Gronk.
410: */
411: }
412:
413: /*
414: * Machine dependent clock (if set) overrides
415: * our generic determinations.
416: */
417: if (isp->isp_mdvec->dv_clock) {
418: if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
419: isp->isp_clock = isp->isp_mdvec->dv_clock;
420: }
421: }
422:
423: }
424:
425: /*
426: * Clear instrumentation
427: */
428: isp->isp_intcnt = isp->isp_intbogus = 0;
429:
430: /*
431: * Do MD specific pre initialization
432: */
433: ISP_RESET0(isp);
434:
435: again:
436:
437: /*
438: * Hit the chip over the head with hammer,
439: * and give the ISP a chance to recover.
440: */
441:
442: if (IS_SCSI(isp)) {
443: ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
444: /*
445: * A slight delay...
446: */
447: USEC_DELAY(100);
448:
449: /*
450: * Clear data && control DMA engines.
451: */
452: ISP_WRITE(isp, CDMA_CONTROL,
453: DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
454: ISP_WRITE(isp, DDMA_CONTROL,
455: DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
456:
457:
458: } else {
459: ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
460: /*
461: * A slight delay...
462: */
463: USEC_DELAY(100);
464:
465: /*
466: * Clear data && control DMA engines.
467: */
468: ISP_WRITE(isp, CDMA2100_CONTROL,
469: DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
470: ISP_WRITE(isp, TDMA2100_CONTROL,
471: DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
472: ISP_WRITE(isp, RDMA2100_CONTROL,
473: DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
474: }
475:
476: /*
477: * Wait for ISP to be ready to go...
478: */
479: loops = MBOX_DELAY_COUNT;
480: for (;;) {
481: if (IS_SCSI(isp)) {
482: if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET))
483: break;
484: } else {
485: if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
486: break;
487: }
488: USEC_DELAY(100);
489: if (--loops < 0) {
490: ISP_DUMPREGS(isp, "chip reset timed out");
491: return;
492: }
493: }
494:
495: /*
496: * After we've fired this chip up, zero out the conf1 register
497: * for SCSI adapters and other settings for the 2100.
498: */
499:
500: if (IS_SCSI(isp)) {
501: ISP_WRITE(isp, BIU_CONF1, 0);
502: } else {
503: ISP_WRITE(isp, BIU2100_CSR, 0);
504: }
505:
506: /*
507: * Reset RISC Processor
508: */
509: ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
510: USEC_DELAY(100);
511: /* Clear semaphore register (just to be sure) */
512: ISP_WRITE(isp, BIU_SEMA, 0);
513:
514: /*
515: * Establish some initial burst rate stuff.
516: * (only for the 1XX0 boards). This really should
517: * be done later after fetching from NVRAM.
518: */
519: if (IS_SCSI(isp)) {
520: u_int16_t tmp = isp->isp_mdvec->dv_conf1;
521: /*
522: * Busted FIFO. Turn off all but burst enables.
523: */
524: if (isp->isp_type == ISP_HA_SCSI_1040A) {
525: tmp &= BIU_BURST_ENABLE;
526: }
527: ISP_SETBITS(isp, BIU_CONF1, tmp);
528: if (tmp & BIU_BURST_ENABLE) {
529: ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
530: ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
531: }
532: #ifdef PTI_CARDS
533: if (((sdparam *) isp->isp_param)->isp_ultramode) {
534: while (ISP_READ(isp, RISC_MTR) != 0x1313) {
535: ISP_WRITE(isp, RISC_MTR, 0x1313);
536: ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
537: }
538: } else {
539: ISP_WRITE(isp, RISC_MTR, 0x1212);
540: }
541: /*
542: * PTI specific register
543: */
544: ISP_WRITE(isp, RISC_EMB, DUAL_BANK)
545: #else
546: ISP_WRITE(isp, RISC_MTR, 0x1212);
547: #endif
548: } else {
549: ISP_WRITE(isp, RISC_MTR2100, 0x1212);
550: if (IS_2200(isp) || IS_23XX(isp)) {
551: ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
552: }
553: }
554:
555: ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); /* release paused processor */
556:
557: /*
558: * Do MD specific post initialization
559: */
560: ISP_RESET1(isp);
561:
562: /*
563: * Wait for everything to finish firing up.
564: *
565: * Avoid doing this on the 2312 because you can generate a PCI
566: * parity error (chip breakage).
567: */
568: if (IS_23XX(isp)) {
569: USEC_DELAY(5);
570: } else {
571: loops = MBOX_DELAY_COUNT;
572: while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
573: USEC_DELAY(100);
574: if (--loops < 0) {
575: isp_prt(isp, ISP_LOGERR,
576: "MBOX_BUSY never cleared on reset");
577: return;
578: }
579: }
580: }
581:
582: /*
583: * Up until this point we've done everything by just reading or
584: * setting registers. From this point on we rely on at least *some*
585: * kind of firmware running in the card.
586: */
587:
588: /*
589: * Do some sanity checking.
590: */
591: mbs.param[0] = MBOX_NO_OP;
592: isp_mboxcmd(isp, &mbs, MBLOGALL);
593: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
594: return;
595: }
596:
597: if (IS_SCSI(isp)) {
598: mbs.param[0] = MBOX_MAILBOX_REG_TEST;
599: mbs.param[1] = 0xdead;
600: mbs.param[2] = 0xbeef;
601: mbs.param[3] = 0xffff;
602: mbs.param[4] = 0x1111;
603: mbs.param[5] = 0xa5a5;
604: isp_mboxcmd(isp, &mbs, MBLOGALL);
605: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
606: return;
607: }
608: if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
609: mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
610: mbs.param[5] != 0xa5a5) {
611: isp_prt(isp, ISP_LOGERR,
612: "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)",
613: mbs.param[1], mbs.param[2], mbs.param[3],
614: mbs.param[4], mbs.param[5]);
615: return;
616: }
617:
618: }
619:
620: /*
621: * Download new Firmware, unless requested not to do so.
622: * This is made slightly trickier in some cases where the
623: * firmware of the ROM revision is newer than the revision
624: * compiled into the driver. So, where we used to compare
625: * versions of our f/w and the ROM f/w, now we just see
626: * whether we have f/w at all and whether a config flag
627: * has disabled our download.
628: */
629: if ((isp->isp_mdvec->dv_ispfw == NULL) ||
630: (isp->isp_confopts & ISP_CFG_NORELOAD)) {
631: dodnld = 0;
632: }
633:
634: if (IS_23XX(isp))
635: code_org = ISP_CODE_ORG_2300;
636: else
637: code_org = ISP_CODE_ORG;
638:
639: if (dodnld) {
640: isp->isp_mbxworkp = (void *) &isp->isp_mdvec->dv_ispfw[1];
641: isp->isp_mbxwrk0 = isp->isp_mdvec->dv_ispfw[3] - 1;
642: isp->isp_mbxwrk1 = code_org + 1;
643: mbs.param[0] = MBOX_WRITE_RAM_WORD;
644: mbs.param[1] = code_org;
645: mbs.param[2] = isp->isp_mdvec->dv_ispfw[0];
646: isp_mboxcmd(isp, &mbs, MBLOGNONE);
647: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
648: isp_prt(isp, ISP_LOGERR,
649: "F/W download failed at word %d",
650: isp->isp_mbxwrk1 - code_org);
651: dodnld = 0;
652: goto again;
653: }
654: /*
655: * Verify that it downloaded correctly.
656: */
657: mbs.param[0] = MBOX_VERIFY_CHECKSUM;
658: mbs.param[1] = code_org;
659: isp_mboxcmd(isp, &mbs, MBLOGNONE);
660: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
661: isp_prt(isp, ISP_LOGERR, "Ram Checksum Failure");
662: return;
663: }
664: isp->isp_loaded_fw = 1;
665: } else {
666: isp->isp_loaded_fw = 0;
667: isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
668: }
669:
670: /*
671: * Now start it rolling.
672: *
673: * If we didn't actually download f/w,
674: * we still need to (re)start it.
675: */
676:
677:
678: mbs.param[0] = MBOX_EXEC_FIRMWARE;
679: mbs.param[1] = code_org;
680: isp_mboxcmd(isp, &mbs, MBLOGNONE);
681: /*
682: * Give it a chance to start.
683: */
684: USEC_DELAY(500);
685:
686: if (IS_SCSI(isp)) {
687: /*
688: * Set CLOCK RATE, but only if asked to.
689: */
690: if (isp->isp_clock) {
691: mbs.param[0] = MBOX_SET_CLOCK_RATE;
692: mbs.param[1] = isp->isp_clock;
693: isp_mboxcmd(isp, &mbs, MBLOGALL);
694: /* we will try not to care if this fails */
695: }
696: }
697:
698: mbs.param[0] = MBOX_ABOUT_FIRMWARE;
699: isp_mboxcmd(isp, &mbs, MBLOGALL);
700: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
701: return;
702: }
703:
704: /*
705: * The SBus firmware that we are using apparently does not return
706: * major, minor, micro revisions in the mailbox registers, which
707: * is really, really, annoying.
708: */
709: if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
710: if (dodnld) {
711: #ifdef ISP_TARGET_MODE
712: isp->isp_fwrev[0] = 7;
713: isp->isp_fwrev[1] = 55;
714: #else
715: isp->isp_fwrev[0] = 1;
716: isp->isp_fwrev[1] = 37;
717: #endif
718: isp->isp_fwrev[2] = 0;
719: }
720: } else {
721: isp->isp_fwrev[0] = mbs.param[1];
722: isp->isp_fwrev[1] = mbs.param[2];
723: isp->isp_fwrev[2] = mbs.param[3];
724: }
725: isp_prt(isp, ISP_LOGCONFIG,
726: "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
727: btype, isp->isp_revision, dodnld? "loaded" : "resident",
728: isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
729:
730: if (IS_FC(isp)) {
731: /*
732: * We do not believe firmware attributes for 2100 code less
733: * than 1.17.0, unless it's the firmware we specifically
734: * are loading.
735: *
736: * Note that all 22XX and 23XX f/w is greater than 1.X.0.
737: */
738: if (!(ISP_FW_NEWER_THAN(isp, 1, 17, 0))) {
739: #ifdef USE_SMALLER_2100_FIRMWARE
740: FCPARAM(isp)->isp_fwattr = ISP_FW_ATTR_SCCLUN;
741: #else
742: FCPARAM(isp)->isp_fwattr = 0;
743: #endif
744: } else {
745: FCPARAM(isp)->isp_fwattr = mbs.param[6];
746: isp_prt(isp, ISP_LOGDEBUG0,
747: "Firmware Attributes = 0x%x", mbs.param[6]);
748: }
749: if (ISP_READ(isp, BIU2100_CSR) & BIU2100_PCI64) {
750: isp_prt(isp, ISP_LOGCONFIG,
751: "Installed in 64-Bit PCI slot");
752: }
753: }
754:
755: if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] ||
756: isp->isp_romfw_rev[2]) {
757: isp_prt(isp, ISP_LOGCONFIG, "Last F/W revision was %d.%d.%d",
758: isp->isp_romfw_rev[0], isp->isp_romfw_rev[1],
759: isp->isp_romfw_rev[2]);
760: }
761:
762: mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
763: isp_mboxcmd(isp, &mbs, MBLOGALL);
764: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
765: return;
766: }
767: isp->isp_maxcmds = mbs.param[2];
768: isp_prt(isp, ISP_LOGINFO,
769: "%d max I/O commands supported", mbs.param[2]);
770: isp_fw_state(isp);
771:
772: /*
773: * Set up DMA for the request and result mailboxes.
774: */
775: if (ISP_MBOXDMASETUP(isp) != 0) {
776: isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
777: return;
778: }
779: isp->isp_state = ISP_RESETSTATE;
780:
781: /*
782: * Okay- now that we have new firmware running, we now (re)set our
783: * notion of how many luns we support. This is somewhat tricky because
784: * if we haven't loaded firmware, we sometimes do not have an easy way
785: * of knowing how many luns we support.
786: *
787: * Expanded lun firmware gives you 32 luns for SCSI cards and
788: * 16384 luns for Fibre Channel cards.
789: *
790: * It turns out that even for QLogic 2100s with ROM 1.10 and above
791: * we do get a firmware attributes word returned in mailbox register 6.
792: *
793: * Because the lun is in a different position in the Request Queue
794: * Entry structure for Fibre Channel with expanded lun firmware, we
795: * can only support one lun (lun zero) when we don't know what kind
796: * of firmware we're running.
797: */
798: if (IS_SCSI(isp)) {
799: if (dodnld) {
800: if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
801: isp->isp_maxluns = 32;
802: } else {
803: isp->isp_maxluns = 8;
804: }
805: } else {
806: isp->isp_maxluns = 8;
807: }
808: } else {
809: if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
810: isp->isp_maxluns = 16384;
811: } else {
812: isp->isp_maxluns = 16;
813: }
814: }
815: }
816:
817: /*
818: * Initialize Parameters of Hardware to a known state.
819: *
820: * Locks are held before coming here.
821: */
822:
823: void
824: isp_init(struct ispsoftc *isp)
825: {
826: /*
827: * Must do this first to get defaults established.
828: */
829: isp_setdfltparm(isp, 0);
830: if (IS_DUALBUS(isp)) {
831: isp_setdfltparm(isp, 1);
832: }
833: if (IS_FC(isp)) {
834: isp_fibre_init(isp);
835: } else {
836: isp_scsi_init(isp);
837: }
838: }
839:
840: static void
841: isp_scsi_init(struct ispsoftc *isp)
842: {
843: sdparam *sdp_chan0, *sdp_chan1;
844: mbreg_t mbs;
845:
846: sdp_chan0 = isp->isp_param;
847: sdp_chan1 = sdp_chan0;
848: if (IS_DUALBUS(isp)) {
849: sdp_chan1++;
850: }
851:
852: /*
853: * If we have no role (neither target nor initiator), return.
854: */
855: if (isp->isp_role == ISP_ROLE_NONE) {
856: return;
857: }
858:
859: /* First do overall per-card settings. */
860:
861: /*
862: * If we have fast memory timing enabled, turn it on.
863: */
864: if (sdp_chan0->isp_fast_mttr) {
865: ISP_WRITE(isp, RISC_MTR, 0x1313);
866: }
867:
868: /*
869: * Set Retry Delay and Count.
870: * You set both channels at the same time.
871: */
872: mbs.param[0] = MBOX_SET_RETRY_COUNT;
873: mbs.param[1] = sdp_chan0->isp_retry_count;
874: mbs.param[2] = sdp_chan0->isp_retry_delay;
875: mbs.param[6] = sdp_chan1->isp_retry_count;
876: mbs.param[7] = sdp_chan1->isp_retry_delay;
877:
878: isp_mboxcmd(isp, &mbs, MBLOGALL);
879: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
880: return;
881: }
882:
883: /*
884: * Set ASYNC DATA SETUP time. This is very important.
885: */
886: mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
887: mbs.param[1] = sdp_chan0->isp_async_data_setup;
888: mbs.param[2] = sdp_chan1->isp_async_data_setup;
889: isp_mboxcmd(isp, &mbs, MBLOGALL);
890: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
891: return;
892: }
893:
894: /*
895: * Set ACTIVE Negation State.
896: */
897: mbs.param[0] = MBOX_SET_ACT_NEG_STATE;
898: mbs.param[1] =
899: (sdp_chan0->isp_req_ack_active_neg << 4) |
900: (sdp_chan0->isp_data_line_active_neg << 5);
901: mbs.param[2] =
902: (sdp_chan1->isp_req_ack_active_neg << 4) |
903: (sdp_chan1->isp_data_line_active_neg << 5);
904:
905: isp_mboxcmd(isp, &mbs, MBLOGNONE);
906: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
907: isp_prt(isp, ISP_LOGERR,
908: "failed to set active negation state (%d,%d), (%d,%d)",
909: sdp_chan0->isp_req_ack_active_neg,
910: sdp_chan0->isp_data_line_active_neg,
911: sdp_chan1->isp_req_ack_active_neg,
912: sdp_chan1->isp_data_line_active_neg);
913: /*
914: * But don't return.
915: */
916: }
917:
918: /*
919: * Set the Tag Aging limit
920: */
921: mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT;
922: mbs.param[1] = sdp_chan0->isp_tag_aging;
923: mbs.param[2] = sdp_chan1->isp_tag_aging;
924: isp_mboxcmd(isp, &mbs, MBLOGALL);
925: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
926: isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
927: sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
928: return;
929: }
930:
931: /*
932: * Set selection timeout.
933: */
934: mbs.param[0] = MBOX_SET_SELECT_TIMEOUT;
935: mbs.param[1] = sdp_chan0->isp_selection_timeout;
936: mbs.param[2] = sdp_chan1->isp_selection_timeout;
937: isp_mboxcmd(isp, &mbs, MBLOGALL);
938: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
939: return;
940: }
941:
942: /* now do per-channel settings */
943: isp_scsi_channel_init(isp, 0);
944: if (IS_DUALBUS(isp))
945: isp_scsi_channel_init(isp, 1);
946:
947: /*
948: * Now enable request/response queues
949: */
950:
951: if (IS_ULTRA2(isp) || IS_1240(isp)) {
952: mbs.param[0] = MBOX_INIT_RES_QUEUE_A64;
953: mbs.param[1] = RESULT_QUEUE_LEN(isp);
954: mbs.param[2] = DMA_WD1(isp->isp_result_dma);
955: mbs.param[3] = DMA_WD0(isp->isp_result_dma);
956: mbs.param[4] = 0;
957: mbs.param[6] = DMA_WD3(isp->isp_result_dma);
958: mbs.param[7] = DMA_WD2(isp->isp_result_dma);
959: isp_mboxcmd(isp, &mbs, MBLOGALL);
960: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
961: return;
962: }
963: isp->isp_residx = mbs.param[5];
964:
965: mbs.param[0] = MBOX_INIT_REQ_QUEUE_A64;
966: mbs.param[1] = RQUEST_QUEUE_LEN(isp);
967: mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
968: mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
969: mbs.param[5] = 0;
970: mbs.param[6] = DMA_WD3(isp->isp_result_dma);
971: mbs.param[7] = DMA_WD2(isp->isp_result_dma);
972: isp_mboxcmd(isp, &mbs, MBLOGALL);
973: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
974: return;
975: }
976: isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
977: } else {
978: mbs.param[0] = MBOX_INIT_RES_QUEUE;
979: mbs.param[1] = RESULT_QUEUE_LEN(isp);
980: mbs.param[2] = DMA_WD1(isp->isp_result_dma);
981: mbs.param[3] = DMA_WD0(isp->isp_result_dma);
982: mbs.param[4] = 0;
983: isp_mboxcmd(isp, &mbs, MBLOGALL);
984: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
985: return;
986: }
987: isp->isp_residx = mbs.param[5];
988:
989: mbs.param[0] = MBOX_INIT_REQ_QUEUE;
990: mbs.param[1] = RQUEST_QUEUE_LEN(isp);
991: mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
992: mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
993: mbs.param[5] = 0;
994: isp_mboxcmd(isp, &mbs, MBLOGALL);
995: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
996: return;
997: }
998: isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
999: }
1000:
1001: /*
1002: * Turn on Fast Posting, LVD transitions
1003: *
1004: * Ultra2 F/W always has had fast posting (and LVD transitions)
1005: *
1006: * Ultra and older (i.e., SBus) cards may not. It's just safer
1007: * to assume not for them.
1008: */
1009:
1010: mbs.param[0] = MBOX_SET_FW_FEATURES;
1011: mbs.param[1] = 0;
1012: if (IS_ULTRA2(isp))
1013: mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
1014: #ifndef ISP_NO_RIO
1015: if (IS_ULTRA2(isp) || IS_1240(isp))
1016: mbs.param[1] |= FW_FEATURE_RIO_16BIT;
1017: #else
1018: #ifndef ISP_NO_FASTPOST
1019: if (IS_ULTRA2(isp) || IS_1240(isp))
1020: mbs.param[1] |= FW_FEATURE_FAST_POST;
1021: #endif
1022: #endif
1023: if (mbs.param[1] != 0) {
1024: u_int16_t sfeat = mbs.param[1];
1025: isp_mboxcmd(isp, &mbs, MBLOGALL);
1026: if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1027: isp_prt(isp, ISP_LOGINFO,
1028: "Enabled FW features (0x%x)", sfeat);
1029: }
1030: }
1031:
1032: /*
1033: * Let the outer layers decide whether to issue a SCSI bus reset.
1034: */
1035: isp->isp_state = ISP_INITSTATE;
1036: }
1037:
1038: static void
1039: isp_scsi_channel_init(struct ispsoftc *isp, int channel)
1040: {
1041: sdparam *sdp;
1042: mbreg_t mbs;
1043: int tgt;
1044:
1045: sdp = isp->isp_param;
1046: sdp += channel;
1047:
1048: /*
1049: * Set (possibly new) Initiator ID.
1050: */
1051: mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
1052: mbs.param[1] = (channel << 7) | sdp->isp_initiator_id;
1053: isp_mboxcmd(isp, &mbs, MBLOGALL);
1054: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1055: return;
1056: }
1057: isp_prt(isp, ISP_LOGINFO, "Initiator ID is %d on Channel %d",
1058: sdp->isp_initiator_id, channel);
1059:
1060:
1061: /*
1062: * Set current per-target parameters to an initial safe minimum.
1063: */
1064: for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1065: int lun;
1066: u_int16_t sdf;
1067:
1068: if (sdp->isp_devparam[tgt].dev_enable == 0) {
1069: continue;
1070: }
1071: #ifndef ISP_TARGET_MODE
1072: sdf = sdp->isp_devparam[tgt].goal_flags;
1073: sdf &= DPARM_SAFE_DFLT;
1074: /*
1075: * It is not quite clear when this changed over so that
1076: * we could force narrow and async for 1000/1020 cards,
1077: * but assume that this is only the case for loaded
1078: * firmware.
1079: */
1080: if (isp->isp_loaded_fw) {
1081: sdf |= DPARM_NARROW | DPARM_ASYNC;
1082: }
1083: #else
1084: /*
1085: * The !$*!)$!$)* f/w uses the same index into some
1086: * internal table to decide how to respond to negotiations,
1087: * so if we've said "let's be safe" for ID X, and ID X
1088: * selects *us*, the negotiations will back to 'safe'
1089: * (as in narrow/async). What the f/w *should* do is
1090: * use the initiator id settings to decide how to respond.
1091: */
1092: sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
1093: #endif
1094: mbs.param[0] = MBOX_SET_TARGET_PARAMS;
1095: mbs.param[1] = (channel << 15) | (tgt << 8);
1096: mbs.param[2] = sdf;
1097: if ((sdf & DPARM_SYNC) == 0) {
1098: mbs.param[3] = 0;
1099: } else {
1100: mbs.param[3] =
1101: (sdp->isp_devparam[tgt].goal_offset << 8) |
1102: (sdp->isp_devparam[tgt].goal_period);
1103: }
1104: isp_prt(isp, ISP_LOGDEBUG0,
1105: "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
1106: channel, tgt, mbs.param[2], mbs.param[3] >> 8,
1107: mbs.param[3] & 0xff);
1108: isp_mboxcmd(isp, &mbs, MBLOGNONE);
1109: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1110: sdf = DPARM_SAFE_DFLT;
1111: mbs.param[0] = MBOX_SET_TARGET_PARAMS;
1112: mbs.param[1] = (tgt << 8) | (channel << 15);
1113: mbs.param[2] = sdf;
1114: mbs.param[3] = 0;
1115: isp_mboxcmd(isp, &mbs, MBLOGALL);
1116: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1117: continue;
1118: }
1119: }
1120:
1121: /*
1122: * We don't update any information directly from the f/w
1123: * because we need to run at least one command to cause a
1124: * new state to be latched up. So, we just assume that we
1125: * converge to the values we just had set.
1126: *
1127: * Ensure that we don't believe tagged queuing is enabled yet.
1128: * It turns out that sometimes the ISP just ignores our
1129: * attempts to set parameters for devices that it hasn't
1130: * seen yet.
1131: */
1132: sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
1133: for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
1134: mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
1135: mbs.param[1] = (channel << 15) | (tgt << 8) | lun;
1136: mbs.param[2] = sdp->isp_max_queue_depth;
1137: mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
1138: isp_mboxcmd(isp, &mbs, MBLOGALL);
1139: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1140: break;
1141: }
1142: }
1143: }
1144: for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1145: if (sdp->isp_devparam[tgt].dev_refresh) {
1146: isp->isp_sendmarker |= (1 << channel);
1147: isp->isp_update |= (1 << channel);
1148: break;
1149: }
1150: }
1151: }
1152:
1153: /*
1154: * Fibre Channel specific initialization.
1155: *
1156: * Locks are held before coming here.
1157: */
1158: static void
1159: isp_fibre_init(struct ispsoftc *isp)
1160: {
1161: fcparam *fcp;
1162: isp_icb_t local, *icbp = &local;
1163: mbreg_t mbs;
1164: int loopid;
1165: u_int64_t nwwn, pwwn;
1166:
1167: fcp = isp->isp_param;
1168:
1169: /*
1170: * Do this *before* initializing the firmware.
1171: */
1172: isp_mark_getpdb_all(isp);
1173: fcp->isp_fwstate = FW_CONFIG_WAIT;
1174: fcp->isp_loopstate = LOOP_NIL;
1175:
1176: /*
1177: * If we have no role (neither target nor initiator), return.
1178: */
1179: if (isp->isp_role == ISP_ROLE_NONE) {
1180: return;
1181: }
1182:
1183: loopid = fcp->isp_loopid;
1184: MEMZERO(icbp, sizeof (*icbp));
1185: icbp->icb_version = ICB_VERSION1;
1186:
1187: /*
1188: * Firmware Options are either retrieved from NVRAM or
1189: * are patched elsewhere. We check them for sanity here
1190: * and make changes based on board revision, but otherwise
1191: * let others decide policy.
1192: */
1193:
1194: /*
1195: * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
1196: */
1197: if ((isp->isp_type == ISP_HA_FC_2100) && isp->isp_revision < 5) {
1198: fcp->isp_fwoptions &= ~ICBOPT_FAIRNESS;
1199: }
1200:
1201: /*
1202: * We have to use FULL LOGIN even though it resets the loop too much
1203: * because otherwise port database entries don't get updated after
1204: * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
1205: */
1206: if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
1207: fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
1208: }
1209:
1210: /*
1211: * Insist on Port Database Update Async notifications
1212: */
1213: fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
1214:
1215: /*
1216: * Make sure that target role reflects into fwoptions.
1217: */
1218: if (isp->isp_role & ISP_ROLE_TARGET) {
1219: fcp->isp_fwoptions |= ICBOPT_TGT_ENABLE;
1220: } else {
1221: fcp->isp_fwoptions &= ~ICBOPT_TGT_ENABLE;
1222: }
1223:
1224: /*
1225: * Propagate all of this into the ICB structure.
1226: */
1227: icbp->icb_fwoptions = fcp->isp_fwoptions;
1228: icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
1229: if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
1230: icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
1231: isp_prt(isp, ISP_LOGERR,
1232: "bad frame length (%d) from NVRAM- using %d",
1233: fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN);
1234: icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
1235: }
1236: icbp->icb_maxalloc = fcp->isp_maxalloc;
1237: if (icbp->icb_maxalloc < 1) {
1238: isp_prt(isp, ISP_LOGERR,
1239: "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
1240: icbp->icb_maxalloc = 16;
1241: }
1242: icbp->icb_execthrottle = fcp->isp_execthrottle;
1243: if (icbp->icb_execthrottle < 1) {
1244: isp_prt(isp, ISP_LOGERR,
1245: "bad execution throttle of %d- using 16",
1246: fcp->isp_execthrottle);
1247: icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
1248: }
1249: icbp->icb_retry_delay = fcp->isp_retry_delay;
1250: icbp->icb_retry_count = fcp->isp_retry_count;
1251: icbp->icb_hardaddr = loopid;
1252: /*
1253: * Right now we just set extended options to prefer point-to-point
1254: * over loop based upon some soft config options.
1255: *
1256: * NB: for the 2300, ICBOPT_EXTENDED is required.
1257: */
1258: if (IS_2200(isp) || IS_23XX(isp)) {
1259: icbp->icb_fwoptions |= ICBOPT_EXTENDED;
1260: /*
1261: * Prefer or force Point-To-Point instead Loop?
1262: */
1263: switch(isp->isp_confopts & ISP_CFG_PORT_PREF) {
1264: case ISP_CFG_NPORT:
1265: icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
1266: break;
1267: case ISP_CFG_NPORT_ONLY:
1268: icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY;
1269: break;
1270: case ISP_CFG_LPORT_ONLY:
1271: icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY;
1272: break;
1273: default:
1274: icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
1275: break;
1276: }
1277: if (IS_23XX(isp)) {
1278: /*
1279: * QLogic recommends that FAST Posting be turned
1280: * off for 23XX cards and instead allow the HBA
1281: * to write response queue entries and interrupt
1282: * after a delay (ZIO).
1283: *
1284: * If we set ZIO, it will disable fast posting,
1285: * so we don't need to clear it in fwoptions.
1286: */
1287: icbp->icb_xfwoptions |= ICBXOPT_ZIO;
1288: #if 0
1289: /*
1290: * Values, in 100us increments. The default
1291: * is 2 (200us) if a value 0 (default) is
1292: * selected.
1293: */
1294: icbp->icb_idelaytimer = 2;
1295: #endif
1296:
1297: if (isp->isp_confopts & ISP_CFG_ONEGB) {
1298: icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
1299: } else if (isp->isp_confopts & ISP_CFG_TWOGB) {
1300: icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB;
1301: } else {
1302: icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
1303: }
1304: }
1305: }
1306:
1307: #ifndef ISP_NO_RIO_FC
1308: /*
1309: * RIO seems to be enabled in 2100s for fw >= 1.17.0.
1310: *
1311: * I've had some questionable problems with RIO on 2200.
1312: * More specifically, on a 2204 I had problems with RIO
1313: * on a Linux system where I was dropping commands right
1314: * and left. It's not clear to me what the actual problem
1315: * was.
1316: *
1317: * 23XX Cards do not support RIO. Instead they support ZIO.
1318: */
1319: #if 0
1320: if (!IS_23XX(isp) && ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
1321: icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
1322: icbp->icb_racctimer = 4;
1323: icbp->icb_idelaytimer = 8;
1324: }
1325: #endif
1326: #endif
1327:
1328: /*
1329: * For 22XX > 2.1.26 && 23XX, set someoptions.
1330: * XXX: Probably okay for newer 2100 f/w too.
1331: */
1332: if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
1333: /*
1334: * Turn on LIP F8 async event (1)
1335: * Turn on generate AE 8013 on all LIP Resets (2)
1336: * Disable LIP F7 switching (8)
1337: */
1338: mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS;
1339: mbs.param[1] = 0xb;
1340: mbs.param[2] = 0;
1341: mbs.param[3] = 0;
1342: isp_mboxcmd(isp, &mbs, MBLOGALL);
1343: }
1344: icbp->icb_logintime = 30; /* 30 second login timeout */
1345:
1346: if (IS_23XX(isp)) {
1347: ISP_WRITE(isp, isp->isp_rqstinrp, 0);
1348: ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
1349: ISP_WRITE(isp, isp->isp_respinrp, 0);
1350: ISP_WRITE(isp, isp->isp_respoutrp, 0);
1351: }
1352:
1353: nwwn = ISP_NODEWWN(isp);
1354: pwwn = ISP_PORTWWN(isp);
1355: if (nwwn && pwwn) {
1356: icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
1357: MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn);
1358: MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
1359: isp_prt(isp, ISP_LOGDEBUG1,
1360: "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
1361: ((u_int32_t) (nwwn >> 32)),
1362: ((u_int32_t) (nwwn & 0xffffffff)),
1363: ((u_int32_t) (pwwn >> 32)),
1364: ((u_int32_t) (pwwn & 0xffffffff)));
1365: } else {
1366: isp_prt(isp, ISP_LOGDEBUG1, "Not using any WWNs");
1367: icbp->icb_fwoptions &= ~(ICBOPT_BOTH_WWNS|ICBOPT_FULL_LOGIN);
1368: }
1369: icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
1370: icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
1371: icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1372: icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1373: icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1374: icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
1375: icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1376: icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1377: icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1378: icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
1379: isp_prt(isp, ISP_LOGDEBUG0,
1380: "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
1381: icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
1382:
1383: FC_SCRATCH_ACQUIRE(isp);
1384: isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
1385:
1386: /*
1387: * Init the firmware
1388: */
1389: mbs.param[0] = MBOX_INIT_FIRMWARE;
1390: mbs.param[1] = 0;
1391: mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1392: mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1393: mbs.param[4] = 0;
1394: mbs.param[5] = 0;
1395: mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1396: mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1397: isp_mboxcmd(isp, &mbs, MBLOGALL);
1398: FC_SCRATCH_RELEASE(isp);
1399: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1400: return;
1401: }
1402: isp->isp_reqidx = isp->isp_reqodx = 0;
1403: isp->isp_residx = 0;
1404: isp->isp_sendmarker = 1;
1405:
1406: /*
1407: * Whatever happens, we're now committed to being here.
1408: */
1409: isp->isp_state = ISP_INITSTATE;
1410: }
1411:
1412: /*
1413: * Fibre Channel Support- get the port database for the id.
1414: *
1415: * Locks are held before coming here. Return 0 if success,
1416: * else failure.
1417: */
1418:
1419: static int
1420: isp_getmap(struct ispsoftc *isp, fcpos_map_t *map)
1421: {
1422: fcparam *fcp = (fcparam *) isp->isp_param;
1423: mbreg_t mbs;
1424:
1425: mbs.param[0] = MBOX_GET_FC_AL_POSITION_MAP;
1426: mbs.param[1] = 0;
1427: mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1428: mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1429: /*
1430: * Unneeded. For the 2100, except for initializing f/w, registers
1431: * 4/5 have to not be written to.
1432: * mbs.param[4] = 0;
1433: * mbs.param[5] = 0;
1434: *
1435: */
1436: mbs.param[6] = 0;
1437: mbs.param[7] = 0;
1438: FC_SCRATCH_ACQUIRE(isp);
1439: isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
1440: if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1441: MEMCPY(map, fcp->isp_scratch, sizeof (fcpos_map_t));
1442: map->fwmap = mbs.param[1] != 0;
1443: FC_SCRATCH_RELEASE(isp);
1444: return (0);
1445: }
1446: FC_SCRATCH_RELEASE(isp);
1447: return (-1);
1448: }
1449:
1450: static void
1451: isp_mark_getpdb_all(struct ispsoftc *isp)
1452: {
1453: fcparam *fcp = (fcparam *) isp->isp_param;
1454: int i;
1455: for (i = 0; i < MAX_FC_TARG; i++) {
1456: fcp->portdb[i].valid = fcp->portdb[i].fabric_dev = 0;
1457: }
1458: }
1459:
1460: static int
1461: isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp)
1462: {
1463: fcparam *fcp = (fcparam *) isp->isp_param;
1464: mbreg_t mbs;
1465:
1466: mbs.param[0] = MBOX_GET_PORT_DB;
1467: mbs.param[1] = id << 8;
1468: mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1469: mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1470: /*
1471: * Unneeded. For the 2100, except for initializing f/w, registers
1472: * 4/5 have to not be written to.
1473: * mbs.param[4] = 0;
1474: * mbs.param[5] = 0;
1475: *
1476: */
1477: mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1478: mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1479: FC_SCRATCH_ACQUIRE(isp);
1480: isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
1481: if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1482: isp_get_pdb(isp, (isp_pdb_t *)fcp->isp_scratch, pdbp);
1483: FC_SCRATCH_RELEASE(isp);
1484: return (0);
1485: }
1486: FC_SCRATCH_RELEASE(isp);
1487: return (-1);
1488: }
1489:
1490: static u_int64_t
1491: isp_get_portname(struct ispsoftc *isp, int loopid, int nodename)
1492: {
1493: u_int64_t wwn = 0;
1494: mbreg_t mbs;
1495:
1496: mbs.param[0] = MBOX_GET_PORT_NAME;
1497: mbs.param[1] = loopid << 8;
1498: if (nodename)
1499: mbs.param[1] |= 1;
1500: isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
1501: if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1502: wwn =
1503: (((u_int64_t)(mbs.param[2] & 0xff)) << 56) |
1504: (((u_int64_t)(mbs.param[2] >> 8)) << 48) |
1505: (((u_int64_t)(mbs.param[3] & 0xff)) << 40) |
1506: (((u_int64_t)(mbs.param[3] >> 8)) << 32) |
1507: (((u_int64_t)(mbs.param[6] & 0xff)) << 24) |
1508: (((u_int64_t)(mbs.param[6] >> 8)) << 16) |
1509: (((u_int64_t)(mbs.param[7] & 0xff)) << 8) |
1510: (((u_int64_t)(mbs.param[7] >> 8)));
1511: }
1512: return (wwn);
1513: }
1514:
1515: /*
1516: * Make sure we have good FC link and know our Loop ID.
1517: */
1518:
1519: static int
1520: isp_fclink_test(struct ispsoftc *isp, int usdelay)
1521: {
1522: static char *toponames[] = {
1523: "Private Loop",
1524: "FL Port",
1525: "N-Port to N-Port",
1526: "F Port",
1527: "F Port (no FLOGI_ACC response)"
1528: };
1529: mbreg_t mbs;
1530: int count, check_for_fabric;
1531: u_int8_t lwfs;
1532: fcparam *fcp;
1533: struct lportdb *lp;
1534: isp_pdb_t pdb;
1535:
1536: fcp = isp->isp_param;
1537:
1538: /*
1539: * XXX: Here is where we would start a 'loop dead' timeout
1540: */
1541:
1542: /*
1543: * Wait up to N microseconds for F/W to go to a ready state.
1544: */
1545: lwfs = FW_CONFIG_WAIT;
1546: count = 0;
1547: while (count < usdelay) {
1548: u_int64_t enano;
1549: u_int32_t wrk;
1550: NANOTIME_T hra, hrb;
1551:
1552: GET_NANOTIME(&hra);
1553: isp_fw_state(isp);
1554: if (lwfs != fcp->isp_fwstate) {
1555: isp_prt(isp, ISP_LOGINFO, "Firmware State <%s->%s>",
1556: isp2100_fw_statename((int)lwfs),
1557: isp2100_fw_statename((int)fcp->isp_fwstate));
1558: lwfs = fcp->isp_fwstate;
1559: }
1560: if (fcp->isp_fwstate == FW_READY) {
1561: break;
1562: }
1563: GET_NANOTIME(&hrb);
1564:
1565: /*
1566: * Get the elapsed time in nanoseconds.
1567: * Always guaranteed to be non-zero.
1568: */
1569: enano = NANOTIME_SUB(&hrb, &hra);
1570:
1571: isp_prt(isp, ISP_LOGDEBUG1,
1572: "usec%d: 0x%lx->0x%lx enano 0x%x%08x",
1573: count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb),
1574: (u_int32_t)(enano >> 32), (u_int32_t)(enano & 0xffffffff));
1575:
1576: /*
1577: * If the elapsed time is less than 1 millisecond,
1578: * delay a period of time up to that millisecond of
1579: * waiting.
1580: *
1581: * This peculiar code is an attempt to try and avoid
1582: * invoking u_int64_t math support functions for some
1583: * platforms where linkage is a problem.
1584: */
1585: if (enano < (1000 * 1000)) {
1586: count += 1000;
1587: enano = (1000 * 1000) - enano;
1588: while (enano > (u_int64_t) 4000000000U) {
1589: USEC_SLEEP(isp, 4000000);
1590: enano -= (u_int64_t) 4000000000U;
1591: }
1592: wrk = enano;
1593: wrk /= 1000;
1594: USEC_SLEEP(isp, wrk);
1595: } else {
1596: while (enano > (u_int64_t) 4000000000U) {
1597: count += 4000000;
1598: enano -= (u_int64_t) 4000000000U;
1599: }
1600: wrk = enano;
1601: count += (wrk / 1000);
1602: }
1603: }
1604:
1605: /*
1606: * If we haven't gone to 'ready' state, return.
1607: */
1608: if (fcp->isp_fwstate != FW_READY) {
1609: return (-1);
1610: }
1611:
1612: /*
1613: * Get our Loop ID (if possible). We really need to have it.
1614: */
1615: mbs.param[0] = MBOX_GET_LOOP_ID;
1616: isp_mboxcmd(isp, &mbs, MBLOGALL);
1617: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1618: return (-1);
1619: }
1620: fcp->isp_loopid = mbs.param[1];
1621: if (IS_2200(isp) || IS_23XX(isp)) {
1622: int topo = (int) mbs.param[6];
1623: if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
1624: topo = TOPO_PTP_STUB;
1625: fcp->isp_topo = topo;
1626: } else {
1627: fcp->isp_topo = TOPO_NL_PORT;
1628: }
1629: fcp->isp_portid = fcp->isp_alpa = mbs.param[2] & 0xff;
1630:
1631: /*
1632: * Check to see if we're on a fabric by trying to see if we
1633: * can talk to the fabric name server. This can be a bit
1634: * tricky because if we're a 2100, we should check always
1635: * (in case we're connected to a server doing aliasing).
1636: */
1637: fcp->isp_onfabric = 0;
1638:
1639: if (IS_2100(isp)) {
1640: /*
1641: * Don't bother with fabric if we are using really old
1642: * 2100 firmware. It's just not worth it.
1643: */
1644: if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) {
1645: check_for_fabric = 1;
1646: } else {
1647: check_for_fabric = 0;
1648: }
1649: } else if (fcp->isp_topo == TOPO_FL_PORT ||
1650: fcp->isp_topo == TOPO_F_PORT) {
1651: check_for_fabric = 1;
1652: } else
1653: check_for_fabric = 0;
1654:
1655: if (check_for_fabric && isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
1656: int loopid = FL_PORT_ID;
1657: if (IS_2100(isp)) {
1658: fcp->isp_topo = TOPO_FL_PORT;
1659: }
1660:
1661: if (BITS2WORD(pdb.pdb_portid_bits) == 0) {
1662: /*
1663: * Crock.
1664: */
1665: fcp->isp_topo = TOPO_NL_PORT;
1666: goto not_on_fabric;
1667: }
1668: fcp->isp_portid = mbs.param[2] | ((int) mbs.param[3] << 16);
1669:
1670: /*
1671: * Save the Fabric controller's port database entry.
1672: */
1673: lp = &fcp->portdb[loopid];
1674: lp->node_wwn =
1675: (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
1676: (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
1677: (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
1678: (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
1679: (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
1680: (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
1681: (((u_int64_t)pdb.pdb_nodename[6]) << 8) |
1682: (((u_int64_t)pdb.pdb_nodename[7]));
1683: lp->port_wwn =
1684: (((u_int64_t)pdb.pdb_portname[0]) << 56) |
1685: (((u_int64_t)pdb.pdb_portname[1]) << 48) |
1686: (((u_int64_t)pdb.pdb_portname[2]) << 40) |
1687: (((u_int64_t)pdb.pdb_portname[3]) << 32) |
1688: (((u_int64_t)pdb.pdb_portname[4]) << 24) |
1689: (((u_int64_t)pdb.pdb_portname[5]) << 16) |
1690: (((u_int64_t)pdb.pdb_portname[6]) << 8) |
1691: (((u_int64_t)pdb.pdb_portname[7]));
1692: lp->roles =
1693: (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
1694: lp->portid = BITS2WORD(pdb.pdb_portid_bits);
1695: lp->loopid = pdb.pdb_loopid;
1696: lp->loggedin = lp->valid = 1;
1697: fcp->isp_onfabric = 1;
1698: (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
1699: isp_register_fc4_type(isp);
1700: } else {
1701: not_on_fabric:
1702: fcp->isp_onfabric = 0;
1703: fcp->portdb[FL_PORT_ID].valid = 0;
1704: }
1705:
1706: fcp->isp_gbspeed = 1;
1707: if (IS_23XX(isp)) {
1708: mbs.param[0] = MBOX_GET_SET_DATA_RATE;
1709: mbs.param[1] = MBGSD_GET_RATE;
1710: /* mbs.param[2] undefined if we're just getting rate */
1711: isp_mboxcmd(isp, &mbs, MBLOGALL);
1712: if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1713: if (mbs.param[1] == MBGSD_TWOGB) {
1714: isp_prt(isp, ISP_LOGINFO, "2Gb link speed/s");
1715: fcp->isp_gbspeed = 2;
1716: }
1717: }
1718: }
1719:
1720: isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_loopid, fcp->isp_alpa,
1721: fcp->isp_portid, fcp->isp_loopstate, toponames[fcp->isp_topo]);
1722:
1723: /*
1724: * Announce ourselves, too. This involves synthesizing an entry.
1725: */
1726: if (fcp->isp_iid_set == 0) {
1727: fcp->isp_iid_set = 1;
1728: fcp->isp_iid = fcp->isp_loopid;
1729: lp = &fcp->portdb[fcp->isp_iid];
1730: } else {
1731: lp = &fcp->portdb[fcp->isp_iid];
1732: if (fcp->isp_portid != lp->portid ||
1733: fcp->isp_loopid != lp->loopid ||
1734: fcp->isp_nodewwn != ISP_NODEWWN(isp) ||
1735: fcp->isp_portwwn != ISP_PORTWWN(isp)) {
1736: lp->valid = 0;
1737: count = fcp->isp_iid;
1738: (void) isp_async(isp, ISPASYNC_PROMENADE, &count);
1739: }
1740: }
1741: lp->loopid = fcp->isp_loopid;
1742: lp->portid = fcp->isp_portid;
1743: lp->node_wwn = ISP_NODEWWN(isp);
1744: lp->port_wwn = ISP_PORTWWN(isp);
1745: switch (isp->isp_role) {
1746: case ISP_ROLE_NONE:
1747: lp->roles = 0;
1748: break;
1749: case ISP_ROLE_TARGET:
1750: lp->roles = SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT;
1751: break;
1752: case ISP_ROLE_INITIATOR:
1753: lp->roles = SVC3_INI_ROLE >> SVC3_ROLE_SHIFT;
1754: break;
1755: case ISP_ROLE_BOTH:
1756: lp->roles = (SVC3_INI_ROLE|SVC3_TGT_ROLE) >> SVC3_ROLE_SHIFT;
1757: break;
1758: }
1759: lp->loggedin = lp->valid = 1;
1760: count = fcp->isp_iid;
1761: (void) isp_async(isp, ISPASYNC_PROMENADE, &count);
1762: return (0);
1763: }
1764:
1765: static char *
1766: isp2100_fw_statename(int state)
1767: {
1768: switch(state) {
1769: case FW_CONFIG_WAIT: return "Config Wait";
1770: case FW_WAIT_AL_PA: return "Waiting for AL_PA";
1771: case FW_WAIT_LOGIN: return "Wait Login";
1772: case FW_READY: return "Ready";
1773: case FW_LOSS_OF_SYNC: return "Loss Of Sync";
1774: case FW_ERROR: return "Error";
1775: case FW_REINIT: return "Re-Init";
1776: case FW_NON_PART: return "Nonparticipating";
1777: default: return "?????";
1778: }
1779: }
1780:
1781: /*
1782: * Synchronize our soft copy of the port database with what the f/w thinks
1783: * (with a view toward possibly for a specific target....)
1784: */
1785:
1786: static int
1787: isp_pdb_sync(struct ispsoftc *isp)
1788: {
1789: struct lportdb *lp;
1790: fcparam *fcp = isp->isp_param;
1791: isp_pdb_t pdb;
1792: int loopid, base, lim;
1793:
1794: /*
1795: * Make sure we're okay for doing this right now.
1796: */
1797: if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
1798: fcp->isp_loopstate != LOOP_FSCAN_DONE &&
1799: fcp->isp_loopstate != LOOP_LSCAN_DONE) {
1800: return (-1);
1801: }
1802:
1803: if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT ||
1804: fcp->isp_topo == TOPO_N_PORT) {
1805: if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
1806: if (isp_scan_loop(isp) != 0) {
1807: return (-1);
1808: }
1809: }
1810: }
1811: fcp->isp_loopstate = LOOP_SYNCING_PDB;
1812:
1813: /*
1814: * If we get this far, we've settled our differences with the f/w
1815: * (for local loop device) and we can say that the loop state is ready.
1816: */
1817:
1818: if (fcp->isp_topo == TOPO_NL_PORT) {
1819: fcp->loop_seen_once = 1;
1820: fcp->isp_loopstate = LOOP_READY;
1821: return (0);
1822: }
1823:
1824: /*
1825: * Find all Fabric Entities that didn't make it from one scan to the
1826: * next and let the world know they went away. Scan the whole database.
1827: */
1828: for (lp = &fcp->portdb[0]; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
1829: if (lp->was_fabric_dev && lp->fabric_dev == 0) {
1830: loopid = lp - fcp->portdb;
1831: lp->valid = 0; /* should already be set */
1832: (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
1833: MEMZERO((void *) lp, sizeof (*lp));
1834: continue;
1835: }
1836: lp->was_fabric_dev = lp->fabric_dev;
1837: }
1838:
1839: if (fcp->isp_topo == TOPO_FL_PORT)
1840: base = FC_SNS_ID+1;
1841: else
1842: base = 0;
1843:
1844: if (fcp->isp_topo == TOPO_N_PORT)
1845: lim = 1;
1846: else
1847: lim = MAX_FC_TARG;
1848:
1849: /*
1850: * Now log in any fabric devices that the outer layer has
1851: * left for us to see. This seems the most sane policy
1852: * for the moment.
1853: */
1854: for (lp = &fcp->portdb[base]; lp < &fcp->portdb[lim]; lp++) {
1855: u_int32_t portid;
1856: mbreg_t mbs;
1857:
1858: loopid = lp - fcp->portdb;
1859: if (loopid >= FL_PORT_ID && loopid <= FC_SNS_ID) {
1860: continue;
1861: }
1862:
1863: /*
1864: * Anything here?
1865: */
1866: if (lp->port_wwn == 0) {
1867: continue;
1868: }
1869:
1870: /*
1871: * Don't try to log into yourself.
1872: */
1873: if ((portid = lp->portid) == fcp->isp_portid) {
1874: continue;
1875: }
1876:
1877:
1878: /*
1879: * If we'd been logged in- see if we still are and we haven't
1880: * changed. If so, no need to log ourselves out, etc..
1881: *
1882: * Unfortunately, our charming Qlogic f/w has decided to
1883: * return a valid port database entry for a fabric device
1884: * that has, in fact, gone away. And it hangs trying to
1885: * log it out.
1886: */
1887: if (lp->loggedin && lp->force_logout == 0 &&
1888: isp_getpdb(isp, lp->loopid, &pdb) == 0) {
1889: int nrole;
1890: u_int64_t nwwnn, nwwpn;
1891: nwwnn =
1892: (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
1893: (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
1894: (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
1895: (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
1896: (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
1897: (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
1898: (((u_int64_t)pdb.pdb_nodename[6]) << 8) |
1899: (((u_int64_t)pdb.pdb_nodename[7]));
1900: nwwpn =
1901: (((u_int64_t)pdb.pdb_portname[0]) << 56) |
1902: (((u_int64_t)pdb.pdb_portname[1]) << 48) |
1903: (((u_int64_t)pdb.pdb_portname[2]) << 40) |
1904: (((u_int64_t)pdb.pdb_portname[3]) << 32) |
1905: (((u_int64_t)pdb.pdb_portname[4]) << 24) |
1906: (((u_int64_t)pdb.pdb_portname[5]) << 16) |
1907: (((u_int64_t)pdb.pdb_portname[6]) << 8) |
1908: (((u_int64_t)pdb.pdb_portname[7]));
1909: nrole = (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >>
1910: SVC3_ROLE_SHIFT;
1911: if (pdb.pdb_loopid == lp->loopid && lp->portid ==
1912: (u_int32_t) BITS2WORD(pdb.pdb_portid_bits) &&
1913: nwwnn == lp->node_wwn && nwwpn == lp->port_wwn &&
1914: lp->roles == nrole && lp->force_logout == 0) {
1915: lp->loggedin = lp->valid = 1;
1916: isp_prt(isp, ISP_LOGCONFIG, lretained,
1917: (int) (lp - fcp->portdb),
1918: (int) lp->loopid, lp->portid);
1919: continue;
1920: }
1921: }
1922:
1923: if (fcp->isp_fwstate != FW_READY ||
1924: fcp->isp_loopstate != LOOP_SYNCING_PDB) {
1925: return (-1);
1926: }
1927:
1928: /*
1929: * Force a logout if we were logged in.
1930: */
1931: if (lp->loggedin) {
1932: if (lp->force_logout ||
1933: isp_getpdb(isp, lp->loopid, &pdb) == 0) {
1934: mbs.param[0] = MBOX_FABRIC_LOGOUT;
1935: mbs.param[1] = lp->loopid << 8;
1936: mbs.param[2] = 0;
1937: mbs.param[3] = 0;
1938: isp_mboxcmd(isp, &mbs, MBLOGNONE);
1939: isp_prt(isp, ISP_LOGINFO, plogout,
1940: (int) (lp - fcp->portdb), lp->loopid,
1941: lp->portid);
1942: }
1943: lp->force_logout = lp->loggedin = 0;
1944: if (fcp->isp_fwstate != FW_READY ||
1945: fcp->isp_loopstate != LOOP_SYNCING_PDB) {
1946: return (-1);
1947: }
1948: }
1949:
1950: /*
1951: * And log in....
1952: */
1953: loopid = lp - fcp->portdb;
1954: lp->loopid = FL_PORT_ID;
1955: do {
1956: mbs.param[0] = MBOX_FABRIC_LOGIN;
1957: mbs.param[1] = loopid << 8;
1958: mbs.param[2] = portid >> 16;
1959: mbs.param[3] = portid & 0xffff;
1960: isp_mboxcmd(isp, &mbs, MBLOGALL & ~(MBOX_LOOP_ID_USED |
1961: MBOX_PORT_ID_USED | MBOX_COMMAND_ERROR));
1962: if (fcp->isp_fwstate != FW_READY ||
1963: fcp->isp_loopstate != LOOP_SYNCING_PDB) {
1964: return (-1);
1965: }
1966: switch (mbs.param[0]) {
1967: case MBOX_LOOP_ID_USED:
1968: /*
1969: * Try the next available loop id.
1970: */
1971: loopid++;
1972: break;
1973: case MBOX_PORT_ID_USED:
1974: /*
1975: * This port is already logged in.
1976: * Snaffle the loop id it's using if it's
1977: * nonzero, otherwise we're hosed.
1978: */
1979: if (mbs.param[1] != 0) {
1980: loopid = mbs.param[1];
1981: isp_prt(isp, ISP_LOGINFO, retained,
1982: loopid, (int) (lp - fcp->portdb),
1983: lp->portid);
1984: } else {
1985: loopid = MAX_FC_TARG;
1986: break;
1987: }
1988: /* FALLTHROUGH */
1989: case MBOX_COMMAND_COMPLETE:
1990: lp->loggedin = 1;
1991: lp->loopid = loopid;
1992: break;
1993: case MBOX_COMMAND_ERROR:
1994: isp_prt(isp, ISP_LOGINFO, plogierr,
1995: portid, mbs.param[1]);
1996: /* FALLTHROUGH */
1997: case MBOX_ALL_IDS_USED: /* We're outta IDs */
1998: default:
1999: loopid = MAX_FC_TARG;
2000: break;
2001: }
2002: } while (lp->loopid == FL_PORT_ID && loopid < MAX_FC_TARG);
2003:
2004: /*
2005: * If we get here and we haven't set a Loop ID,
2006: * we failed to log into this device.
2007: */
2008:
2009: if (lp->loopid == FL_PORT_ID) {
2010: lp->loopid = 0;
2011: continue;
2012: }
2013:
2014: /*
2015: * Make sure we can get the appropriate port information.
2016: */
2017: if (isp_getpdb(isp, lp->loopid, &pdb) != 0) {
2018: isp_prt(isp, ISP_LOGWARN, nopdb, lp->portid);
2019: goto dump_em;
2020: }
2021:
2022: if (fcp->isp_fwstate != FW_READY ||
2023: fcp->isp_loopstate != LOOP_SYNCING_PDB) {
2024: return (-1);
2025: }
2026:
2027: if (pdb.pdb_loopid != lp->loopid) {
2028: isp_prt(isp, ISP_LOGWARN, pdbmfail1,
2029: lp->portid, pdb.pdb_loopid);
2030: goto dump_em;
2031: }
2032:
2033: if (lp->portid != (u_int32_t) BITS2WORD(pdb.pdb_portid_bits)) {
2034: isp_prt(isp, ISP_LOGWARN, pdbmfail2,
2035: lp->portid, BITS2WORD(pdb.pdb_portid_bits));
2036: goto dump_em;
2037: }
2038:
2039: lp->roles =
2040: (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
2041: lp->node_wwn =
2042: (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
2043: (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
2044: (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
2045: (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
2046: (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
2047: (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
2048: (((u_int64_t)pdb.pdb_nodename[6]) << 8) |
2049: (((u_int64_t)pdb.pdb_nodename[7]));
2050: lp->port_wwn =
2051: (((u_int64_t)pdb.pdb_portname[0]) << 56) |
2052: (((u_int64_t)pdb.pdb_portname[1]) << 48) |
2053: (((u_int64_t)pdb.pdb_portname[2]) << 40) |
2054: (((u_int64_t)pdb.pdb_portname[3]) << 32) |
2055: (((u_int64_t)pdb.pdb_portname[4]) << 24) |
2056: (((u_int64_t)pdb.pdb_portname[5]) << 16) |
2057: (((u_int64_t)pdb.pdb_portname[6]) << 8) |
2058: (((u_int64_t)pdb.pdb_portname[7]));
2059: /*
2060: * Check to make sure this all makes sense.
2061: */
2062: if (lp->node_wwn && lp->port_wwn) {
2063: lp->valid = 1;
2064: loopid = lp - fcp->portdb;
2065: (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
2066: continue;
2067: }
2068: dump_em:
2069: lp->valid = 0;
2070: isp_prt(isp, ISP_LOGINFO,
2071: ldumped, loopid, lp->loopid, lp->portid);
2072: mbs.param[0] = MBOX_FABRIC_LOGOUT;
2073: mbs.param[1] = lp->loopid << 8;
2074: mbs.param[2] = 0;
2075: mbs.param[3] = 0;
2076: isp_mboxcmd(isp, &mbs, MBLOGNONE);
2077: if (fcp->isp_fwstate != FW_READY ||
2078: fcp->isp_loopstate != LOOP_SYNCING_PDB) {
2079: return (-1);
2080: }
2081: }
2082: /*
2083: * If we get here, we've for sure seen not only a valid loop
2084: * but know what is or isn't on it, so mark this for usage
2085: * in isp_start.
2086: */
2087: fcp->loop_seen_once = 1;
2088: fcp->isp_loopstate = LOOP_READY;
2089: return (0);
2090: }
2091:
2092: static int
2093: isp_scan_loop(struct ispsoftc *isp)
2094: {
2095: struct lportdb *lp;
2096: fcparam *fcp = isp->isp_param;
2097: isp_pdb_t pdb;
2098: int loopid, lim, hival;
2099:
2100: switch (fcp->isp_topo) {
2101: case TOPO_NL_PORT:
2102: hival = FL_PORT_ID;
2103: break;
2104: case TOPO_N_PORT:
2105: hival = 2;
2106: break;
2107: case TOPO_FL_PORT:
2108: hival = FC_PORT_ID;
2109: break;
2110: default:
2111: fcp->isp_loopstate = LOOP_LSCAN_DONE;
2112: return (0);
2113: }
2114: fcp->isp_loopstate = LOOP_SCANNING_LOOP;
2115:
2116: /*
2117: * make sure the temp port database is clean...
2118: */
2119: MEMZERO((void *)fcp->tport, sizeof (fcp->tport));
2120:
2121: /*
2122: * Run through the local loop ports and get port database info
2123: * for each loop ID.
2124: *
2125: * There's a somewhat unexplained situation where the f/w passes back
2126: * the wrong database entity- if that happens, just restart (up to
2127: * FL_PORT_ID times).
2128: */
2129: for (lim = loopid = 0; loopid < hival; loopid++) {
2130: lp = &fcp->tport[loopid];
2131:
2132: /*
2133: * Don't even try for ourselves...
2134: */
2135: if (loopid == fcp->isp_loopid)
2136: continue;
2137:
2138: lp->node_wwn = isp_get_portname(isp, loopid, 1);
2139: if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
2140: return (-1);
2141: if (lp->node_wwn == 0)
2142: continue;
2143: lp->port_wwn = isp_get_portname(isp, loopid, 0);
2144: if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
2145: return (-1);
2146: if (lp->port_wwn == 0) {
2147: lp->node_wwn = 0;
2148: continue;
2149: }
2150:
2151: /*
2152: * Get an entry....
2153: */
2154: if (isp_getpdb(isp, loopid, &pdb) != 0) {
2155: if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
2156: return (-1);
2157: continue;
2158: }
2159: if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2160: return (-1);
2161: }
2162:
2163: /*
2164: * If the returned database element doesn't match what we
2165: * asked for, restart the process entirely (up to a point...).
2166: */
2167: if (pdb.pdb_loopid != loopid) {
2168: loopid = 0;
2169: if (lim++ < hival) {
2170: continue;
2171: }
2172: isp_prt(isp, ISP_LOGWARN,
2173: "giving up on synchronizing the port database");
2174: return (-1);
2175: }
2176:
2177: /*
2178: * Save the pertinent info locally.
2179: */
2180: lp->node_wwn =
2181: (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
2182: (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
2183: (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
2184: (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
2185: (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
2186: (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
2187: (((u_int64_t)pdb.pdb_nodename[6]) << 8) |
2188: (((u_int64_t)pdb.pdb_nodename[7]));
2189: lp->port_wwn =
2190: (((u_int64_t)pdb.pdb_portname[0]) << 56) |
2191: (((u_int64_t)pdb.pdb_portname[1]) << 48) |
2192: (((u_int64_t)pdb.pdb_portname[2]) << 40) |
2193: (((u_int64_t)pdb.pdb_portname[3]) << 32) |
2194: (((u_int64_t)pdb.pdb_portname[4]) << 24) |
2195: (((u_int64_t)pdb.pdb_portname[5]) << 16) |
2196: (((u_int64_t)pdb.pdb_portname[6]) << 8) |
2197: (((u_int64_t)pdb.pdb_portname[7]));
2198: lp->roles =
2199: (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
2200: lp->portid = BITS2WORD(pdb.pdb_portid_bits);
2201: lp->loopid = pdb.pdb_loopid;
2202: }
2203:
2204: /*
2205: * Mark all of the permanent local loop database entries as invalid
2206: * (except our own entry).
2207: */
2208: for (loopid = 0; loopid < hival; loopid++) {
2209: if (loopid == fcp->isp_iid) {
2210: fcp->portdb[loopid].valid = 1;
2211: fcp->portdb[loopid].loopid = fcp->isp_loopid;
2212: continue;
2213: }
2214: fcp->portdb[loopid].valid = 0;
2215: }
2216:
2217: /*
2218: * Now merge our local copy of the port database into our saved copy.
2219: * Notify the outer layers of new devices arriving.
2220: */
2221: for (loopid = 0; loopid < hival; loopid++) {
2222: int i;
2223:
2224: /*
2225: * If we don't have a non-zero Port WWN, we're not here.
2226: */
2227: if (fcp->tport[loopid].port_wwn == 0) {
2228: continue;
2229: }
2230:
2231: /*
2232: * Skip ourselves.
2233: */
2234: if (loopid == fcp->isp_iid) {
2235: continue;
2236: }
2237:
2238: /*
2239: * For the purposes of deciding whether this is the
2240: * 'same' device or not, we only search for an identical
2241: * Port WWN. Node WWNs may or may not be the same as
2242: * the Port WWN, and there may be multiple different
2243: * Port WWNs with the same Node WWN. It would be chaos
2244: * to have multiple identical Port WWNs, so we don't
2245: * allow that.
2246: */
2247:
2248: for (i = 0; i < hival; i++) {
2249: int j;
2250: if (fcp->portdb[i].port_wwn == 0)
2251: continue;
2252: if (fcp->portdb[i].port_wwn !=
2253: fcp->tport[loopid].port_wwn)
2254: continue;
2255: /*
2256: * We found this WWN elsewhere- it's changed
2257: * loopids then. We don't change its actual
2258: * position in our cached port database- we
2259: * just change the actual loop ID we'd use.
2260: */
2261: if (fcp->portdb[i].loopid != loopid) {
2262: isp_prt(isp, ISP_LOGINFO, portshift, i,
2263: fcp->portdb[i].loopid,
2264: fcp->portdb[i].portid, loopid,
2265: fcp->tport[loopid].portid);
2266: }
2267: fcp->portdb[i].portid = fcp->tport[loopid].portid;
2268: fcp->portdb[i].loopid = loopid;
2269: fcp->portdb[i].valid = 1;
2270: fcp->portdb[i].roles = fcp->tport[loopid].roles;
2271:
2272: /*
2273: * Now make sure this Port WWN doesn't exist elsewhere
2274: * in the port database.
2275: */
2276: for (j = i+1; j < hival; j++) {
2277: if (fcp->portdb[i].port_wwn !=
2278: fcp->portdb[j].port_wwn) {
2279: continue;
2280: }
2281: isp_prt(isp, ISP_LOGWARN, portdup, j, i);
2282: /*
2283: * Invalidate the 'old' *and* 'new' ones.
2284: * This is really harsh and not quite right,
2285: * but if this happens, we really don't know
2286: * who is what at this point.
2287: */
2288: fcp->portdb[i].valid = 0;
2289: fcp->portdb[j].valid = 0;
2290: }
2291: break;
2292: }
2293:
2294: /*
2295: * If we didn't traverse the entire port database,
2296: * then we found (and remapped) an existing entry.
2297: * No need to notify anyone- go for the next one.
2298: */
2299: if (i < hival) {
2300: isp_prt(isp, ISP_LOGINFO, retained,
2301: fcp->portdb[i].loopid, i, fcp->portdb[i].portid);
2302: continue;
2303: }
2304:
2305: /*
2306: * We've not found this Port WWN anywhere. It's a new entry.
2307: * See if we can leave it where it is (with target == loopid).
2308: */
2309: if (fcp->portdb[loopid].port_wwn != 0) {
2310: for (lim = 0; lim < hival; lim++) {
2311: if (fcp->portdb[lim].port_wwn == 0)
2312: break;
2313: }
2314: /* "Cannot Happen" */
2315: if (lim == hival) {
2316: isp_prt(isp, ISP_LOGWARN, "Remap Overflow");
2317: continue;
2318: }
2319: i = lim;
2320: } else {
2321: i = loopid;
2322: }
2323:
2324: /*
2325: * NB: The actual loopid we use here is loopid- we may
2326: * in fact be at a completely different index (target).
2327: */
2328: fcp->portdb[i].loopid = loopid;
2329: fcp->portdb[i].port_wwn = fcp->tport[loopid].port_wwn;
2330: fcp->portdb[i].node_wwn = fcp->tport[loopid].node_wwn;
2331: fcp->portdb[i].roles = fcp->tport[loopid].roles;
2332: fcp->portdb[i].portid = fcp->tport[loopid].portid;
2333: fcp->portdb[i].valid = 1;
2334:
2335: /*
2336: * Tell the outside world we've arrived.
2337: */
2338: (void) isp_async(isp, ISPASYNC_PROMENADE, &i);
2339: }
2340:
2341: /*
2342: * Now find all previously used targets that are now invalid and
2343: * notify the outer layers that they're gone.
2344: */
2345: for (lp = &fcp->portdb[0]; lp < &fcp->portdb[hival]; lp++) {
2346: if (lp->valid || lp->port_wwn == 0) {
2347: continue;
2348: }
2349:
2350: /*
2351: * Tell the outside world we've gone
2352: * away and erase our pdb entry.
2353: *
2354: */
2355: loopid = lp - fcp->portdb;
2356: (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
2357: MEMZERO((void *) lp, sizeof (*lp));
2358: }
2359: fcp->isp_loopstate = LOOP_LSCAN_DONE;
2360: return (0);
2361: }
2362:
2363:
2364: static int
2365: isp_fabric_mbox_cmd(struct ispsoftc *isp, mbreg_t *mbp)
2366: {
2367: isp_mboxcmd(isp, mbp, MBLOGNONE);
2368: if (mbp->param[0] != MBOX_COMMAND_COMPLETE) {
2369: if (FCPARAM(isp)->isp_loopstate == LOOP_SCANNING_FABRIC) {
2370: FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
2371: }
2372: if (mbp->param[0] == MBOX_COMMAND_ERROR) {
2373: char tbuf[16];
2374: char *m;
2375: switch (mbp->param[1]) {
2376: case 1:
2377: m = "No Loop";
2378: break;
2379: case 2:
2380: m = "Failed to allocate IOCB buffer";
2381: break;
2382: case 3:
2383: m = "Failed to allocate XCB buffer";
2384: break;
2385: case 4:
2386: m = "timeout or transmit failed";
2387: break;
2388: case 5:
2389: m = "no fabric loop";
2390: break;
2391: case 6:
2392: m = "remote device not a target";
2393: break;
2394: default:
2395: SNPRINTF(tbuf, sizeof tbuf, "%x",
2396: mbp->param[1]);
2397: m = tbuf;
2398: break;
2399: }
2400: isp_prt(isp, ISP_LOGERR, "SNS Failed- %s", m);
2401: }
2402: return (-1);
2403: }
2404:
2405: if (FCPARAM(isp)->isp_fwstate != FW_READY ||
2406: FCPARAM(isp)->isp_loopstate < LOOP_SCANNING_FABRIC) {
2407: return (-1);
2408: }
2409: return(0);
2410: }
2411:
2412: #ifdef ISP_USE_GA_NXT
2413: static int
2414: isp_scan_fabric(struct ispsoftc *isp, int ftype)
2415: {
2416: fcparam *fcp = isp->isp_param;
2417: u_int32_t portid, first_portid, last_portid;
2418: int hicap, last_port_same;
2419:
2420: if (fcp->isp_onfabric == 0) {
2421: fcp->isp_loopstate = LOOP_FSCAN_DONE;
2422: return (0);
2423: }
2424:
2425: FC_SCRATCH_ACQUIRE(isp);
2426:
2427: /*
2428: * Since Port IDs are 24 bits, we can check against having seen
2429: * anything yet with this value.
2430: */
2431: last_port_same = 0;
2432: last_portid = 0xffffffff; /* not a port */
2433: first_portid = portid = fcp->isp_portid;
2434: fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
2435:
2436: for (hicap = 0; hicap < GA_NXT_MAX; hicap++) {
2437: mbreg_t mbs;
2438: sns_screq_t *rq;
2439: sns_ga_nxt_rsp_t *rs0, *rs1;
2440: struct lportdb lcl;
2441: u_int8_t sc[SNS_GA_NXT_RESP_SIZE];
2442:
2443: rq = (sns_screq_t *)sc;
2444: MEMZERO((void *) rq, SNS_GA_NXT_REQ_SIZE);
2445: rq->snscb_rblen = SNS_GA_NXT_RESP_SIZE >> 1;
2446: rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+0x100);
2447: rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+0x100);
2448: rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+0x100);
2449: rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+0x100);
2450: rq->snscb_sblen = 6;
2451: rq->snscb_data[0] = SNS_GA_NXT;
2452: rq->snscb_data[4] = portid & 0xffff;
2453: rq->snscb_data[5] = (portid >> 16) & 0xff;
2454: isp_put_sns_request(isp, rq, (sns_screq_t *) fcp->isp_scratch);
2455: MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GA_NXT_REQ_SIZE);
2456: mbs.param[0] = MBOX_SEND_SNS;
2457: mbs.param[1] = SNS_GA_NXT_REQ_SIZE >> 1;
2458: mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2459: mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2460: /*
2461: * Leave 4 and 5 alone
2462: */
2463: mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2464: mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2465: if (isp_fabric_mbox_cmd(isp, &mbs)) {
2466: if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2467: fcp->isp_loopstate = LOOP_PDB_RCVD;
2468: }
2469: FC_SCRATCH_RELEASE(isp);
2470: return (-1);
2471: }
2472: MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GA_NXT_RESP_SIZE);
2473: rs1 = (sns_ga_nxt_rsp_t *) sc;
2474: rs0 = (sns_ga_nxt_rsp_t *) ((u_int8_t *)fcp->isp_scratch+0x100);
2475: isp_get_ga_nxt_response(isp, rs0, rs1);
2476: if (rs1->snscb_cthdr.ct_response != FS_ACC) {
2477: int level;
2478: if (rs1->snscb_cthdr.ct_reason == 9 &&
2479: rs1->snscb_cthdr.ct_explanation == 7)
2480: level = ISP_LOGDEBUG0;
2481: else
2482: level = ISP_LOGWARN;
2483: isp_prt(isp, level, swrej, "GA_NXT",
2484: rs1->snscb_cthdr.ct_reason,
2485: rs1->snscb_cthdr.ct_explanation, portid);
2486: FC_SCRATCH_RELEASE(isp);
2487: fcp->isp_loopstate = LOOP_FSCAN_DONE;
2488: return (0);
2489: }
2490: portid =
2491: (((u_int32_t) rs1->snscb_port_id[0]) << 16) |
2492: (((u_int32_t) rs1->snscb_port_id[1]) << 8) |
2493: (((u_int32_t) rs1->snscb_port_id[2]));
2494:
2495: /*
2496: * XXX: We should check to make sure that this entry
2497: * XXX: supports the type(s) we are interested in.
2498: */
2499: /*
2500: * Okay, we now have information about a fabric object.
2501: * If it is the type we're interested in, tell the outer layers
2502: * about it. The outer layer needs to know: Port ID, WWNN,
2503: * WWPN, FC4 type, and port type.
2504: *
2505: * The lportdb structure is adequate for this.
2506: */
2507: MEMZERO(&lcl, sizeof (lcl));
2508: lcl.port_type = rs1->snscb_port_type;
2509: lcl.fc4_type = ftype;
2510: lcl.portid = portid;
2511: lcl.node_wwn =
2512: (((u_int64_t)rs1->snscb_nodename[0]) << 56) |
2513: (((u_int64_t)rs1->snscb_nodename[1]) << 48) |
2514: (((u_int64_t)rs1->snscb_nodename[2]) << 40) |
2515: (((u_int64_t)rs1->snscb_nodename[3]) << 32) |
2516: (((u_int64_t)rs1->snscb_nodename[4]) << 24) |
2517: (((u_int64_t)rs1->snscb_nodename[5]) << 16) |
2518: (((u_int64_t)rs1->snscb_nodename[6]) << 8) |
2519: (((u_int64_t)rs1->snscb_nodename[7]));
2520: lcl.port_wwn =
2521: (((u_int64_t)rs1->snscb_portname[0]) << 56) |
2522: (((u_int64_t)rs1->snscb_portname[1]) << 48) |
2523: (((u_int64_t)rs1->snscb_portname[2]) << 40) |
2524: (((u_int64_t)rs1->snscb_portname[3]) << 32) |
2525: (((u_int64_t)rs1->snscb_portname[4]) << 24) |
2526: (((u_int64_t)rs1->snscb_portname[5]) << 16) |
2527: (((u_int64_t)rs1->snscb_portname[6]) << 8) |
2528: (((u_int64_t)rs1->snscb_portname[7]));
2529:
2530: /*
2531: * Does this fabric object support the type we want?
2532: * If not, skip it.
2533: */
2534: if (rs1->snscb_fc4_types[ftype >> 5] & (1 << (ftype & 0x1f))) {
2535: if (first_portid == portid) {
2536: lcl.last_fabric_dev = 1;
2537: } else {
2538: lcl.last_fabric_dev = 0;
2539: }
2540: (void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
2541: } else {
2542: isp_prt(isp, ISP_LOGDEBUG0,
2543: "PortID 0x%x doesn't support FC4 type 0x%x",
2544: portid, ftype);
2545: }
2546: if (first_portid == portid) {
2547: fcp->isp_loopstate = LOOP_FSCAN_DONE;
2548: FC_SCRATCH_RELEASE(isp);
2549: return (0);
2550: }
2551: if (portid == last_portid) {
2552: if (last_port_same++ > 20) {
2553: isp_prt(isp, ISP_LOGWARN,
2554: "tangled fabric database detected");
2555: break;
2556: }
2557: } else {
2558: last_port_same = 0 ;
2559: last_portid = portid;
2560: }
2561: }
2562: FC_SCRATCH_RELEASE(isp);
2563: if (hicap >= GA_NXT_MAX) {
2564: isp_prt(isp, ISP_LOGWARN, "fabric too big (> %d)", GA_NXT_MAX);
2565: }
2566: fcp->isp_loopstate = LOOP_FSCAN_DONE;
2567: return (0);
2568: }
2569: #else
2570: #define GIDLEN ((ISP2100_SCRLEN >> 1) + 16)
2571: #define NGENT ((GIDLEN - 16) >> 2)
2572:
2573: #define IGPOFF (ISP2100_SCRLEN - GIDLEN)
2574: #define GXOFF (256)
2575:
2576: static int
2577: isp_scan_fabric(struct ispsoftc *isp, int ftype)
2578: {
2579: fcparam *fcp = FCPARAM(isp);
2580: mbreg_t mbs;
2581: int i;
2582: sns_gid_ft_req_t *rq;
2583: sns_gid_ft_rsp_t *rs0, *rs1;
2584:
2585: if (fcp->isp_onfabric == 0) {
2586: fcp->isp_loopstate = LOOP_FSCAN_DONE;
2587: return (0);
2588: }
2589:
2590: FC_SCRATCH_ACQUIRE(isp);
2591: fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
2592:
2593: rq = (sns_gid_ft_req_t *)fcp->tport;
2594: MEMZERO((void *) rq, SNS_GID_FT_REQ_SIZE);
2595: rq->snscb_rblen = GIDLEN >> 1;
2596: rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+IGPOFF);
2597: rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+IGPOFF);
2598: rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+IGPOFF);
2599: rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+IGPOFF);
2600: rq->snscb_sblen = 6;
2601: rq->snscb_cmd = SNS_GID_FT;
2602: rq->snscb_mword_div_2 = NGENT;
2603: rq->snscb_fc4_type = ftype;
2604: isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *) fcp->isp_scratch);
2605: MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
2606: mbs.param[0] = MBOX_SEND_SNS;
2607: mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
2608: mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2609: mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2610:
2611: /*
2612: * Leave 4 and 5 alone
2613: */
2614: mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2615: mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2616: if (isp_fabric_mbox_cmd(isp, &mbs)) {
2617: if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2618: fcp->isp_loopstate = LOOP_PDB_RCVD;
2619: }
2620: FC_SCRATCH_RELEASE(isp);
2621: return (-1);
2622: }
2623: if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2624: FC_SCRATCH_RELEASE(isp);
2625: return (-1);
2626: }
2627: MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
2628: rs1 = (sns_gid_ft_rsp_t *) fcp->tport;
2629: rs0 = (sns_gid_ft_rsp_t *) ((u_int8_t *)fcp->isp_scratch+IGPOFF);
2630: isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
2631: if (rs1->snscb_cthdr.ct_response != FS_ACC) {
2632: int level;
2633: if (rs1->snscb_cthdr.ct_reason == 9 &&
2634: rs1->snscb_cthdr.ct_explanation == 7)
2635: level = ISP_LOGDEBUG0;
2636: else
2637: level = ISP_LOGWARN;
2638: isp_prt(isp, level, swrej, "GID_FT",
2639: rs1->snscb_cthdr.ct_reason,
2640: rs1->snscb_cthdr.ct_explanation, 0);
2641: FC_SCRATCH_RELEASE(isp);
2642: fcp->isp_loopstate = LOOP_FSCAN_DONE;
2643: return (0);
2644: }
2645:
2646: /*
2647: * Okay, we now have a list of Port IDs for this class of device.
2648: * Go through the list and for each one get the WWPN/WWNN for it
2649: * and tell the outer layers about it. The outer layer needs to
2650: * know: Port ID, WWNN, WWPN, FC4 type, and (possibly) port type.
2651: *
2652: * The lportdb structure is adequate for this.
2653: */
2654: i = -1;
2655: do {
2656: sns_gxn_id_req_t grqbuf, *gq = &grqbuf;
2657: sns_gxn_id_rsp_t *gs0, grsbuf, *gs1 = &grsbuf;
2658: struct lportdb lcl;
2659: #if 0
2660: sns_gff_id_rsp_t *fs0, ffsbuf, *fs1 = &ffsbuf;
2661: #endif
2662:
2663: i++;
2664: MEMZERO(&lcl, sizeof (lcl));
2665: lcl.fc4_type = ftype;
2666: lcl.portid =
2667: (((u_int32_t) rs1->snscb_ports[i].portid[0]) << 16) |
2668: (((u_int32_t) rs1->snscb_ports[i].portid[1]) << 8) |
2669: (((u_int32_t) rs1->snscb_ports[i].portid[2]));
2670:
2671: MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
2672: gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
2673: gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
2674: gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
2675: gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
2676: gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
2677: gq->snscb_sblen = 6;
2678: gq->snscb_cmd = SNS_GPN_ID;
2679: gq->snscb_portid = lcl.portid;
2680: isp_put_gxn_id_request(isp, gq,
2681: (sns_gxn_id_req_t *) fcp->isp_scratch);
2682: MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
2683: mbs.param[0] = MBOX_SEND_SNS;
2684: mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
2685: mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2686: mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2687: /*
2688: * Leave 4 and 5 alone
2689: */
2690: mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2691: mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2692: if (isp_fabric_mbox_cmd(isp, &mbs)) {
2693: if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2694: fcp->isp_loopstate = LOOP_PDB_RCVD;
2695: }
2696: FC_SCRATCH_RELEASE(isp);
2697: return (-1);
2698: }
2699: if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2700: FC_SCRATCH_RELEASE(isp);
2701: return (-1);
2702: }
2703: MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
2704: gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
2705: isp_get_gxn_id_response(isp, gs0, gs1);
2706: if (gs1->snscb_cthdr.ct_response != FS_ACC) {
2707: isp_prt(isp, ISP_LOGWARN, swrej, "GPN_ID",
2708: gs1->snscb_cthdr.ct_reason,
2709: gs1->snscb_cthdr.ct_explanation, lcl.portid);
2710: if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2711: FC_SCRATCH_RELEASE(isp);
2712: return (-1);
2713: }
2714: continue;
2715: }
2716: lcl.port_wwn =
2717: (((u_int64_t)gs1->snscb_wwn[0]) << 56) |
2718: (((u_int64_t)gs1->snscb_wwn[1]) << 48) |
2719: (((u_int64_t)gs1->snscb_wwn[2]) << 40) |
2720: (((u_int64_t)gs1->snscb_wwn[3]) << 32) |
2721: (((u_int64_t)gs1->snscb_wwn[4]) << 24) |
2722: (((u_int64_t)gs1->snscb_wwn[5]) << 16) |
2723: (((u_int64_t)gs1->snscb_wwn[6]) << 8) |
2724: (((u_int64_t)gs1->snscb_wwn[7]));
2725:
2726: MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
2727: gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
2728: gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
2729: gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
2730: gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
2731: gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
2732: gq->snscb_sblen = 6;
2733: gq->snscb_cmd = SNS_GNN_ID;
2734: gq->snscb_portid = lcl.portid;
2735: isp_put_gxn_id_request(isp, gq,
2736: (sns_gxn_id_req_t *) fcp->isp_scratch);
2737: MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
2738: mbs.param[0] = MBOX_SEND_SNS;
2739: mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
2740: mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2741: mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2742: /*
2743: * Leave 4 and 5 alone
2744: */
2745: mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2746: mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2747: if (isp_fabric_mbox_cmd(isp, &mbs)) {
2748: if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2749: fcp->isp_loopstate = LOOP_PDB_RCVD;
2750: }
2751: FC_SCRATCH_RELEASE(isp);
2752: return (-1);
2753: }
2754: if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2755: FC_SCRATCH_RELEASE(isp);
2756: return (-1);
2757: }
2758: MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
2759: gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
2760: isp_get_gxn_id_response(isp, gs0, gs1);
2761: if (gs1->snscb_cthdr.ct_response != FS_ACC) {
2762: isp_prt(isp, ISP_LOGWARN, swrej, "GNN_ID",
2763: gs1->snscb_cthdr.ct_reason,
2764: gs1->snscb_cthdr.ct_explanation, lcl.portid);
2765: if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2766: FC_SCRATCH_RELEASE(isp);
2767: return (-1);
2768: }
2769: continue;
2770: }
2771: lcl.node_wwn =
2772: (((u_int64_t)gs1->snscb_wwn[0]) << 56) |
2773: (((u_int64_t)gs1->snscb_wwn[1]) << 48) |
2774: (((u_int64_t)gs1->snscb_wwn[2]) << 40) |
2775: (((u_int64_t)gs1->snscb_wwn[3]) << 32) |
2776: (((u_int64_t)gs1->snscb_wwn[4]) << 24) |
2777: (((u_int64_t)gs1->snscb_wwn[5]) << 16) |
2778: (((u_int64_t)gs1->snscb_wwn[6]) << 8) |
2779: (((u_int64_t)gs1->snscb_wwn[7]));
2780:
2781: /*
2782: * The QLogic f/w is bouncing this with a parameter error.
2783: */
2784: #if 0
2785: /*
2786: * Try and get FC4 Features (FC-GS-3 only).
2787: * We can use the sns_gxn_id_req_t for this request.
2788: */
2789: MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
2790: gq->snscb_rblen = SNS_GFF_ID_RESP_SIZE >> 1;
2791: gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
2792: gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
2793: gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
2794: gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
2795: gq->snscb_sblen = 6;
2796: gq->snscb_cmd = SNS_GFF_ID;
2797: gq->snscb_portid = lcl.portid;
2798: isp_put_gxn_id_request(isp, gq,
2799: (sns_gxn_id_req_t *) fcp->isp_scratch);
2800: MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
2801: mbs.param[0] = MBOX_SEND_SNS;
2802: mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
2803: mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2804: mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2805: /*
2806: * Leave 4 and 5 alone
2807: */
2808: mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2809: mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2810: if (isp_fabric_mbox_cmd(isp, &mbs)) {
2811: if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2812: fcp->isp_loopstate = LOOP_PDB_RCVD;
2813: }
2814: FC_SCRATCH_RELEASE(isp);
2815: return (-1);
2816: }
2817: if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2818: FC_SCRATCH_RELEASE(isp);
2819: return (-1);
2820: }
2821: MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GFF_ID_RESP_SIZE);
2822: fs0 = (sns_gff_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
2823: isp_get_gff_id_response(isp, fs0, fs1);
2824: if (fs1->snscb_cthdr.ct_response != FS_ACC) {
2825: isp_prt(isp, /* ISP_LOGDEBUG0 */ ISP_LOGWARN,
2826: swrej, "GFF_ID",
2827: fs1->snscb_cthdr.ct_reason,
2828: fs1->snscb_cthdr.ct_explanation, lcl.portid);
2829: if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2830: FC_SCRATCH_RELEASE(isp);
2831: return (-1);
2832: }
2833: } else {
2834: int index = (ftype >> 3);
2835: int bshft = (ftype & 0x7) * 4;
2836: int fc4_fval =
2837: (fs1->snscb_fc4_features[index] >> bshft) & 0xf;
2838: if (fc4_fval & 0x1) {
2839: lcl.roles |=
2840: (SVC3_INI_ROLE >> SVC3_ROLE_SHIFT);
2841: }
2842: if (fc4_fval & 0x2) {
2843: lcl.roles |=
2844: (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
2845: }
2846: }
2847: #endif
2848:
2849: /*
2850: * If we really want to know what kind of port type this is,
2851: * we have to run another CT command. Otherwise, we'll leave
2852: * it as undefined.
2853: *
2854: lcl.port_type = 0;
2855: */
2856: if (rs1->snscb_ports[i].control & 0x80) {
2857: lcl.last_fabric_dev = 1;
2858: } else {
2859: lcl.last_fabric_dev = 0;
2860: }
2861: (void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
2862:
2863: } while ((rs1->snscb_ports[i].control & 0x80) == 0 && i < NGENT-1);
2864:
2865: /*
2866: * If we're not at the last entry, our list isn't big enough.
2867: */
2868: if ((rs1->snscb_ports[i].control & 0x80) == 0) {
2869: isp_prt(isp, ISP_LOGWARN, "fabric too big for scratch area");
2870: }
2871:
2872: FC_SCRATCH_RELEASE(isp);
2873: fcp->isp_loopstate = LOOP_FSCAN_DONE;
2874: return (0);
2875: }
2876: #endif
2877:
2878: static void
2879: isp_register_fc4_type(struct ispsoftc *isp)
2880: {
2881: fcparam *fcp = isp->isp_param;
2882: u_int8_t local[SNS_RFT_ID_REQ_SIZE];
2883: sns_screq_t *reqp = (sns_screq_t *) local;
2884: mbreg_t mbs;
2885:
2886: MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
2887: reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
2888: reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
2889: reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
2890: reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
2891: reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
2892: reqp->snscb_sblen = 22;
2893: reqp->snscb_data[0] = SNS_RFT_ID;
2894: reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
2895: reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
2896: reqp->snscb_data[6] = (1 << FC4_SCSI);
2897: #if 0
2898: reqp->snscb_data[6] |= (1 << FC4_IP); /* ISO/IEC 8802-2 LLC/SNAP */
2899: #endif
2900: FC_SCRATCH_ACQUIRE(isp);
2901: isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
2902: mbs.param[0] = MBOX_SEND_SNS;
2903: mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
2904: mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2905: mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2906: /*
2907: * Leave 4 and 5 alone
2908: */
2909: mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2910: mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2911: isp_mboxcmd(isp, &mbs, MBLOGALL);
2912: FC_SCRATCH_RELEASE(isp);
2913: if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
2914: isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 types succeeded");
2915: }
2916: }
2917:
2918: /*
2919: * Start a command. Locking is assumed done in the caller.
2920: */
2921:
2922: int
2923: isp_start(XS_T *xs)
2924: {
2925: struct ispsoftc *isp;
2926: u_int16_t nxti, optr, handle;
2927: u_int8_t local[QENTRY_LEN];
2928: ispreq_t *reqp, *qep;
2929: int target, i;
2930:
2931: XS_INITERR(xs);
2932: isp = XS_ISP(xs);
2933:
2934: /*
2935: * Check to make sure we're supporting initiator role.
2936: */
2937: if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
2938: XS_SETERR(xs, HBA_SELTIMEOUT);
2939: return (CMD_COMPLETE);
2940: }
2941:
2942: /*
2943: * Now make sure we're running.
2944: */
2945:
2946: if (isp->isp_state != ISP_RUNSTATE) {
2947: isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
2948: XS_SETERR(xs, HBA_BOTCH);
2949: return (CMD_COMPLETE);
2950: }
2951:
2952: /*
2953: * Check command CDB length, etc.. We really are limited to 16 bytes
2954: * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
2955: * but probably only if we're running fairly new firmware (we'll
2956: * let the old f/w choke on an extended command queue entry).
2957: */
2958:
2959: if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
2960: isp_prt(isp, ISP_LOGERR,
2961: "unsupported cdb length (%d, CDB[0]=0x%x)",
2962: XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
2963: XS_SETERR(xs, HBA_BOTCH);
2964: return (CMD_COMPLETE);
2965: }
2966:
2967: /*
2968: * Check to see whether we have good firmware state still or
2969: * need to refresh our port database for this target.
2970: */
2971: target = XS_TGT(xs);
2972: if (IS_FC(isp)) {
2973: fcparam *fcp = isp->isp_param;
2974: struct lportdb *lp;
2975: #ifdef HANDLE_LOOPSTATE_IN_OUTER_LAYERS
2976: if (fcp->isp_fwstate != FW_READY ||
2977: fcp->isp_loopstate != LOOP_READY) {
2978: return (CMD_RQLATER);
2979: }
2980:
2981: /*
2982: * If we're not on a Fabric, we can't have a target
2983: * above FL_PORT_ID-1.
2984: *
2985: * If we're on a fabric and *not* connected as an F-port,
2986: * we can't have a target less than FC_SNS_ID+1. This
2987: * keeps us from having to sort out the difference between
2988: * local public loop devices and those which we might get
2989: * from a switch's database.
2990: */
2991: if (fcp->isp_onfabric == 0) {
2992: if (target >= FL_PORT_ID) {
2993: XS_SETERR(xs, HBA_SELTIMEOUT);
2994: return (CMD_COMPLETE);
2995: }
2996: } else {
2997: if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
2998: XS_SETERR(xs, HBA_SELTIMEOUT);
2999: return (CMD_COMPLETE);
3000: }
3001: /*
3002: * We used to exclude having local loop ports
3003: * at the same time that we have fabric ports.
3004: * That is, we used to exclude having ports
3005: * at < FL_PORT_ID if we're FL-port.
3006: *
3007: * That's wrong. The only thing that could be
3008: * dicey is if the switch you're connected to
3009: * has these local loop ports appear on the
3010: * fabric and we somehow attach them twice.
3011: */
3012: }
3013: #else
3014: /*
3015: * Check for f/w being in ready state. If the f/w
3016: * isn't in ready state, then we don't know our
3017: * loop ID and the f/w hasn't completed logging
3018: * into all targets on the loop. If this is the
3019: * case, then bounce the command. We pretend this is
3020: * a SELECTION TIMEOUT error if we've never gone to
3021: * FW_READY state at all- in this case we may not
3022: * be hooked to a loop at all and we shouldn't hang
3023: * the machine for this. Otherwise, defer this command
3024: * until later.
3025: */
3026: if (fcp->isp_fwstate != FW_READY) {
3027: /*
3028: * Give ourselves at most a 250ms delay.
3029: */
3030: if (isp_fclink_test(isp, 250000)) {
3031: XS_SETERR(xs, HBA_SELTIMEOUT);
3032: if (fcp->loop_seen_once) {
3033: return (CMD_RQLATER);
3034: } else {
3035: return (CMD_COMPLETE);
3036: }
3037: }
3038: }
3039:
3040: /*
3041: * If we're not on a Fabric, we can't have a target
3042: * above FL_PORT_ID-1.
3043: *
3044: * If we're on a fabric and *not* connected as an F-port,
3045: * we can't have a target less than FC_SNS_ID+1. This
3046: * keeps us from having to sort out the difference between
3047: * local public loop devices and those which we might get
3048: * from a switch's database.
3049: */
3050: if (fcp->isp_onfabric == 0) {
3051: if (target >= FL_PORT_ID) {
3052: XS_SETERR(xs, HBA_SELTIMEOUT);
3053: return (CMD_COMPLETE);
3054: }
3055: } else {
3056: if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
3057: XS_SETERR(xs, HBA_SELTIMEOUT);
3058: return (CMD_COMPLETE);
3059: }
3060: if (fcp->isp_topo != TOPO_F_PORT &&
3061: target < FL_PORT_ID) {
3062: XS_SETERR(xs, HBA_SELTIMEOUT);
3063: return (CMD_COMPLETE);
3064: }
3065: }
3066:
3067: /*
3068: * If our loop state is such that we haven't yet received
3069: * a "Port Database Changed" notification (after a LIP or
3070: * a Loop Reset or firmware initialization), then defer
3071: * sending commands for a little while, but only if we've
3072: * seen a valid loop at one point (otherwise we can get
3073: * stuck at initialization time).
3074: */
3075: if (fcp->isp_loopstate < LOOP_PDB_RCVD) {
3076: XS_SETERR(xs, HBA_SELTIMEOUT);
3077: if (fcp->loop_seen_once) {
3078: return (CMD_RQLATER);
3079: } else {
3080: return (CMD_COMPLETE);
3081: }
3082: }
3083:
3084: /*
3085: * If we're in the middle of loop or fabric scanning
3086: * or merging the port databases, retry this command later.
3087: */
3088: if (fcp->isp_loopstate == LOOP_SCANNING_FABRIC ||
3089: fcp->isp_loopstate == LOOP_SCANNING_LOOP ||
3090: fcp->isp_loopstate == LOOP_SYNCING_PDB) {
3091: return (CMD_RQLATER);
3092: }
3093:
3094: /*
3095: * If our loop state is now such that we've just now
3096: * received a Port Database Change notification, then
3097: * we have to go off and (re)scan the fabric. We back
3098: * out and try again later if this doesn't work.
3099: */
3100: if (fcp->isp_loopstate == LOOP_PDB_RCVD && fcp->isp_onfabric) {
3101: if (isp_scan_fabric(isp, FC4_SCSI)) {
3102: return (CMD_RQLATER);
3103: }
3104: if (fcp->isp_fwstate != FW_READY ||
3105: fcp->isp_loopstate < LOOP_FSCAN_DONE) {
3106: return (CMD_RQLATER);
3107: }
3108: }
3109:
3110: /*
3111: * If our loop state is now such that we've just now
3112: * received a Port Database Change notification, then
3113: * we have to go off and (re)synchronize our port
3114: * database.
3115: */
3116: if (fcp->isp_loopstate < LOOP_READY) {
3117: if (isp_pdb_sync(isp)) {
3118: return (CMD_RQLATER);
3119: }
3120: if (fcp->isp_fwstate != FW_READY ||
3121: fcp->isp_loopstate != LOOP_READY) {
3122: return (CMD_RQLATER);
3123: }
3124: }
3125:
3126: /*
3127: * XXX: Here's were we would cancel any loop_dead flag
3128: * XXX: also cancel in dead_loop timeout that's running
3129: */
3130: #endif
3131:
3132: /*
3133: * Now check whether we should even think about pursuing this.
3134: */
3135: lp = &fcp->portdb[target];
3136: if (lp->valid == 0) {
3137: XS_SETERR(xs, HBA_SELTIMEOUT);
3138: return (CMD_COMPLETE);
3139: }
3140: if ((lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) == 0) {
3141: isp_prt(isp, ISP_LOGDEBUG2,
3142: "Target %d does not have target service", target);
3143: XS_SETERR(xs, HBA_SELTIMEOUT);
3144: return (CMD_COMPLETE);
3145: }
3146: /*
3147: * Now turn target into what the actual Loop ID is.
3148: */
3149: target = lp->loopid;
3150: xs->sc_link->node_wwn = lp->node_wwn;
3151: xs->sc_link->port_wwn = lp->port_wwn;
3152:
3153: }
3154:
3155: /*
3156: * Next check to see if any HBA or Device
3157: * parameters need to be updated.
3158: */
3159: if (isp->isp_update != 0) {
3160: isp_update(isp);
3161: }
3162:
3163: if (isp_getrqentry(isp, &nxti, &optr, (void *)&qep)) {
3164: isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
3165: XS_SETERR(xs, HBA_BOTCH);
3166: return (CMD_EAGAIN);
3167: }
3168:
3169: /*
3170: * Now see if we need to synchronize the ISP with respect to anything.
3171: * We do dual duty here (cough) for synchronizing for busses other
3172: * than which we got here to send a command to.
3173: */
3174: reqp = (ispreq_t *) local;
3175: if (isp->isp_sendmarker) {
3176: u_int8_t n = (IS_DUALBUS(isp)? 2: 1);
3177: /*
3178: * Check ports to send markers for...
3179: */
3180: for (i = 0; i < n; i++) {
3181: if ((isp->isp_sendmarker & (1 << i)) == 0) {
3182: continue;
3183: }
3184: MEMZERO((void *) reqp, QENTRY_LEN);
3185: reqp->req_header.rqs_entry_count = 1;
3186: reqp->req_header.rqs_entry_type = RQSTYPE_MARKER;
3187: reqp->req_modifier = SYNC_ALL;
3188: reqp->req_target = i << 7; /* insert bus number */
3189: isp_put_request(isp, reqp, qep);
3190: ISP_ADD_REQUEST(isp, nxti);
3191: isp->isp_sendmarker &= ~(1 << i);
3192: if (isp_getrqentry(isp, &nxti, &optr, (void *) &qep)) {
3193: isp_prt(isp, ISP_LOGDEBUG0,
3194: "Request Queue Overflow+");
3195: XS_SETERR(xs, HBA_BOTCH);
3196: return (CMD_EAGAIN);
3197: }
3198: }
3199: }
3200:
3201: MEMZERO((void *)reqp, QENTRY_LEN);
3202: reqp->req_header.rqs_entry_count = 1;
3203: if (IS_FC(isp)) {
3204: reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
3205: } else {
3206: if (XS_CDBLEN(xs) > 12)
3207: reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
3208: else
3209: reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
3210: }
3211: /* reqp->req_header.rqs_flags = 0; */
3212: /* reqp->req_header.rqs_seqno = 0; */
3213: if (IS_FC(isp)) {
3214: /*
3215: * See comment in isp_intr
3216: */
3217: /* XS_RESID(xs) = 0; */
3218:
3219: /*
3220: * Fibre Channel always requires some kind of tag.
3221: * The Qlogic drivers seem be happy not to use a tag,
3222: * but this breaks for some devices (IBM drives).
3223: */
3224: if (XS_TAG_P(xs)) {
3225: ((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
3226: } else {
3227: /*
3228: * If we don't know what tag to use, use HEAD OF QUEUE
3229: * for Request Sense or Simple.
3230: */
3231: if (XS_CDBP(xs)[0] == 0x3) /* REQUEST SENSE */
3232: ((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
3233: else
3234: ((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
3235: }
3236: } else {
3237: sdparam *sdp = (sdparam *)isp->isp_param;
3238: sdp += XS_CHANNEL(xs);
3239: if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) &&
3240: XS_TAG_P(xs)) {
3241: reqp->req_flags = XS_TAG_TYPE(xs);
3242: }
3243: }
3244: reqp->req_target = target | (XS_CHANNEL(xs) << 7);
3245: if (IS_SCSI(isp)) {
3246: reqp->req_lun_trn = XS_LUN(xs);
3247: reqp->req_cdblen = XS_CDBLEN(xs);
3248: } else {
3249: if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)
3250: ((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
3251: else
3252: ((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
3253: }
3254: MEMCPY(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs));
3255:
3256: reqp->req_time = XS_TIME(xs) / 1000;
3257: if (reqp->req_time == 0 && XS_TIME(xs)) {
3258: reqp->req_time = 1;
3259: }
3260:
3261: if (isp_save_xs(isp, xs, &handle)) {
3262: isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
3263: XS_SETERR(xs, HBA_BOTCH);
3264: return (CMD_EAGAIN);
3265: }
3266: reqp->req_handle = handle;
3267:
3268: /*
3269: * Set up DMA and/or do any bus swizzling of the request entry
3270: * so that the Qlogic F/W understands what is being asked of it.
3271: */
3272: i = ISP_DMASETUP(isp, xs, reqp, &nxti, optr);
3273: if (i != CMD_QUEUED) {
3274: isp_destroy_handle(isp, handle);
3275: /*
3276: * dmasetup sets actual error in packet, and
3277: * return what we were given to return.
3278: */
3279: return (i);
3280: }
3281: XS_SETERR(xs, HBA_NOERROR);
3282: isp_prt(isp, ISP_LOGDEBUG2,
3283: "START cmd for %d.%d.%d cmd 0x%x datalen %ld",
3284: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0],
3285: (long) XS_XFRLEN(xs));
3286: ISP_ADD_REQUEST(isp, nxti);
3287: isp->isp_nactive++;
3288: return (CMD_QUEUED);
3289: }
3290:
3291: /*
3292: * isp control
3293: * Locks (ints blocked) assumed held.
3294: */
3295:
3296: int
3297: isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
3298: {
3299: XS_T *xs;
3300: mbreg_t mbs;
3301: int bus, tgt;
3302: u_int16_t handle;
3303:
3304: switch (ctl) {
3305: default:
3306: isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
3307: break;
3308:
3309: case ISPCTL_RESET_BUS:
3310: /*
3311: * Issue a bus reset.
3312: */
3313: mbs.param[0] = MBOX_BUS_RESET;
3314: mbs.param[2] = 0;
3315: if (IS_SCSI(isp)) {
3316: mbs.param[1] =
3317: ((sdparam *) isp->isp_param)->isp_bus_reset_delay;
3318: if (mbs.param[1] < 2)
3319: mbs.param[1] = 2;
3320: bus = *((int *) arg);
3321: if (IS_DUALBUS(isp))
3322: mbs.param[2] = bus;
3323: } else {
3324: mbs.param[1] = 10;
3325: bus = 0;
3326: }
3327: isp->isp_sendmarker |= (1 << bus);
3328: isp_mboxcmd(isp, &mbs, MBLOGALL);
3329: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3330: break;
3331: }
3332: isp_prt(isp, ISP_LOGINFO,
3333: "driver initiated bus reset of bus %d", bus);
3334: return (0);
3335:
3336: case ISPCTL_RESET_DEV:
3337: tgt = (*((int *) arg)) & 0xffff;
3338: bus = (*((int *) arg)) >> 16;
3339: mbs.param[0] = MBOX_ABORT_TARGET;
3340: mbs.param[1] = (tgt << 8) | (bus << 15);
3341: mbs.param[2] = 3; /* 'delay', in seconds */
3342: isp_mboxcmd(isp, &mbs, MBLOGALL);
3343: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3344: break;
3345: }
3346: isp_prt(isp, ISP_LOGINFO,
3347: "Target %d on Bus %d Reset Succeeded", tgt, bus);
3348: isp->isp_sendmarker |= (1 << bus);
3349: return (0);
3350:
3351: case ISPCTL_ABORT_CMD:
3352: xs = (XS_T *) arg;
3353: tgt = XS_TGT(xs);
3354: handle = isp_find_handle(isp, xs);
3355: if (handle == 0) {
3356: isp_prt(isp, ISP_LOGWARN,
3357: "cannot find handle for command to abort");
3358: break;
3359: }
3360: bus = XS_CHANNEL(xs);
3361: mbs.param[0] = MBOX_ABORT;
3362: if (IS_FC(isp)) {
3363: if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
3364: mbs.param[1] = tgt << 8;
3365: mbs.param[4] = 0;
3366: mbs.param[5] = 0;
3367: mbs.param[6] = XS_LUN(xs);
3368: } else {
3369: mbs.param[1] = tgt << 8 | XS_LUN(xs);
3370: }
3371: } else {
3372: mbs.param[1] =
3373: (bus << 15) | (XS_TGT(xs) << 8) | XS_LUN(xs);
3374: }
3375: mbs.param[3] = 0;
3376: mbs.param[2] = handle;
3377: isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_ERROR);
3378: if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
3379: return (0);
3380: }
3381: /*
3382: * XXX: Look for command in the REQUEST QUEUE. That is,
3383: * XXX: It hasn't been picked up by firmware yet.
3384: */
3385: break;
3386:
3387: case ISPCTL_UPDATE_PARAMS:
3388:
3389: isp_update(isp);
3390: return (0);
3391:
3392: case ISPCTL_FCLINK_TEST:
3393:
3394: if (IS_FC(isp)) {
3395: int usdelay = (arg)? *((int *) arg) : 250000;
3396: return (isp_fclink_test(isp, usdelay));
3397: }
3398: break;
3399:
3400: case ISPCTL_SCAN_FABRIC:
3401:
3402: if (IS_FC(isp)) {
3403: int ftype = (arg)? *((int *) arg) : FC4_SCSI;
3404: return (isp_scan_fabric(isp, ftype));
3405: }
3406: break;
3407:
3408: case ISPCTL_SCAN_LOOP:
3409:
3410: if (IS_FC(isp)) {
3411: return (isp_scan_loop(isp));
3412: }
3413: break;
3414:
3415: case ISPCTL_PDB_SYNC:
3416:
3417: if (IS_FC(isp)) {
3418: return (isp_pdb_sync(isp));
3419: }
3420: break;
3421:
3422: case ISPCTL_SEND_LIP:
3423:
3424: if (IS_FC(isp)) {
3425: mbs.param[0] = MBOX_INIT_LIP;
3426: isp_mboxcmd(isp, &mbs, MBLOGALL);
3427: if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
3428: return (0);
3429: }
3430: }
3431: break;
3432:
3433: case ISPCTL_GET_POSMAP:
3434:
3435: if (IS_FC(isp) && arg) {
3436: return (isp_getmap(isp, arg));
3437: }
3438: break;
3439:
3440: case ISPCTL_RUN_MBOXCMD:
3441:
3442: isp_mboxcmd(isp, arg, MBLOGALL);
3443: return(0);
3444:
3445: #ifdef ISP_TARGET_MODE
3446: case ISPCTL_TOGGLE_TMODE:
3447: {
3448:
3449: /*
3450: * We don't check/set against role here- that's the
3451: * responsibility for the outer layer to coordinate.
3452: */
3453: if (IS_SCSI(isp)) {
3454: int param = *(int *)arg;
3455: mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
3456: mbs.param[1] = param & 0xffff;
3457: mbs.param[2] = param >> 16;
3458: isp_mboxcmd(isp, &mbs, MBLOGALL);
3459: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3460: break;
3461: }
3462: }
3463: return (0);
3464: }
3465: #endif
3466: }
3467: return (-1);
3468: }
3469:
3470: /*
3471: * Interrupt Service Routine(s).
3472: *
3473: * External (OS) framework has done the appropriate locking,
3474: * and the locking will be held throughout this function.
3475: */
3476:
3477: /*
3478: * Limit our stack depth by sticking with the max likely number
3479: * of completions on a request queue at any one time.
3480: */
3481: #ifndef MAX_REQUESTQ_COMPLETIONS
3482: #define MAX_REQUESTQ_COMPLETIONS 64
3483: #endif
3484:
3485: void
3486: isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
3487: {
3488: XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
3489: u_int16_t iptr, optr, junk;
3490: int i, nlooked = 0, ndone = 0;
3491:
3492: again:
3493: /*
3494: * Is this a mailbox related interrupt?
3495: * The mailbox semaphore will be nonzero if so.
3496: */
3497: if (sema) {
3498: if (mbox & 0x4000) {
3499: isp->isp_intmboxc++;
3500: if (isp->isp_mboxbsy) {
3501: int i = 0, obits = isp->isp_obits;
3502: isp->isp_mboxtmp[i++] = mbox;
3503: for (i = 1; i < MAX_MAILBOX; i++) {
3504: if ((obits & (1 << i)) == 0) {
3505: continue;
3506: }
3507: isp->isp_mboxtmp[i] =
3508: ISP_READ(isp, MBOX_OFF(i));
3509: }
3510: if (isp->isp_mbxwrk0) {
3511: if (isp_mbox_continue(isp) == 0) {
3512: return;
3513: }
3514: }
3515: MBOX_NOTIFY_COMPLETE(isp);
3516: } else {
3517: isp_prt(isp, ISP_LOGWARN,
3518: "Mbox Command Async (0x%x) with no waiters",
3519: mbox);
3520: }
3521: } else if (isp_parse_async(isp, mbox) < 0) {
3522: return;
3523: }
3524: if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) ||
3525: isp->isp_state != ISP_RUNSTATE) {
3526: ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3527: ISP_WRITE(isp, BIU_SEMA, 0);
3528: return;
3529: }
3530: }
3531:
3532: /*
3533: * We can't be getting this now.
3534: */
3535: if (isp->isp_state != ISP_RUNSTATE) {
3536: isp_prt(isp, ISP_LOGWARN,
3537: "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
3538: /*
3539: * Thank you very much! *Burrrp*!
3540: */
3541: WRITE_RESPONSE_QUEUE_OUT_POINTER(isp,
3542: READ_RESPONSE_QUEUE_IN_POINTER(isp));
3543:
3544: ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3545: ISP_WRITE(isp, BIU_SEMA, 0);
3546: return;
3547: }
3548:
3549: /*
3550: * Get the current Response Queue Out Pointer.
3551: *
3552: * If we're a 2300, we can ask what hardware what it thinks.
3553: */
3554: if (IS_23XX(isp)) {
3555: optr = ISP_READ(isp, isp->isp_respoutrp);
3556: /*
3557: * Debug: to be taken out eventually
3558: */
3559: if (isp->isp_residx != optr) {
3560: isp_prt(isp, ISP_LOGWARN, "optr %x soft optr %x",
3561: optr, isp->isp_residx);
3562: }
3563: } else {
3564: optr = isp->isp_residx;
3565: }
3566:
3567: /*
3568: * You *must* read the Response Queue In Pointer
3569: * prior to clearing the RISC interrupt.
3570: *
3571: * Debounce the 2300 if revision less than 2.
3572: */
3573: if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
3574: i = 0;
3575: do {
3576: iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
3577: junk = READ_RESPONSE_QUEUE_IN_POINTER(isp);
3578: } while (junk != iptr && ++i < 1000);
3579:
3580: if (iptr != junk) {
3581: ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3582: isp_prt(isp, ISP_LOGWARN,
3583: "Response Queue Out Pointer Unstable (%x, %x)",
3584: iptr, junk);
3585: return;
3586: }
3587: } else {
3588: iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
3589: }
3590: isp->isp_resodx = iptr;
3591:
3592:
3593: if (optr == iptr && sema == 0) {
3594: /*
3595: * There are a lot of these- reasons unknown- mostly on
3596: * faster Alpha machines.
3597: *
3598: * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
3599: * make sure the old interrupt went away (to avoid 'ringing'
3600: * effects), but that didn't stop this from occurring.
3601: */
3602: if (IS_23XX(isp)) {
3603: USEC_DELAY(100);
3604: iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
3605: junk = ISP_READ(isp, BIU_R2HSTSLO);
3606: } else {
3607: junk = ISP_READ(isp, BIU_ISR);
3608: }
3609: if (optr == iptr) {
3610: if (IS_23XX(isp)) {
3611: ;
3612: } else {
3613: sema = ISP_READ(isp, BIU_SEMA);
3614: mbox = ISP_READ(isp, OUTMAILBOX0);
3615: if ((sema & 0x3) && (mbox & 0x8000)) {
3616: goto again;
3617: }
3618: }
3619: isp->isp_intbogus++;
3620: isp_prt(isp, ISP_LOGDEBUG1,
3621: "bogus intr- isr %x (%x) iptr %x optr %x",
3622: isr, junk, iptr, optr);
3623: }
3624: }
3625: isp->isp_resodx = iptr;
3626: ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3627: ISP_WRITE(isp, BIU_SEMA, 0);
3628:
3629: if (isp->isp_rspbsy) {
3630: return;
3631: }
3632: isp->isp_rspbsy = 1;
3633:
3634: while (optr != iptr) {
3635: ispstatusreq_t local, *sp = &local;
3636: isphdr_t *hp;
3637: int type;
3638: u_int16_t oop;
3639: int buddaboom = 0;
3640:
3641: hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
3642: oop = optr;
3643: optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
3644: nlooked++;
3645: /*
3646: * Synchronize our view of this response queue entry.
3647: */
3648: MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN);
3649:
3650: type = isp_get_response_type(isp, hp);
3651:
3652: if (type == RQSTYPE_RESPONSE) {
3653: isp_get_response(isp, (ispstatusreq_t *) hp, sp);
3654: } else if (type == RQSTYPE_RIO2) {
3655: isp_rio2_t rio;
3656: isp_get_rio2(isp, (isp_rio2_t *) hp, &rio);
3657: for (i = 0; i < rio.req_header.rqs_seqno; i++) {
3658: isp_fastpost_complete(isp, rio.req_handles[i]);
3659: }
3660: if (isp->isp_fpcchiwater < rio.req_header.rqs_seqno)
3661: isp->isp_fpcchiwater = rio.req_header.rqs_seqno;
3662: MEMZERO(hp, QENTRY_LEN); /* PERF */
3663: continue;
3664: } else {
3665: /*
3666: * Somebody reachable via isp_handle_other_response
3667: * may have updated the response queue pointers for
3668: * us, so we reload our goal index.
3669: */
3670: if (isp_handle_other_response(isp, type, hp, &optr)) {
3671: iptr = isp->isp_resodx;
3672: MEMZERO(hp, QENTRY_LEN); /* PERF */
3673: continue;
3674: }
3675:
3676: /*
3677: * After this point, we'll just look at the header as
3678: * we don't know how to deal with the rest of the
3679: * response.
3680: */
3681: isp_get_response(isp, (ispstatusreq_t *) hp, sp);
3682:
3683: /*
3684: * It really has to be a bounced request just copied
3685: * from the request queue to the response queue. If
3686: * not, something bad has happened.
3687: */
3688: if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) {
3689: isp_prt(isp, ISP_LOGERR, notresp,
3690: sp->req_header.rqs_entry_type, oop, optr,
3691: nlooked);
3692: if (isp->isp_dblev & ISP_LOGDEBUG0) {
3693: isp_print_bytes(isp, "Queue Entry",
3694: QENTRY_LEN, sp);
3695: }
3696: MEMZERO(hp, QENTRY_LEN); /* PERF */
3697: continue;
3698: }
3699: buddaboom = 1;
3700: }
3701:
3702: if (sp->req_header.rqs_flags & 0xf) {
3703: #define _RQS_OFLAGS \
3704: ~(RQSFLAG_CONTINUATION|RQSFLAG_FULL|RQSFLAG_BADHEADER|RQSFLAG_BADPACKET)
3705: if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
3706: isp_prt(isp, ISP_LOGWARN,
3707: "continuation segment");
3708: WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
3709: continue;
3710: }
3711: if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
3712: isp_prt(isp, ISP_LOGDEBUG1,
3713: "internal queues full");
3714: /*
3715: * We'll synthesize a QUEUE FULL message below.
3716: */
3717: }
3718: if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
3719: isp_prt(isp, ISP_LOGERR, "bad header flag");
3720: buddaboom++;
3721: }
3722: if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
3723: isp_prt(isp, ISP_LOGERR, "bad request packet");
3724: buddaboom++;
3725: }
3726: if (sp->req_header.rqs_flags & _RQS_OFLAGS) {
3727: isp_prt(isp, ISP_LOGERR,
3728: "unknown flags (0x%x) in response",
3729: sp->req_header.rqs_flags);
3730: buddaboom++;
3731: }
3732: #undef _RQS_OFLAGS
3733: }
3734: if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) {
3735: MEMZERO(hp, QENTRY_LEN); /* PERF */
3736: isp_prt(isp, ISP_LOGERR,
3737: "bad request handle %d (type 0x%x, flags 0x%x)",
3738: sp->req_handle, sp->req_header.rqs_entry_type,
3739: sp->req_header.rqs_flags);
3740: WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
3741: continue;
3742: }
3743: xs = isp_find_xs(isp, sp->req_handle);
3744: if (xs == NULL) {
3745: u_int8_t ts = sp->req_completion_status & 0xff;
3746: MEMZERO(hp, QENTRY_LEN); /* PERF */
3747: /*
3748: * Only whine if this isn't the expected fallout of
3749: * aborting the command.
3750: */
3751: if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
3752: isp_prt(isp, ISP_LOGERR,
3753: "cannot find handle 0x%x (type 0x%x)",
3754: sp->req_handle,
3755: sp->req_header.rqs_entry_type);
3756: } else if (ts != RQCS_ABORTED) {
3757: isp_prt(isp, ISP_LOGERR,
3758: "cannot find handle 0x%x (status 0x%x)",
3759: sp->req_handle, ts);
3760: }
3761: WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
3762: continue;
3763: }
3764: isp_destroy_handle(isp, sp->req_handle);
3765: if (sp->req_status_flags & RQSTF_BUS_RESET) {
3766: XS_SETERR(xs, HBA_BUSRESET);
3767: isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
3768: }
3769: if (buddaboom) {
3770: XS_SETERR(xs, HBA_BOTCH);
3771: }
3772:
3773: if (IS_FC(isp) && (sp->req_scsi_status & RQCS_SV)) {
3774: /*
3775: * Fibre Channel F/W doesn't say we got status
3776: * if there's Sense Data instead. I guess they
3777: * think it goes w/o saying.
3778: */
3779: sp->req_state_flags |= RQSF_GOT_STATUS;
3780: }
3781: if (sp->req_state_flags & RQSF_GOT_STATUS) {
3782: *XS_STSP(xs) = sp->req_scsi_status & 0xff;
3783: }
3784:
3785: switch (sp->req_header.rqs_entry_type) {
3786: case RQSTYPE_RESPONSE:
3787: XS_SET_STATE_STAT(isp, xs, sp);
3788: isp_parse_status(isp, sp, xs);
3789: if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) &&
3790: (*XS_STSP(xs) == SCSI_BUSY)) {
3791: XS_SETERR(xs, HBA_TGTBSY);
3792: }
3793: if (IS_SCSI(isp)) {
3794: XS_RESID(xs) = sp->req_resid;
3795: if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
3796: (*XS_STSP(xs) == SCSI_CHECK) &&
3797: (sp->req_state_flags & RQSF_GOT_SENSE)) {
3798: XS_SAVE_SENSE(xs, sp);
3799: }
3800: /*
3801: * A new synchronous rate was negotiated for
3802: * this target. Mark state such that we'll go
3803: * look up that which has changed later.
3804: */
3805: if (sp->req_status_flags & RQSTF_NEGOTIATION) {
3806: int t = XS_TGT(xs);
3807: sdparam *sdp = isp->isp_param;
3808: sdp += XS_CHANNEL(xs);
3809: sdp->isp_devparam[t].dev_refresh = 1;
3810: isp->isp_update |=
3811: (1 << XS_CHANNEL(xs));
3812: }
3813: } else {
3814: if (sp->req_status_flags & RQSF_XFER_COMPLETE) {
3815: XS_RESID(xs) = 0;
3816: } else if (sp->req_scsi_status & RQCS_RESID) {
3817: XS_RESID(xs) = sp->req_resid;
3818: } else {
3819: XS_RESID(xs) = 0;
3820: }
3821: if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
3822: (*XS_STSP(xs) == SCSI_CHECK) &&
3823: (sp->req_scsi_status & RQCS_SV)) {
3824: XS_SAVE_SENSE(xs, sp);
3825: /* solely for the benefit of debug */
3826: sp->req_state_flags |= RQSF_GOT_SENSE;
3827: }
3828: }
3829: isp_prt(isp, ISP_LOGDEBUG2,
3830: "asked for %ld got resid %ld", (long) XS_XFRLEN(xs),
3831: (long) sp->req_resid);
3832: break;
3833: case RQSTYPE_REQUEST:
3834: if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
3835: /*
3836: * Force Queue Full status.
3837: */
3838: *XS_STSP(xs) = SCSI_QFULL;
3839: XS_SETERR(xs, HBA_NOERROR);
3840: } else if (XS_NOERR(xs)) {
3841: /*
3842: * ????
3843: */
3844: isp_prt(isp, ISP_LOGDEBUG0,
3845: "Request Queue Entry bounced back");
3846: XS_SETERR(xs, HBA_BOTCH);
3847: }
3848: XS_RESID(xs) = XS_XFRLEN(xs);
3849: break;
3850: default:
3851: isp_prt(isp, ISP_LOGWARN,
3852: "unhandled response queue type 0x%x",
3853: sp->req_header.rqs_entry_type);
3854: if (XS_NOERR(xs)) {
3855: XS_SETERR(xs, HBA_BOTCH);
3856: }
3857: break;
3858: }
3859:
3860: /*
3861: * Free any dma resources. As a side effect, this may
3862: * also do any cache flushing necessary for data coherence. */
3863: if (XS_XFRLEN(xs)) {
3864: ISP_DMAFREE(isp, xs, sp->req_handle);
3865: }
3866:
3867: if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
3868: ((isp->isp_dblev & ISP_LOGDEBUG1) && ((!XS_NOERR(xs)) ||
3869: (*XS_STSP(xs) != SCSI_GOOD)))) {
3870: char skey;
3871: if (sp->req_state_flags & RQSF_GOT_SENSE) {
3872: skey = XS_SNSKEY(xs) & 0xf;
3873: if (skey < 10)
3874: skey += '0';
3875: else
3876: skey += 'a' - 10;
3877: } else if (*XS_STSP(xs) == SCSI_CHECK) {
3878: skey = '?';
3879: } else {
3880: skey = '.';
3881: }
3882: isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs),
3883: XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs),
3884: (ulong)XS_RESID(xs),
3885: *XS_STSP(xs), skey, XS_ERR(xs));
3886: }
3887:
3888: if (isp->isp_nactive > 0)
3889: isp->isp_nactive--;
3890: complist[ndone++] = xs; /* defer completion call until later */
3891: MEMZERO(hp, QENTRY_LEN); /* PERF */
3892: if (ndone == MAX_REQUESTQ_COMPLETIONS) {
3893: break;
3894: }
3895: }
3896:
3897: /*
3898: * If we looked at any commands, then it's valid to find out
3899: * what the outpointer is. It also is a trigger to update the
3900: * ISP's notion of what we've seen so far.
3901: */
3902: if (nlooked) {
3903: WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
3904: /*
3905: * While we're at it, read the request queue out pointer.
3906: */
3907: isp->isp_reqodx = READ_REQUEST_QUEUE_OUT_POINTER(isp);
3908: if (isp->isp_rscchiwater < ndone)
3909: isp->isp_rscchiwater = ndone;
3910: }
3911:
3912: isp->isp_residx = optr;
3913: isp->isp_rspbsy = 0;
3914: for (i = 0; i < ndone; i++) {
3915: xs = complist[i];
3916: if (xs) {
3917: isp->isp_rsltccmplt++;
3918: isp_done(xs);
3919: }
3920: }
3921: }
3922:
3923: /*
3924: * Support routines.
3925: */
3926:
3927: static int
3928: isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
3929: {
3930: int rval = 0;
3931: int bus;
3932:
3933: if (IS_DUALBUS(isp)) {
3934: bus = ISP_READ(isp, OUTMAILBOX6);
3935: } else {
3936: bus = 0;
3937: }
3938: isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
3939:
3940: switch (mbox) {
3941: case ASYNC_BUS_RESET:
3942: isp->isp_sendmarker |= (1 << bus);
3943: #ifdef ISP_TARGET_MODE
3944: if (isp_target_async(isp, bus, mbox))
3945: rval = -1;
3946: #endif
3947: isp_async(isp, ISPASYNC_BUS_RESET, &bus);
3948: break;
3949: case ASYNC_SYSTEM_ERROR:
3950: #ifdef ISP_FW_CRASH_DUMP
3951: /*
3952: * If we have crash dumps enabled, it's up to the handler
3953: * for isp_async to reinit stuff and restart the firmware
3954: * after performing the crash dump. The reason we do things
3955: * this way is that we may need to activate a kernel thread
3956: * to do all the crash dump goop.
3957: */
3958: isp_async(isp, ISPASYNC_FW_CRASH, NULL);
3959: #else
3960: isp_async(isp, ISPASYNC_FW_CRASH, NULL);
3961: isp_reinit(isp);
3962: isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
3963: #endif
3964: rval = -1;
3965: break;
3966:
3967: case ASYNC_RQS_XFER_ERR:
3968: isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
3969: break;
3970:
3971: case ASYNC_RSP_XFER_ERR:
3972: isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
3973: break;
3974:
3975: case ASYNC_QWAKEUP:
3976: /*
3977: * We've just been notified that the Queue has woken up.
3978: * We don't need to be chatty about this- just unlatch things
3979: * and move on.
3980: */
3981: mbox = READ_REQUEST_QUEUE_OUT_POINTER(isp);
3982: break;
3983:
3984: case ASYNC_TIMEOUT_RESET:
3985: isp_prt(isp, ISP_LOGWARN,
3986: "timeout initiated SCSI bus reset of bus %d", bus);
3987: isp->isp_sendmarker |= (1 << bus);
3988: #ifdef ISP_TARGET_MODE
3989: if (isp_target_async(isp, bus, mbox))
3990: rval = -1;
3991: #endif
3992: break;
3993:
3994: case ASYNC_DEVICE_RESET:
3995: isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus);
3996: isp->isp_sendmarker |= (1 << bus);
3997: #ifdef ISP_TARGET_MODE
3998: if (isp_target_async(isp, bus, mbox))
3999: rval = -1;
4000: #endif
4001: break;
4002:
4003: case ASYNC_EXTMSG_UNDERRUN:
4004: isp_prt(isp, ISP_LOGWARN, "extended message underrun");
4005: break;
4006:
4007: case ASYNC_SCAM_INT:
4008: isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
4009: break;
4010:
4011: case ASYNC_HUNG_SCSI:
4012: isp_prt(isp, ISP_LOGERR,
4013: "stalled SCSI Bus after DATA Overrun");
4014: /* XXX: Need to issue SCSI reset at this point */
4015: break;
4016:
4017: case ASYNC_KILLED_BUS:
4018: isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
4019: break;
4020:
4021: case ASYNC_BUS_TRANSIT:
4022: mbox = ISP_READ(isp, OUTMAILBOX2);
4023: switch (mbox & 0x1c00) {
4024: case SXP_PINS_LVD_MODE:
4025: isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
4026: SDPARAM(isp)->isp_diffmode = 0;
4027: SDPARAM(isp)->isp_ultramode = 0;
4028: SDPARAM(isp)->isp_lvdmode = 1;
4029: break;
4030: case SXP_PINS_HVD_MODE:
4031: isp_prt(isp, ISP_LOGINFO,
4032: "Transition to Differential mode");
4033: SDPARAM(isp)->isp_diffmode = 1;
4034: SDPARAM(isp)->isp_ultramode = 0;
4035: SDPARAM(isp)->isp_lvdmode = 0;
4036: break;
4037: case SXP_PINS_SE_MODE:
4038: isp_prt(isp, ISP_LOGINFO,
4039: "Transition to Single Ended mode");
4040: SDPARAM(isp)->isp_diffmode = 0;
4041: SDPARAM(isp)->isp_ultramode = 1;
4042: SDPARAM(isp)->isp_lvdmode = 0;
4043: break;
4044: default:
4045: isp_prt(isp, ISP_LOGWARN,
4046: "Transition to Unknown Mode 0x%x", mbox);
4047: break;
4048: }
4049: /*
4050: * XXX: Set up to renegotiate again!
4051: */
4052: /* Can only be for a 1080... */
4053: isp->isp_sendmarker |= (1 << bus);
4054: break;
4055:
4056: /*
4057: * We can use bus, which will always be zero for FC cards,
4058: * as a mailbox pattern accumulator to be checked below.
4059: */
4060: case ASYNC_RIO5:
4061: bus = 0x1ce; /* outgoing mailbox regs 1-3, 6-7 */
4062: break;
4063:
4064: case ASYNC_RIO4:
4065: bus = 0x14e; /* outgoing mailbox regs 1-3, 6 */
4066: break;
4067:
4068: case ASYNC_RIO3:
4069: bus = 0x10e; /* outgoing mailbox regs 1-3 */
4070: break;
4071:
4072: case ASYNC_RIO2:
4073: bus = 0x106; /* outgoing mailbox regs 1-2 */
4074: break;
4075:
4076: case ASYNC_RIO1:
4077: case ASYNC_CMD_CMPLT:
4078: bus = 0x102; /* outgoing mailbox regs 1 */
4079: break;
4080:
4081: case ASYNC_RIO_RESP:
4082: return (rval);
4083:
4084: case ASYNC_CTIO_DONE:
4085: {
4086: #ifdef ISP_TARGET_MODE
4087: int handle =
4088: (ISP_READ(isp, OUTMAILBOX2) << 16) |
4089: (ISP_READ(isp, OUTMAILBOX1));
4090: if (isp_target_async(isp, handle, mbox))
4091: rval = -1;
4092: #else
4093: isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
4094: #endif
4095: isp->isp_fphccmplt++; /* count it as a fast posting intr */
4096: break;
4097: }
4098: case ASYNC_LIP_F8:
4099: case ASYNC_LIP_OCCURRED:
4100: FCPARAM(isp)->isp_lipseq =
4101: ISP_READ(isp, OUTMAILBOX1);
4102: FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4103: FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
4104: isp->isp_sendmarker = 1;
4105: isp_mark_getpdb_all(isp);
4106: isp_async(isp, ISPASYNC_LIP, NULL);
4107: #ifdef ISP_TARGET_MODE
4108: if (isp_target_async(isp, bus, mbox))
4109: rval = -1;
4110: #endif
4111: /*
4112: * We've had problems with data corruption occurring on
4113: * commands that complete (with no apparent error) after
4114: * we receive a LIP. This has been observed mostly on
4115: * Local Loop topologies. To be safe, let's just mark
4116: * all active commands as dead.
4117: */
4118: if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
4119: FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
4120: int i, j;
4121: for (i = j = 0; i < isp->isp_maxcmds; i++) {
4122: XS_T *xs;
4123: xs = isp->isp_xflist[i];
4124: if (xs != NULL) {
4125: j++;
4126: XS_SETERR(xs, HBA_BUSRESET);
4127: }
4128: }
4129: if (j) {
4130: isp_prt(isp, ISP_LOGERR,
4131: "LIP destroyed %d active commands", j);
4132: }
4133: }
4134: break;
4135:
4136: case ASYNC_LOOP_UP:
4137: isp->isp_sendmarker = 1;
4138: FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4139: FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
4140: isp_mark_getpdb_all(isp);
4141: isp_async(isp, ISPASYNC_LOOP_UP, NULL);
4142: #ifdef ISP_TARGET_MODE
4143: if (isp_target_async(isp, bus, mbox))
4144: rval = -1;
4145: #endif
4146: break;
4147:
4148: case ASYNC_LOOP_DOWN:
4149: isp->isp_sendmarker = 1;
4150: FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4151: FCPARAM(isp)->isp_loopstate = LOOP_NIL;
4152: isp_mark_getpdb_all(isp);
4153: isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
4154: #ifdef ISP_TARGET_MODE
4155: if (isp_target_async(isp, bus, mbox))
4156: rval = -1;
4157: #endif
4158: break;
4159:
4160: case ASYNC_LOOP_RESET:
4161: isp->isp_sendmarker = 1;
4162: FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4163: FCPARAM(isp)->isp_loopstate = LOOP_NIL;
4164: isp_mark_getpdb_all(isp);
4165: isp_async(isp, ISPASYNC_LOOP_RESET, NULL);
4166: #ifdef ISP_TARGET_MODE
4167: if (isp_target_async(isp, bus, mbox))
4168: rval = -1;
4169: #endif
4170: break;
4171:
4172: case ASYNC_PDB_CHANGED:
4173: isp->isp_sendmarker = 1;
4174: FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
4175: isp_mark_getpdb_all(isp);
4176: isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_PDB);
4177: break;
4178:
4179: case ASYNC_CHANGE_NOTIFY:
4180: /*
4181: * Not correct, but it will force us to rescan the loop.
4182: */
4183: FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
4184: isp_mark_getpdb_all(isp);
4185: isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_SNS);
4186: break;
4187:
4188: case ASYNC_PTPMODE:
4189: if (FCPARAM(isp)->isp_onfabric)
4190: FCPARAM(isp)->isp_topo = TOPO_F_PORT;
4191: else
4192: FCPARAM(isp)->isp_topo = TOPO_N_PORT;
4193: isp_mark_getpdb_all(isp);
4194: isp->isp_sendmarker = 1;
4195: FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4196: FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
4197: isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
4198: #ifdef ISP_TARGET_MODE
4199: if (isp_target_async(isp, bus, mbox))
4200: rval = -1;
4201: #endif
4202: isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode");
4203: break;
4204:
4205: case ASYNC_CONNMODE:
4206: mbox = ISP_READ(isp, OUTMAILBOX1);
4207: isp_mark_getpdb_all(isp);
4208: switch (mbox) {
4209: case ISP_CONN_LOOP:
4210: isp_prt(isp, ISP_LOGINFO,
4211: "Point-to-Point -> Loop mode");
4212: break;
4213: case ISP_CONN_PTP:
4214: isp_prt(isp, ISP_LOGINFO,
4215: "Loop -> Point-to-Point mode");
4216: break;
4217: case ISP_CONN_BADLIP:
4218: isp_prt(isp, ISP_LOGWARN,
4219: "Point-to-Point -> Loop mode (BAD LIP)");
4220: break;
4221: case ISP_CONN_FATAL:
4222: isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
4223: #ifdef ISP_FW_CRASH_DUMP
4224: isp_async(isp, ISPASYNC_FW_CRASH, NULL);
4225: #else
4226: isp_async(isp, ISPASYNC_FW_CRASH, NULL);
4227: isp_reinit(isp);
4228: isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
4229: #endif
4230: return (-1);
4231: case ISP_CONN_LOOPBACK:
4232: isp_prt(isp, ISP_LOGWARN,
4233: "Looped Back in Point-to-Point mode");
4234: break;
4235: default:
4236: isp_prt(isp, ISP_LOGWARN,
4237: "Unknown connection mode (0x%x)", mbox);
4238: break;
4239: }
4240: isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
4241: isp->isp_sendmarker = 1;
4242: FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4243: FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
4244: break;
4245:
4246: default:
4247: isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
4248: break;
4249: }
4250:
4251: if (bus & 0x100) {
4252: int i, nh;
4253: u_int16_t handles[5];
4254:
4255: for (nh = 0, i = 1; i < MAX_MAILBOX; i++) {
4256: if ((bus & (1 << i)) == 0) {
4257: continue;
4258: }
4259: handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
4260: }
4261: for (i = 0; i < nh; i++) {
4262: isp_fastpost_complete(isp, handles[i]);
4263: isp_prt(isp, ISP_LOGDEBUG3,
4264: "fast post completion of %u", handles[i]);
4265: }
4266: if (isp->isp_fpcchiwater < nh)
4267: isp->isp_fpcchiwater = nh;
4268: } else {
4269: isp->isp_intoasync++;
4270: }
4271: return (rval);
4272: }
4273:
4274: /*
4275: * Handle other response entries. A pointer to the request queue output
4276: * index is here in case we want to eat several entries at once, although
4277: * this is not used currently.
4278: */
4279:
4280: static int
4281: isp_handle_other_response(struct ispsoftc *isp, int type,
4282: isphdr_t *hp, u_int16_t *optrp)
4283: {
4284: switch (type) {
4285: case RQSTYPE_STATUS_CONT:
4286: isp_prt(isp, ISP_LOGINFO, "Ignored Continuation Response");
4287: return (1);
4288: case RQSTYPE_ATIO:
4289: case RQSTYPE_CTIO:
4290: case RQSTYPE_ENABLE_LUN:
4291: case RQSTYPE_MODIFY_LUN:
4292: case RQSTYPE_NOTIFY:
4293: case RQSTYPE_NOTIFY_ACK:
4294: case RQSTYPE_CTIO1:
4295: case RQSTYPE_ATIO2:
4296: case RQSTYPE_CTIO2:
4297: case RQSTYPE_CTIO3:
4298: isp->isp_rsltccmplt++; /* count as a response completion */
4299: #ifdef ISP_TARGET_MODE
4300: if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
4301: return (1);
4302: }
4303: #endif
4304: /* FALLTHROUGH */
4305: case RQSTYPE_REQUEST:
4306: default:
4307: if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) {
4308: return (1);
4309: }
4310: isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
4311: isp_get_response_type(isp, hp));
4312: return (0);
4313: }
4314: }
4315:
4316: static void
4317: isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
4318: {
4319: switch (sp->req_completion_status & 0xff) {
4320: case RQCS_COMPLETE:
4321: if (XS_NOERR(xs)) {
4322: XS_SETERR(xs, HBA_NOERROR);
4323: }
4324: return;
4325:
4326: case RQCS_INCOMPLETE:
4327: if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
4328: isp_prt(isp, ISP_LOGDEBUG1,
4329: "Selection Timeout for %d.%d.%d",
4330: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4331: if (XS_NOERR(xs)) {
4332: XS_SETERR(xs, HBA_SELTIMEOUT);
4333: }
4334: return;
4335: }
4336: isp_prt(isp, ISP_LOGERR,
4337: "command incomplete for %d.%d.%d, state 0x%x",
4338: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
4339: sp->req_state_flags);
4340: break;
4341:
4342: case RQCS_DMA_ERROR:
4343: isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
4344: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4345: break;
4346:
4347: case RQCS_TRANSPORT_ERROR:
4348: {
4349: char buf[172];
4350: SNPRINTF(buf, sizeof (buf), "states=>");
4351: if (sp->req_state_flags & RQSF_GOT_BUS) {
4352: SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
4353: }
4354: if (sp->req_state_flags & RQSF_GOT_TARGET) {
4355: SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
4356: }
4357: if (sp->req_state_flags & RQSF_SENT_CDB) {
4358: SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
4359: }
4360: if (sp->req_state_flags & RQSF_XFRD_DATA) {
4361: SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
4362: }
4363: if (sp->req_state_flags & RQSF_GOT_STATUS) {
4364: SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
4365: }
4366: if (sp->req_state_flags & RQSF_GOT_SENSE) {
4367: SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
4368: }
4369: if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
4370: SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
4371: }
4372: SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
4373: if (sp->req_status_flags & RQSTF_DISCONNECT) {
4374: SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
4375: }
4376: if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
4377: SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
4378: }
4379: if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
4380: SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
4381: }
4382: if (sp->req_status_flags & RQSTF_BUS_RESET) {
4383: SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
4384: }
4385: if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
4386: SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
4387: }
4388: if (sp->req_status_flags & RQSTF_ABORTED) {
4389: SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
4390: }
4391: if (sp->req_status_flags & RQSTF_TIMEOUT) {
4392: SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
4393: }
4394: if (sp->req_status_flags & RQSTF_NEGOTIATION) {
4395: SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
4396: }
4397: isp_prt(isp, ISP_LOGERR, "%s", buf);
4398: isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
4399: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
4400: break;
4401: }
4402: case RQCS_RESET_OCCURRED:
4403: isp_prt(isp, ISP_LOGWARN,
4404: "bus reset destroyed command for %d.%d.%d",
4405: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4406: isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
4407: if (XS_NOERR(xs)) {
4408: XS_SETERR(xs, HBA_BUSRESET);
4409: }
4410: return;
4411:
4412: case RQCS_ABORTED:
4413: isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
4414: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4415: isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
4416: if (XS_NOERR(xs)) {
4417: XS_SETERR(xs, HBA_ABORTED);
4418: }
4419: return;
4420:
4421: case RQCS_TIMEOUT:
4422: isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
4423: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4424: /*
4425: * Check to see if we logged out the device.
4426: */
4427: if (IS_FC(isp)) {
4428: if ((sp->req_completion_status & RQSTF_LOGOUT) &&
4429: FCPARAM(isp)->portdb[XS_TGT(xs)].valid &&
4430: FCPARAM(isp)->portdb[XS_TGT(xs)].fabric_dev) {
4431: FCPARAM(isp)->portdb[XS_TGT(xs)].relogin = 1;
4432: }
4433: }
4434: if (XS_NOERR(xs)) {
4435: XS_SETERR(xs, HBA_CMDTIMEOUT);
4436: }
4437: return;
4438:
4439: case RQCS_DATA_OVERRUN:
4440: XS_RESID(xs) = sp->req_resid;
4441: isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d",
4442: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4443: if (XS_NOERR(xs)) {
4444: XS_SETERR(xs, HBA_DATAOVR);
4445: }
4446: return;
4447:
4448: case RQCS_COMMAND_OVERRUN:
4449: isp_prt(isp, ISP_LOGERR,
4450: "command overrun for command on %d.%d.%d",
4451: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4452: break;
4453:
4454: case RQCS_STATUS_OVERRUN:
4455: isp_prt(isp, ISP_LOGERR,
4456: "status overrun for command on %d.%d.%d",
4457: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4458: break;
4459:
4460: case RQCS_BAD_MESSAGE:
4461: isp_prt(isp, ISP_LOGERR,
4462: "msg not COMMAND COMPLETE after status %d.%d.%d",
4463: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4464: break;
4465:
4466: case RQCS_NO_MESSAGE_OUT:
4467: isp_prt(isp, ISP_LOGERR,
4468: "No MESSAGE OUT phase after selection on %d.%d.%d",
4469: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4470: break;
4471:
4472: case RQCS_EXT_ID_FAILED:
4473: isp_prt(isp, ISP_LOGERR, "EXTENDED IDENTIFY failed %d.%d.%d",
4474: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4475: break;
4476:
4477: case RQCS_IDE_MSG_FAILED:
4478: isp_prt(isp, ISP_LOGERR,
4479: "INITIATOR DETECTED ERROR rejected by %d.%d.%d",
4480: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4481: break;
4482:
4483: case RQCS_ABORT_MSG_FAILED:
4484: isp_prt(isp, ISP_LOGERR, "ABORT OPERATION rejected by %d.%d.%d",
4485: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4486: break;
4487:
4488: case RQCS_REJECT_MSG_FAILED:
4489: isp_prt(isp, ISP_LOGERR, "MESSAGE REJECT rejected by %d.%d.%d",
4490: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4491: break;
4492:
4493: case RQCS_NOP_MSG_FAILED:
4494: isp_prt(isp, ISP_LOGERR, "NOP rejected by %d.%d.%d",
4495: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4496: break;
4497:
4498: case RQCS_PARITY_ERROR_MSG_FAILED:
4499: isp_prt(isp, ISP_LOGERR,
4500: "MESSAGE PARITY ERROR rejected by %d.%d.%d",
4501: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4502: break;
4503:
4504: case RQCS_DEVICE_RESET_MSG_FAILED:
4505: isp_prt(isp, ISP_LOGWARN,
4506: "BUS DEVICE RESET rejected by %d.%d.%d",
4507: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4508: break;
4509:
4510: case RQCS_ID_MSG_FAILED:
4511: isp_prt(isp, ISP_LOGERR, "IDENTIFY rejected by %d.%d.%d",
4512: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4513: break;
4514:
4515: case RQCS_UNEXP_BUS_FREE:
4516: isp_prt(isp, ISP_LOGERR, "%d.%d.%d had an unexpected bus free",
4517: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4518: break;
4519:
4520: case RQCS_DATA_UNDERRUN:
4521: {
4522: if (IS_FC(isp)) {
4523: int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
4524: if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
4525: isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
4526: XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
4527: (ru_marked)? "marked" : "not marked");
4528: if (XS_NOERR(xs)) {
4529: XS_SETERR(xs, HBA_BOTCH);
4530: }
4531: return;
4532: }
4533: }
4534: XS_RESID(xs) = sp->req_resid;
4535: if (XS_NOERR(xs)) {
4536: XS_SETERR(xs, HBA_NOERROR);
4537: }
4538: return;
4539: }
4540:
4541: case RQCS_XACT_ERR1:
4542: isp_prt(isp, ISP_LOGERR, xact1, XS_CHANNEL(xs),
4543: XS_TGT(xs), XS_LUN(xs));
4544: break;
4545:
4546: case RQCS_XACT_ERR2:
4547: isp_prt(isp, ISP_LOGERR, xact2,
4548: XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs));
4549: break;
4550:
4551: case RQCS_XACT_ERR3:
4552: isp_prt(isp, ISP_LOGERR, xact3,
4553: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4554: break;
4555:
4556: case RQCS_BAD_ENTRY:
4557: isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
4558: break;
4559:
4560: case RQCS_QUEUE_FULL:
4561: isp_prt(isp, ISP_LOGDEBUG0,
4562: "internal queues full for %d.%d.%d status 0x%x",
4563: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), *XS_STSP(xs));
4564:
4565: /*
4566: * If QFULL or some other status byte is set, then this
4567: * isn't an error, per se.
4568: *
4569: * Unfortunately, some QLogic f/w writers have, in
4570: * some cases, ommitted to *set* status to QFULL.
4571: *
4572:
4573: if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
4574: XS_SETERR(xs, HBA_NOERROR);
4575: return;
4576: }
4577:
4578: *
4579: *
4580: */
4581:
4582: *XS_STSP(xs) = SCSI_QFULL;
4583: XS_SETERR(xs, HBA_NOERROR);
4584: return;
4585:
4586: case RQCS_PHASE_SKIPPED:
4587: isp_prt(isp, ISP_LOGERR, pskip, XS_CHANNEL(xs),
4588: XS_TGT(xs), XS_LUN(xs));
4589: break;
4590:
4591: case RQCS_ARQS_FAILED:
4592: isp_prt(isp, ISP_LOGERR,
4593: "Auto Request Sense failed for %d.%d.%d",
4594: XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4595: if (XS_NOERR(xs)) {
4596: XS_SETERR(xs, HBA_ARQFAIL);
4597: }
4598: return;
4599:
4600: case RQCS_WIDE_FAILED:
4601: isp_prt(isp, ISP_LOGERR,
4602: "Wide Negotiation failed for %d.%d.%d",
4603: XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
4604: if (IS_SCSI(isp)) {
4605: sdparam *sdp = isp->isp_param;
4606: sdp += XS_CHANNEL(xs);
4607: sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
4608: sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
4609: isp->isp_update |= (1 << XS_CHANNEL(xs));
4610: }
4611: if (XS_NOERR(xs)) {
4612: XS_SETERR(xs, HBA_NOERROR);
4613: }
4614: return;
4615:
4616: case RQCS_SYNCXFER_FAILED:
4617: isp_prt(isp, ISP_LOGERR,
4618: "SDTR Message failed for target %d.%d.%d",
4619: XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
4620: if (IS_SCSI(isp)) {
4621: sdparam *sdp = isp->isp_param;
4622: sdp += XS_CHANNEL(xs);
4623: sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
4624: sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
4625: isp->isp_update |= (1 << XS_CHANNEL(xs));
4626: }
4627: break;
4628:
4629: case RQCS_LVD_BUSERR:
4630: isp_prt(isp, ISP_LOGERR,
4631: "Bad LVD condition while talking to %d.%d.%d",
4632: XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
4633: break;
4634:
4635: case RQCS_PORT_UNAVAILABLE:
4636: /*
4637: * No such port on the loop. Moral equivalent of SELTIMEO
4638: */
4639: case RQCS_PORT_LOGGED_OUT:
4640: /*
4641: * It was there (maybe)- treat as a selection timeout.
4642: */
4643: if ((sp->req_completion_status & 0xff) == RQCS_PORT_UNAVAILABLE)
4644: isp_prt(isp, ISP_LOGINFO,
4645: "port unavailable for target %d", XS_TGT(xs));
4646: else
4647: isp_prt(isp, ISP_LOGINFO,
4648: "port logout for target %d", XS_TGT(xs));
4649: /*
4650: * If we're on a local loop, force a LIP (which is overkill)
4651: * to force a re-login of this unit. If we're on fabric,
4652: * then we'll have to relogin as a matter of course.
4653: */
4654: if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
4655: FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
4656: mbreg_t mbs;
4657: mbs.param[0] = MBOX_INIT_LIP;
4658: isp_mboxcmd_qnw(isp, &mbs, 1);
4659: }
4660:
4661: /*
4662: * Probably overkill.
4663: */
4664: isp->isp_sendmarker = 1;
4665: FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
4666: isp_mark_getpdb_all(isp);
4667: isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
4668: if (XS_NOERR(xs)) {
4669: XS_SETERR(xs, HBA_SELTIMEOUT);
4670: }
4671: return;
4672:
4673: case RQCS_PORT_CHANGED:
4674: isp_prt(isp, ISP_LOGWARN,
4675: "port changed for target %d", XS_TGT(xs));
4676: if (XS_NOERR(xs)) {
4677: XS_SETERR(xs, HBA_SELTIMEOUT);
4678: }
4679: return;
4680:
4681: case RQCS_PORT_BUSY:
4682: isp_prt(isp, ISP_LOGWARN,
4683: "port busy for target %d", XS_TGT(xs));
4684: if (XS_NOERR(xs)) {
4685: XS_SETERR(xs, HBA_TGTBSY);
4686: }
4687: return;
4688:
4689: default:
4690: isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
4691: sp->req_completion_status);
4692: break;
4693: }
4694: if (XS_NOERR(xs)) {
4695: XS_SETERR(xs, HBA_BOTCH);
4696: }
4697: }
4698:
4699: static void
4700: isp_fastpost_complete(struct ispsoftc *isp, u_int16_t fph)
4701: {
4702: XS_T *xs;
4703:
4704: if (fph == 0) {
4705: return;
4706: }
4707: xs = isp_find_xs(isp, fph);
4708: if (xs == NULL) {
4709: isp_prt(isp, ISP_LOGWARN,
4710: "Command for fast post handle 0x%x not found", fph);
4711: return;
4712: }
4713: isp_destroy_handle(isp, fph);
4714:
4715: /*
4716: * Since we don't have a result queue entry item,
4717: * we must believe that SCSI status is zero and
4718: * that all data transferred.
4719: */
4720: XS_SET_STATE_STAT(isp, xs, NULL);
4721: XS_RESID(xs) = 0;
4722: *XS_STSP(xs) = SCSI_GOOD;
4723: if (XS_XFRLEN(xs)) {
4724: ISP_DMAFREE(isp, xs, fph);
4725: }
4726: if (isp->isp_nactive)
4727: isp->isp_nactive--;
4728: isp->isp_fphccmplt++;
4729: isp_done(xs);
4730: }
4731:
4732: static int
4733: isp_mbox_continue(struct ispsoftc *isp)
4734: {
4735: mbreg_t mbs;
4736: u_int16_t *ptr;
4737:
4738: switch (isp->isp_lastmbxcmd) {
4739: case MBOX_WRITE_RAM_WORD:
4740: case MBOX_READ_RAM_WORD:
4741: case MBOX_READ_RAM_WORD_EXTENDED:
4742: break;
4743: default:
4744: return (1);
4745: }
4746: if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
4747: isp->isp_mbxwrk0 = 0;
4748: return (-1);
4749: }
4750:
4751:
4752: /*
4753: * Clear the previous interrupt.
4754: */
4755: ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
4756: ISP_WRITE(isp, BIU_SEMA, 0);
4757:
4758: /*
4759: * Continue with next word.
4760: */
4761: ptr = isp->isp_mbxworkp;
4762: switch (isp->isp_lastmbxcmd) {
4763: case MBOX_WRITE_RAM_WORD:
4764: mbs.param[2] = *ptr++;
4765: mbs.param[1] = isp->isp_mbxwrk1++;
4766: break;
4767: case MBOX_READ_RAM_WORD:
4768: case MBOX_READ_RAM_WORD_EXTENDED:
4769: *ptr++ = isp->isp_mboxtmp[2];
4770: mbs.param[1] = isp->isp_mbxwrk1++;
4771: break;
4772: }
4773: isp->isp_mbxworkp = ptr;
4774: mbs.param[0] = isp->isp_lastmbxcmd;
4775: isp->isp_mbxwrk0 -= 1;
4776: isp_mboxcmd_qnw(isp, &mbs, 0);
4777: return (0);
4778: }
4779:
4780:
4781: #define HIBYT(x) ((x) >> 0x8)
4782: #define LOBYT(x) ((x) & 0xff)
4783: #define ISPOPMAP(a, b) (((a) << 8) | (b))
4784: static const u_int16_t mbpscsi[] = {
4785: ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */
4786: ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */
4787: ISPOPMAP(0x03, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */
4788: ISPOPMAP(0x1f, 0x01), /* 0x03: MBOX_DUMP_RAM */
4789: ISPOPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */
4790: ISPOPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */
4791: ISPOPMAP(0x3f, 0x3f), /* 0x06: MBOX_MAILBOX_REG_TEST */
4792: ISPOPMAP(0x03, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */
4793: ISPOPMAP(0x01, 0x0f), /* 0x08: MBOX_ABOUT_FIRMWARE */
4794: ISPOPMAP(0x00, 0x00), /* 0x09: */
4795: ISPOPMAP(0x00, 0x00), /* 0x0a: */
4796: ISPOPMAP(0x00, 0x00), /* 0x0b: */
4797: ISPOPMAP(0x00, 0x00), /* 0x0c: */
4798: ISPOPMAP(0x00, 0x00), /* 0x0d: */
4799: ISPOPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */
4800: ISPOPMAP(0x00, 0x00), /* 0x0f: */
4801: ISPOPMAP(0x1f, 0x1f), /* 0x10: MBOX_INIT_REQ_QUEUE */
4802: ISPOPMAP(0x3f, 0x3f), /* 0x11: MBOX_INIT_RES_QUEUE */
4803: ISPOPMAP(0x0f, 0x0f), /* 0x12: MBOX_EXECUTE_IOCB */
4804: ISPOPMAP(0x03, 0x03), /* 0x13: MBOX_WAKE_UP */
4805: ISPOPMAP(0x01, 0x3f), /* 0x14: MBOX_STOP_FIRMWARE */
4806: ISPOPMAP(0x0f, 0x0f), /* 0x15: MBOX_ABORT */
4807: ISPOPMAP(0x03, 0x03), /* 0x16: MBOX_ABORT_DEVICE */
4808: ISPOPMAP(0x07, 0x07), /* 0x17: MBOX_ABORT_TARGET */
4809: ISPOPMAP(0x07, 0x07), /* 0x18: MBOX_BUS_RESET */
4810: ISPOPMAP(0x03, 0x07), /* 0x19: MBOX_STOP_QUEUE */
4811: ISPOPMAP(0x03, 0x07), /* 0x1a: MBOX_START_QUEUE */
4812: ISPOPMAP(0x03, 0x07), /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
4813: ISPOPMAP(0x03, 0x07), /* 0x1c: MBOX_ABORT_QUEUE */
4814: ISPOPMAP(0x03, 0x4f), /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
4815: ISPOPMAP(0x00, 0x00), /* 0x1e: */
4816: ISPOPMAP(0x01, 0x07), /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
4817: ISPOPMAP(0x01, 0x07), /* 0x20: MBOX_GET_INIT_SCSI_ID */
4818: ISPOPMAP(0x01, 0x07), /* 0x21: MBOX_GET_SELECT_TIMEOUT */
4819: ISPOPMAP(0x01, 0xc7), /* 0x22: MBOX_GET_RETRY_COUNT */
4820: ISPOPMAP(0x01, 0x07), /* 0x23: MBOX_GET_TAG_AGE_LIMIT */
4821: ISPOPMAP(0x01, 0x03), /* 0x24: MBOX_GET_CLOCK_RATE */
4822: ISPOPMAP(0x01, 0x07), /* 0x25: MBOX_GET_ACT_NEG_STATE */
4823: ISPOPMAP(0x01, 0x07), /* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
4824: ISPOPMAP(0x01, 0x07), /* 0x27: MBOX_GET_PCI_PARAMS */
4825: ISPOPMAP(0x03, 0x4f), /* 0x28: MBOX_GET_TARGET_PARAMS */
4826: ISPOPMAP(0x03, 0x0f), /* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
4827: ISPOPMAP(0x01, 0x07), /* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
4828: ISPOPMAP(0x00, 0x00), /* 0x2b: */
4829: ISPOPMAP(0x00, 0x00), /* 0x2c: */
4830: ISPOPMAP(0x00, 0x00), /* 0x2d: */
4831: ISPOPMAP(0x00, 0x00), /* 0x2e: */
4832: ISPOPMAP(0x00, 0x00), /* 0x2f: */
4833: ISPOPMAP(0x03, 0x03), /* 0x30: MBOX_SET_INIT_SCSI_ID */
4834: ISPOPMAP(0x07, 0x07), /* 0x31: MBOX_SET_SELECT_TIMEOUT */
4835: ISPOPMAP(0xc7, 0xc7), /* 0x32: MBOX_SET_RETRY_COUNT */
4836: ISPOPMAP(0x07, 0x07), /* 0x33: MBOX_SET_TAG_AGE_LIMIT */
4837: ISPOPMAP(0x03, 0x03), /* 0x34: MBOX_SET_CLOCK_RATE */
4838: ISPOPMAP(0x07, 0x07), /* 0x35: MBOX_SET_ACT_NEG_STATE */
4839: ISPOPMAP(0x07, 0x07), /* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
4840: ISPOPMAP(0x07, 0x07), /* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
4841: ISPOPMAP(0x4f, 0x4f), /* 0x38: MBOX_SET_TARGET_PARAMS */
4842: ISPOPMAP(0x0f, 0x0f), /* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
4843: ISPOPMAP(0x07, 0x07), /* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
4844: ISPOPMAP(0x00, 0x00), /* 0x3b: */
4845: ISPOPMAP(0x00, 0x00), /* 0x3c: */
4846: ISPOPMAP(0x00, 0x00), /* 0x3d: */
4847: ISPOPMAP(0x00, 0x00), /* 0x3e: */
4848: ISPOPMAP(0x00, 0x00), /* 0x3f: */
4849: ISPOPMAP(0x01, 0x03), /* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
4850: ISPOPMAP(0x3f, 0x01), /* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
4851: ISPOPMAP(0x03, 0x07), /* 0x42: MBOX_EXEC_BIOS_IOCB */
4852: ISPOPMAP(0x00, 0x00), /* 0x43: */
4853: ISPOPMAP(0x00, 0x00), /* 0x44: */
4854: ISPOPMAP(0x03, 0x03), /* 0x45: SET SYSTEM PARAMETER */
4855: ISPOPMAP(0x01, 0x03), /* 0x46: GET SYSTEM PARAMETER */
4856: ISPOPMAP(0x00, 0x00), /* 0x47: */
4857: ISPOPMAP(0x01, 0xcf), /* 0x48: GET SCAM CONFIGURATION */
4858: ISPOPMAP(0xcf, 0xcf), /* 0x49: SET SCAM CONFIGURATION */
4859: ISPOPMAP(0x03, 0x03), /* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
4860: ISPOPMAP(0x01, 0x03), /* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
4861: ISPOPMAP(0x00, 0x00), /* 0x4c: */
4862: ISPOPMAP(0x00, 0x00), /* 0x4d: */
4863: ISPOPMAP(0x00, 0x00), /* 0x4e: */
4864: ISPOPMAP(0x00, 0x00), /* 0x4f: */
4865: ISPOPMAP(0xdf, 0xdf), /* 0x50: LOAD RAM A64 */
4866: ISPOPMAP(0xdf, 0xdf), /* 0x51: DUMP RAM A64 */
4867: ISPOPMAP(0xdf, 0xff), /* 0x52: INITIALIZE REQUEST QUEUE A64 */
4868: ISPOPMAP(0xef, 0xff), /* 0x53: INITIALIZE RESPONSE QUEUE A64 */
4869: ISPOPMAP(0xcf, 0x01), /* 0x54: EXECUTE IOCB A64 */
4870: ISPOPMAP(0x07, 0x01), /* 0x55: ENABLE TARGET MODE */
4871: ISPOPMAP(0x03, 0x0f), /* 0x56: GET TARGET STATUS */
4872: ISPOPMAP(0x00, 0x00), /* 0x57: */
4873: ISPOPMAP(0x00, 0x00), /* 0x58: */
4874: ISPOPMAP(0x00, 0x00), /* 0x59: */
4875: ISPOPMAP(0x03, 0x03), /* 0x5a: SET DATA OVERRUN RECOVERY MODE */
4876: ISPOPMAP(0x01, 0x03), /* 0x5b: GET DATA OVERRUN RECOVERY MODE */
4877: ISPOPMAP(0x0f, 0x0f), /* 0x5c: SET HOST DATA */
4878: ISPOPMAP(0x01, 0x01) /* 0x5d: GET NOST DATA */
4879: };
4880:
4881: #ifdef SMALL_KERNEL
4882: #define ISP_STRIPPED
4883: #endif
4884:
4885: #ifndef ISP_STRIPPED
4886: static char *scsi_mbcmd_names[] = {
4887: "NO-OP",
4888: "LOAD RAM",
4889: "EXEC FIRMWARE",
4890: "DUMP RAM",
4891: "WRITE RAM WORD",
4892: "READ RAM WORD",
4893: "MAILBOX REG TEST",
4894: "VERIFY CHECKSUM",
4895: "ABOUT FIRMWARE",
4896: NULL,
4897: NULL,
4898: NULL,
4899: NULL,
4900: NULL,
4901: "CHECK FIRMWARE",
4902: NULL,
4903: "INIT REQUEST QUEUE",
4904: "INIT RESULT QUEUE",
4905: "EXECUTE IOCB",
4906: "WAKE UP",
4907: "STOP FIRMWARE",
4908: "ABORT",
4909: "ABORT DEVICE",
4910: "ABORT TARGET",
4911: "BUS RESET",
4912: "STOP QUEUE",
4913: "START QUEUE",
4914: "SINGLE STEP QUEUE",
4915: "ABORT QUEUE",
4916: "GET DEV QUEUE STATUS",
4917: NULL,
4918: "GET FIRMWARE STATUS",
4919: "GET INIT SCSI ID",
4920: "GET SELECT TIMEOUT",
4921: "GET RETRY COUNT",
4922: "GET TAG AGE LIMIT",
4923: "GET CLOCK RATE",
4924: "GET ACT NEG STATE",
4925: "GET ASYNC DATA SETUP TIME",
4926: "GET PCI PARAMS",
4927: "GET TARGET PARAMS",
4928: "GET DEV QUEUE PARAMS",
4929: "GET RESET DELAY PARAMS",
4930: NULL,
4931: NULL,
4932: NULL,
4933: NULL,
4934: NULL,
4935: "SET INIT SCSI ID",
4936: "SET SELECT TIMEOUT",
4937: "SET RETRY COUNT",
4938: "SET TAG AGE LIMIT",
4939: "SET CLOCK RATE",
4940: "SET ACT NEG STATE",
4941: "SET ASYNC DATA SETUP TIME",
4942: "SET PCI CONTROL PARAMS",
4943: "SET TARGET PARAMS",
4944: "SET DEV QUEUE PARAMS",
4945: "SET RESET DELAY PARAMS",
4946: NULL,
4947: NULL,
4948: NULL,
4949: NULL,
4950: NULL,
4951: "RETURN BIOS BLOCK ADDR",
4952: "WRITE FOUR RAM WORDS",
4953: "EXEC BIOS IOCB",
4954: NULL,
4955: NULL,
4956: "SET SYSTEM PARAMETER",
4957: "GET SYSTEM PARAMETER",
4958: NULL,
4959: "GET SCAM CONFIGURATION",
4960: "SET SCAM CONFIGURATION",
4961: "SET FIRMWARE FEATURES",
4962: "GET FIRMWARE FEATURES",
4963: NULL,
4964: NULL,
4965: NULL,
4966: NULL,
4967: "LOAD RAM A64",
4968: "DUMP RAM A64",
4969: "INITIALIZE REQUEST QUEUE A64",
4970: "INITIALIZE RESPONSE QUEUE A64",
4971: "EXECUTE IOCB A64",
4972: "ENABLE TARGET MODE",
4973: "GET TARGET MODE STATE",
4974: NULL,
4975: NULL,
4976: NULL,
4977: "SET DATA OVERRUN RECOVERY MODE",
4978: "GET DATA OVERRUN RECOVERY MODE",
4979: "SET HOST DATA",
4980: "GET NOST DATA",
4981: };
4982: #endif
4983:
4984: static const u_int16_t mbpfc[] = {
4985: ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */
4986: ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */
4987: ISPOPMAP(0x03, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */
4988: ISPOPMAP(0xdf, 0x01), /* 0x03: MBOX_DUMP_RAM */
4989: ISPOPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */
4990: ISPOPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */
4991: ISPOPMAP(0xff, 0xff), /* 0x06: MBOX_MAILBOX_REG_TEST */
4992: ISPOPMAP(0x03, 0x05), /* 0x07: MBOX_VERIFY_CHECKSUM */
4993: ISPOPMAP(0x01, 0x4f), /* 0x08: MBOX_ABOUT_FIRMWARE */
4994: ISPOPMAP(0xdf, 0x01), /* 0x09: LOAD RAM */
4995: ISPOPMAP(0xdf, 0x01), /* 0x0a: DUMP RAM */
4996: ISPOPMAP(0x00, 0x00), /* 0x0b: */
4997: ISPOPMAP(0x00, 0x00), /* 0x0c: */
4998: ISPOPMAP(0x00, 0x00), /* 0x0d: */
4999: ISPOPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */
5000: ISPOPMAP(0x03, 0x07), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED(1) */
5001: ISPOPMAP(0x1f, 0x11), /* 0x10: MBOX_INIT_REQ_QUEUE */
5002: ISPOPMAP(0x2f, 0x21), /* 0x11: MBOX_INIT_RES_QUEUE */
5003: ISPOPMAP(0x0f, 0x01), /* 0x12: MBOX_EXECUTE_IOCB */
5004: ISPOPMAP(0x03, 0x03), /* 0x13: MBOX_WAKE_UP */
5005: ISPOPMAP(0x01, 0xff), /* 0x14: MBOX_STOP_FIRMWARE */
5006: ISPOPMAP(0x4f, 0x01), /* 0x15: MBOX_ABORT */
5007: ISPOPMAP(0x07, 0x01), /* 0x16: MBOX_ABORT_DEVICE */
5008: ISPOPMAP(0x07, 0x01), /* 0x17: MBOX_ABORT_TARGET */
5009: ISPOPMAP(0x03, 0x03), /* 0x18: MBOX_BUS_RESET */
5010: ISPOPMAP(0x07, 0x05), /* 0x19: MBOX_STOP_QUEUE */
5011: ISPOPMAP(0x07, 0x05), /* 0x1a: MBOX_START_QUEUE */
5012: ISPOPMAP(0x07, 0x05), /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
5013: ISPOPMAP(0x07, 0x05), /* 0x1c: MBOX_ABORT_QUEUE */
5014: ISPOPMAP(0x07, 0x03), /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
5015: ISPOPMAP(0x00, 0x00), /* 0x1e: */
5016: ISPOPMAP(0x01, 0x07), /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
5017: ISPOPMAP(0x01, 0x4f), /* 0x20: MBOX_GET_LOOP_ID */
5018: ISPOPMAP(0x00, 0x00), /* 0x21: */
5019: ISPOPMAP(0x01, 0x07), /* 0x22: MBOX_GET_RETRY_COUNT */
5020: ISPOPMAP(0x00, 0x00), /* 0x23: */
5021: ISPOPMAP(0x00, 0x00), /* 0x24: */
5022: ISPOPMAP(0x00, 0x00), /* 0x25: */
5023: ISPOPMAP(0x00, 0x00), /* 0x26: */
5024: ISPOPMAP(0x00, 0x00), /* 0x27: */
5025: ISPOPMAP(0x01, 0x03), /* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
5026: ISPOPMAP(0x03, 0x07), /* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
5027: ISPOPMAP(0x00, 0x00), /* 0x2a: */
5028: ISPOPMAP(0x00, 0x00), /* 0x2b: */
5029: ISPOPMAP(0x00, 0x00), /* 0x2c: */
5030: ISPOPMAP(0x00, 0x00), /* 0x2d: */
5031: ISPOPMAP(0x00, 0x00), /* 0x2e: */
5032: ISPOPMAP(0x00, 0x00), /* 0x2f: */
5033: ISPOPMAP(0x00, 0x00), /* 0x30: */
5034: ISPOPMAP(0x00, 0x00), /* 0x31: */
5035: ISPOPMAP(0x07, 0x07), /* 0x32: MBOX_SET_RETRY_COUNT */
5036: ISPOPMAP(0x00, 0x00), /* 0x33: */
5037: ISPOPMAP(0x00, 0x00), /* 0x34: */
5038: ISPOPMAP(0x00, 0x00), /* 0x35: */
5039: ISPOPMAP(0x00, 0x00), /* 0x36: */
5040: ISPOPMAP(0x00, 0x00), /* 0x37: */
5041: ISPOPMAP(0x0f, 0x01), /* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
5042: ISPOPMAP(0x0f, 0x07), /* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
5043: ISPOPMAP(0x00, 0x00), /* 0x3a: */
5044: ISPOPMAP(0x00, 0x00), /* 0x3b: */
5045: ISPOPMAP(0x00, 0x00), /* 0x3c: */
5046: ISPOPMAP(0x00, 0x00), /* 0x3d: */
5047: ISPOPMAP(0x00, 0x00), /* 0x3e: */
5048: ISPOPMAP(0x00, 0x00), /* 0x3f: */
5049: ISPOPMAP(0x03, 0x01), /* 0x40: MBOX_LOOP_PORT_BYPASS */
5050: ISPOPMAP(0x03, 0x01), /* 0x41: MBOX_LOOP_PORT_ENABLE */
5051: ISPOPMAP(0x03, 0x07), /* 0x42: MBOX_GET_RESOURCE_COUNTS */
5052: ISPOPMAP(0x01, 0x01), /* 0x43: MBOX_REQUEST_NON_PARTICIPATING_MODE */
5053: ISPOPMAP(0x00, 0x00), /* 0x44: */
5054: ISPOPMAP(0x00, 0x00), /* 0x45: */
5055: ISPOPMAP(0x00, 0x00), /* 0x46: */
5056: ISPOPMAP(0xcf, 0x03), /* 0x47: GET PORT_DATABASE ENHANCED */
5057: ISPOPMAP(0x00, 0x00), /* 0x48: */
5058: ISPOPMAP(0x00, 0x00), /* 0x49: */
5059: ISPOPMAP(0x00, 0x00), /* 0x4a: */
5060: ISPOPMAP(0x00, 0x00), /* 0x4b: */
5061: ISPOPMAP(0x00, 0x00), /* 0x4c: */
5062: ISPOPMAP(0x00, 0x00), /* 0x4d: */
5063: ISPOPMAP(0x00, 0x00), /* 0x4e: */
5064: ISPOPMAP(0x00, 0x00), /* 0x4f: */
5065: ISPOPMAP(0x00, 0x00), /* 0x50: */
5066: ISPOPMAP(0x00, 0x00), /* 0x51: */
5067: ISPOPMAP(0x00, 0x00), /* 0x52: */
5068: ISPOPMAP(0x00, 0x00), /* 0x53: */
5069: ISPOPMAP(0xcf, 0x01), /* 0x54: EXECUTE IOCB A64 */
5070: ISPOPMAP(0x00, 0x00), /* 0x55: */
5071: ISPOPMAP(0x00, 0x00), /* 0x56: */
5072: ISPOPMAP(0x00, 0x00), /* 0x57: */
5073: ISPOPMAP(0x00, 0x00), /* 0x58: */
5074: ISPOPMAP(0x00, 0x00), /* 0x59: */
5075: ISPOPMAP(0x00, 0x00), /* 0x5a: */
5076: ISPOPMAP(0x03, 0x01), /* 0x5b: MBOX_DRIVER_HEARTBEAT */
5077: ISPOPMAP(0xcf, 0x01), /* 0x5c: MBOX_FW_HEARTBEAT */
5078: ISPOPMAP(0x07, 0x03), /* 0x5d: MBOX_GET_SET_DATA_RATE */
5079: ISPOPMAP(0x00, 0x00), /* 0x5e: */
5080: ISPOPMAP(0x00, 0x00), /* 0x5f: */
5081: ISPOPMAP(0xfd, 0x31), /* 0x60: MBOX_INIT_FIRMWARE */
5082: ISPOPMAP(0x00, 0x00), /* 0x61: */
5083: ISPOPMAP(0x01, 0x01), /* 0x62: MBOX_INIT_LIP */
5084: ISPOPMAP(0xcd, 0x03), /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
5085: ISPOPMAP(0xcf, 0x01), /* 0x64: MBOX_GET_PORT_DB */
5086: ISPOPMAP(0x07, 0x01), /* 0x65: MBOX_CLEAR_ACA */
5087: ISPOPMAP(0x07, 0x01), /* 0x66: MBOX_TARGET_RESET */
5088: ISPOPMAP(0x07, 0x01), /* 0x67: MBOX_CLEAR_TASK_SET */
5089: ISPOPMAP(0x07, 0x01), /* 0x68: MBOX_ABORT_TASK_SET */
5090: ISPOPMAP(0x01, 0x07), /* 0x69: MBOX_GET_FW_STATE */
5091: ISPOPMAP(0x03, 0xcf), /* 0x6a: MBOX_GET_PORT_NAME */
5092: ISPOPMAP(0xcf, 0x01), /* 0x6b: MBOX_GET_LINK_STATUS */
5093: ISPOPMAP(0x0f, 0x01), /* 0x6c: MBOX_INIT_LIP_RESET */
5094: ISPOPMAP(0x00, 0x00), /* 0x6d: */
5095: ISPOPMAP(0xcf, 0x03), /* 0x6e: MBOX_SEND_SNS */
5096: ISPOPMAP(0x0f, 0x07), /* 0x6f: MBOX_FABRIC_LOGIN */
5097: ISPOPMAP(0x03, 0x01), /* 0x70: MBOX_SEND_CHANGE_REQUEST */
5098: ISPOPMAP(0x03, 0x03), /* 0x71: MBOX_FABRIC_LOGOUT */
5099: ISPOPMAP(0x0f, 0x0f), /* 0x72: MBOX_INIT_LIP_LOGIN */
5100: ISPOPMAP(0x00, 0x00), /* 0x73: */
5101: ISPOPMAP(0x07, 0x01), /* 0x74: LOGIN LOOP PORT */
5102: ISPOPMAP(0xcf, 0x03), /* 0x75: GET PORT/NODE NAME LIST */
5103: ISPOPMAP(0x4f, 0x01), /* 0x76: SET VENDOR ID */
5104: ISPOPMAP(0xcd, 0x01), /* 0x77: INITIALIZE IP MAILBOX */
5105: ISPOPMAP(0x00, 0x00), /* 0x78: */
5106: ISPOPMAP(0x00, 0x00), /* 0x79: */
5107: ISPOPMAP(0x00, 0x00), /* 0x7a: */
5108: ISPOPMAP(0x00, 0x00), /* 0x7b: */
5109: ISPOPMAP(0x4f, 0x03), /* 0x7c: Get ID List */
5110: ISPOPMAP(0xcf, 0x01), /* 0x7d: SEND LFA */
5111: ISPOPMAP(0x07, 0x01) /* 0x7e: Lun RESET */
5112: };
5113: /*
5114: * Footnotes
5115: *
5116: * (1): this sets bits 21..16 in mailbox register #8, which we nominally
5117: * do not access at this time in the core driver. The caller is
5118: * responsible for setting this register first (Gross!).
5119: */
5120:
5121: #ifndef ISP_STRIPPED
5122: static char *fc_mbcmd_names[] = {
5123: "NO-OP",
5124: "LOAD RAM",
5125: "EXEC FIRMWARE",
5126: "DUMP RAM",
5127: "WRITE RAM WORD",
5128: "READ RAM WORD",
5129: "MAILBOX REG TEST",
5130: "VERIFY CHECKSUM",
5131: "ABOUT FIRMWARE",
5132: "LOAD RAM",
5133: "DUMP RAM",
5134: NULL,
5135: NULL,
5136: "READ RAM WORD EXTENDED",
5137: "CHECK FIRMWARE",
5138: NULL,
5139: "INIT REQUEST QUEUE",
5140: "INIT RESULT QUEUE",
5141: "EXECUTE IOCB",
5142: "WAKE UP",
5143: "STOP FIRMWARE",
5144: "ABORT",
5145: "ABORT DEVICE",
5146: "ABORT TARGET",
5147: "BUS RESET",
5148: "STOP QUEUE",
5149: "START QUEUE",
5150: "SINGLE STEP QUEUE",
5151: "ABORT QUEUE",
5152: "GET DEV QUEUE STATUS",
5153: NULL,
5154: "GET FIRMWARE STATUS",
5155: "GET LOOP ID",
5156: NULL,
5157: "GET RETRY COUNT",
5158: NULL,
5159: NULL,
5160: NULL,
5161: NULL,
5162: NULL,
5163: "GET FIRMWARE OPTIONS",
5164: "GET PORT QUEUE PARAMS",
5165: NULL,
5166: NULL,
5167: NULL,
5168: NULL,
5169: NULL,
5170: NULL,
5171: NULL,
5172: NULL,
5173: "SET RETRY COUNT",
5174: NULL,
5175: NULL,
5176: NULL,
5177: NULL,
5178: NULL,
5179: "SET FIRMWARE OPTIONS",
5180: "SET PORT QUEUE PARAMS",
5181: NULL,
5182: NULL,
5183: NULL,
5184: NULL,
5185: NULL,
5186: NULL,
5187: "LOOP PORT BYPASS",
5188: "LOOP PORT ENABLE",
5189: "GET RESOURCE COUNTS",
5190: "REQUEST NON PARTICIPATING MODE",
5191: NULL,
5192: NULL,
5193: NULL,
5194: "GET PORT DATABASE,, ENHANCED",
5195: NULL,
5196: NULL,
5197: NULL,
5198: NULL,
5199: NULL,
5200: NULL,
5201: NULL,
5202: NULL,
5203: NULL,
5204: NULL,
5205: NULL,
5206: NULL,
5207: "EXECUTE IOCB A64",
5208: NULL,
5209: NULL,
5210: NULL,
5211: NULL,
5212: NULL,
5213: NULL,
5214: "DRIVER HEARTBEAT",
5215: NULL,
5216: "GET/SET DATA RATE",
5217: NULL,
5218: NULL,
5219: "INIT FIRMWARE",
5220: NULL,
5221: "INIT LIP",
5222: "GET FC-AL POSITION MAP",
5223: "GET PORT DATABASE",
5224: "CLEAR ACA",
5225: "TARGET RESET",
5226: "CLEAR TASK SET",
5227: "ABORT TASK SET",
5228: "GET FW STATE",
5229: "GET PORT NAME",
5230: "GET LINK STATUS",
5231: "INIT LIP RESET",
5232: NULL,
5233: "SEND SNS",
5234: "FABRIC LOGIN",
5235: "SEND CHANGE REQUEST",
5236: "FABRIC LOGOUT",
5237: "INIT LIP LOGIN",
5238: NULL,
5239: "LOGIN LOOP PORT",
5240: "GET PORT/NODE NAME LIST",
5241: "SET VENDOR ID",
5242: "INITIALIZE IP MAILBOX",
5243: NULL,
5244: NULL,
5245: NULL,
5246: NULL,
5247: "Get ID List",
5248: "SEND LFA",
5249: "Lun RESET"
5250: };
5251: #endif
5252:
5253: static void
5254: isp_mboxcmd_qnw(struct ispsoftc *isp, mbreg_t *mbp, int nodelay)
5255: {
5256: unsigned int lim, ibits, obits, box, opcode;
5257: const u_int16_t *mcp;
5258:
5259: if (IS_FC(isp)) {
5260: mcp = mbpfc;
5261: lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
5262: } else {
5263: mcp = mbpscsi;
5264: lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
5265: }
5266: opcode = mbp->param[0];
5267: ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
5268: obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
5269: for (box = 0; box < MAX_MAILBOX; box++) {
5270: if (ibits & (1 << box)) {
5271: ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
5272: }
5273: if (nodelay == 0) {
5274: isp->isp_mboxtmp[box] = mbp->param[box] = 0;
5275: }
5276: }
5277: if (nodelay == 0) {
5278: isp->isp_lastmbxcmd = opcode;
5279: isp->isp_obits = obits;
5280: isp->isp_mboxbsy = 1;
5281: }
5282: ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
5283: /*
5284: * Oddly enough, if we're not delaying for an answer,
5285: * delay a bit to give the f/w a chance to pick up the
5286: * command.
5287: */
5288: if (nodelay) {
5289: USEC_DELAY(1000);
5290: }
5291: }
5292:
5293: static void
5294: isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
5295: {
5296: char *cname, *xname, tname[16], mname[16];
5297: unsigned int lim, ibits, obits, box, opcode;
5298: const u_int16_t *mcp;
5299:
5300: if (IS_FC(isp)) {
5301: mcp = mbpfc;
5302: lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
5303: } else {
5304: mcp = mbpscsi;
5305: lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
5306: }
5307:
5308: if ((opcode = mbp->param[0]) >= lim) {
5309: mbp->param[0] = MBOX_INVALID_COMMAND;
5310: isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
5311: return;
5312: }
5313:
5314: ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
5315: obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
5316:
5317: if (ibits == 0 && obits == 0) {
5318: mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
5319: isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
5320: return;
5321: }
5322:
5323: /*
5324: * Get exclusive usage of mailbox registers.
5325: */
5326: MBOX_ACQUIRE(isp);
5327:
5328: for (box = 0; box < MAX_MAILBOX; box++) {
5329: if (ibits & (1 << box)) {
5330: ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
5331: }
5332: isp->isp_mboxtmp[box] = mbp->param[box] = 0;
5333: }
5334:
5335: isp->isp_lastmbxcmd = opcode;
5336:
5337: /*
5338: * We assume that we can't overwrite a previous command.
5339: */
5340: isp->isp_obits = obits;
5341: isp->isp_mboxbsy = 1;
5342:
5343: /*
5344: * Set Host Interrupt condition so that RISC will pick up mailbox regs.
5345: */
5346: ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
5347:
5348: /*
5349: * While we haven't finished the command, spin our wheels here.
5350: */
5351: MBOX_WAIT_COMPLETE(isp);
5352:
5353: if (isp->isp_mboxbsy) {
5354: /*
5355: * Command timed out.
5356: */
5357: isp->isp_mboxbsy = 0;
5358: MBOX_RELEASE(isp);
5359: return;
5360: }
5361:
5362: /*
5363: * Copy back output registers.
5364: */
5365: for (box = 0; box < MAX_MAILBOX; box++) {
5366: if (obits & (1 << box)) {
5367: mbp->param[box] = isp->isp_mboxtmp[box];
5368: }
5369: }
5370:
5371: MBOX_RELEASE(isp);
5372:
5373: if (logmask == 0 || opcode == MBOX_EXEC_FIRMWARE) {
5374: return;
5375: }
5376: #ifdef ISP_STRIPPED
5377: cname = NULL;
5378: #else
5379: cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
5380: #endif
5381: if (cname == NULL) {
5382: cname = tname;
5383: SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
5384: }
5385:
5386: /*
5387: * Just to be chatty here...
5388: */
5389: xname = NULL;
5390: switch (mbp->param[0]) {
5391: case MBOX_COMMAND_COMPLETE:
5392: break;
5393: case MBOX_INVALID_COMMAND:
5394: if (logmask & MBLOGMASK(MBOX_COMMAND_COMPLETE))
5395: xname = "INVALID COMMAND";
5396: break;
5397: case MBOX_HOST_INTERFACE_ERROR:
5398: if (logmask & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR))
5399: xname = "HOST INTERFACE ERROR";
5400: break;
5401: case MBOX_TEST_FAILED:
5402: if (logmask & MBLOGMASK(MBOX_TEST_FAILED))
5403: xname = "TEST FAILED";
5404: break;
5405: case MBOX_COMMAND_ERROR:
5406: if (logmask & MBLOGMASK(MBOX_COMMAND_ERROR))
5407: xname = "COMMAND ERROR";
5408: break;
5409: case MBOX_COMMAND_PARAM_ERROR:
5410: if (logmask & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR))
5411: xname = "COMMAND PARAMETER ERROR";
5412: break;
5413: case MBOX_LOOP_ID_USED:
5414: if (logmask & MBLOGMASK(MBOX_LOOP_ID_USED))
5415: xname = "LOOP ID ALREADY IN USE";
5416: break;
5417: case MBOX_PORT_ID_USED:
5418: if (logmask & MBLOGMASK(MBOX_PORT_ID_USED))
5419: xname = "PORT ID ALREADY IN USE";
5420: break;
5421: case MBOX_ALL_IDS_USED:
5422: if (logmask & MBLOGMASK(MBOX_ALL_IDS_USED))
5423: xname = "ALL LOOP IDS IN USE";
5424: break;
5425: case 0: /* special case */
5426: xname = "TIMEOUT";
5427: break;
5428: default:
5429: SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
5430: xname = mname;
5431: break;
5432: }
5433: if (xname)
5434: isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
5435: cname, xname);
5436: }
5437:
5438: static void
5439: isp_fw_state(struct ispsoftc *isp)
5440: {
5441: if (IS_FC(isp)) {
5442: mbreg_t mbs;
5443: fcparam *fcp = isp->isp_param;
5444:
5445: mbs.param[0] = MBOX_GET_FW_STATE;
5446: isp_mboxcmd(isp, &mbs, MBLOGALL);
5447: if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
5448: fcp->isp_fwstate = mbs.param[1];
5449: }
5450: }
5451: }
5452:
5453: static void
5454: isp_update(struct ispsoftc *isp)
5455: {
5456: int bus, upmask;
5457:
5458: for (bus = 0, upmask = isp->isp_update; upmask != 0; bus++) {
5459: if (upmask & (1 << bus)) {
5460: isp_update_bus(isp, bus);
5461: }
5462: upmask &= ~(1 << bus);
5463: }
5464: }
5465:
5466: static void
5467: isp_update_bus(struct ispsoftc *isp, int bus)
5468: {
5469: int tgt;
5470: mbreg_t mbs;
5471: sdparam *sdp;
5472:
5473: isp->isp_update &= ~(1 << bus);
5474: if (IS_FC(isp)) {
5475: /*
5476: * There are no 'per-bus' settings for Fibre Channel.
5477: */
5478: return;
5479: }
5480: sdp = isp->isp_param;
5481: sdp += bus;
5482:
5483: for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
5484: u_int16_t flags, period, offset;
5485: int get;
5486:
5487: if (sdp->isp_devparam[tgt].dev_enable == 0) {
5488: sdp->isp_devparam[tgt].dev_update = 0;
5489: sdp->isp_devparam[tgt].dev_refresh = 0;
5490: isp_prt(isp, ISP_LOGDEBUG0,
5491: "skipping target %d bus %d update", tgt, bus);
5492: continue;
5493: }
5494: /*
5495: * If the goal is to update the status of the device,
5496: * take what's in goal_flags and try and set the device
5497: * toward that. Otherwise, if we're just refreshing the
5498: * current device state, get the current parameters.
5499: */
5500:
5501: /*
5502: * Refresh overrides set
5503: */
5504: if (sdp->isp_devparam[tgt].dev_refresh) {
5505: mbs.param[0] = MBOX_GET_TARGET_PARAMS;
5506: sdp->isp_devparam[tgt].dev_refresh = 0;
5507: get = 1;
5508: } else if (sdp->isp_devparam[tgt].dev_update) {
5509: mbs.param[0] = MBOX_SET_TARGET_PARAMS;
5510: /*
5511: * Make sure goal_flags has "Renegotiate on Error"
5512: * on and "Freeze Queue on Error" off.
5513: */
5514: sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
5515: sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
5516:
5517: mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
5518:
5519: /*
5520: * Insist that PARITY must be enabled
5521: * if SYNC or WIDE is enabled.
5522: */
5523: if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
5524: mbs.param[2] |= DPARM_PARITY;
5525: }
5526:
5527: if ((mbs.param[2] & DPARM_SYNC) == 0) {
5528: mbs.param[3] = 0;
5529: } else {
5530: mbs.param[3] =
5531: (sdp->isp_devparam[tgt].goal_offset << 8) |
5532: (sdp->isp_devparam[tgt].goal_period);
5533: }
5534: /*
5535: * A command completion later that has
5536: * RQSTF_NEGOTIATION set can cause
5537: * the dev_refresh/announce cycle also.
5538: *
5539: * Note: It is really important to update our current
5540: * flags with at least the state of TAG capabilities-
5541: * otherwise we might try and send a tagged command
5542: * when we have it all turned off. So change it here
5543: * to say that current already matches goal.
5544: */
5545: sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
5546: sdp->isp_devparam[tgt].actv_flags |=
5547: (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
5548: isp_prt(isp, ISP_LOGDEBUG0,
5549: "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
5550: bus, tgt, mbs.param[2], mbs.param[3] >> 8,
5551: mbs.param[3] & 0xff);
5552: sdp->isp_devparam[tgt].dev_update = 0;
5553: sdp->isp_devparam[tgt].dev_refresh = 1;
5554: get = 0;
5555: } else {
5556: continue;
5557: }
5558: mbs.param[1] = (bus << 15) | (tgt << 8);
5559: isp_mboxcmd(isp, &mbs, MBLOGALL);
5560: if (get == 0) {
5561: isp->isp_sendmarker |= (1 << bus);
5562: continue;
5563: }
5564: flags = mbs.param[2];
5565: period = mbs.param[3] & 0xff;
5566: offset = mbs.param[3] >> 8;
5567: sdp->isp_devparam[tgt].actv_flags = flags;
5568: sdp->isp_devparam[tgt].actv_period = period;
5569: sdp->isp_devparam[tgt].actv_offset = offset;
5570: get = (bus << 16) | tgt;
5571: (void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get);
5572: }
5573:
5574: for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
5575: if (sdp->isp_devparam[tgt].dev_update ||
5576: sdp->isp_devparam[tgt].dev_refresh) {
5577: isp->isp_update |= (1 << bus);
5578: break;
5579: }
5580: }
5581: }
5582:
5583: #ifndef DEFAULT_FRAMESIZE
5584: #define DEFAULT_FRAMESIZE(isp) ICB_DFLT_FRMLEN
5585: #endif
5586: #ifndef DEFAULT_EXEC_THROTTLE
5587: #define DEFAULT_EXEC_THROTTLE(isp) ISP_EXEC_THROTTLE
5588: #endif
5589:
5590: static void
5591: isp_setdfltparm(struct ispsoftc *isp, int channel)
5592: {
5593: int tgt;
5594: mbreg_t mbs;
5595: sdparam *sdp;
5596:
5597: if (IS_FC(isp)) {
5598: fcparam *fcp = (fcparam *) isp->isp_param;
5599: int nvfail;
5600:
5601: fcp += channel;
5602: if (fcp->isp_gotdparms) {
5603: return;
5604: }
5605: fcp->isp_gotdparms = 1;
5606: fcp->isp_maxfrmlen = DEFAULT_FRAMESIZE(isp);
5607: fcp->isp_maxalloc = ICB_DFLT_ALLOC;
5608: fcp->isp_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
5609: fcp->isp_retry_delay = ICB_DFLT_RDELAY;
5610: fcp->isp_retry_count = ICB_DFLT_RCOUNT;
5611: /* Platform specific.... */
5612: fcp->isp_loopid = DEFAULT_LOOPID(isp);
5613: fcp->isp_nodewwn = DEFAULT_NODEWWN(isp);
5614: fcp->isp_portwwn = DEFAULT_PORTWWN(isp);
5615: fcp->isp_fwoptions = 0;
5616: fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
5617: fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
5618: fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
5619: #ifndef ISP_NO_FASTPOST_FC
5620: fcp->isp_fwoptions |= ICBOPT_FAST_POST;
5621: #endif
5622: if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
5623: fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
5624:
5625: /*
5626: * Make sure this is turned off now until we get
5627: * extended options from NVRAM
5628: */
5629: fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
5630:
5631: /*
5632: * Now try and read NVRAM unless told to not do so.
5633: * This will set fcparam's isp_nodewwn && isp_portwwn.
5634: */
5635: if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
5636: nvfail = isp_read_nvram(isp);
5637: if (nvfail)
5638: isp->isp_confopts |= ISP_CFG_NONVRAM;
5639: } else {
5640: nvfail = 1;
5641: }
5642: /*
5643: * Set node && port to override platform set defaults
5644: * unless the nvram read failed (or none was done),
5645: * or the platform code wants to use what had been
5646: * set in the defaults.
5647: */
5648: if (nvfail) {
5649: isp->isp_confopts |= ISP_CFG_OWNWWPN|ISP_CFG_OWNWWNN;
5650: }
5651: if (isp->isp_confopts & ISP_CFG_OWNWWNN) {
5652: isp_prt(isp, ISP_LOGCONFIG, "Using Node WWN 0x%08x%08x",
5653: (u_int32_t) (DEFAULT_NODEWWN(isp) >> 32),
5654: (u_int32_t) (DEFAULT_NODEWWN(isp) & 0xffffffff));
5655: ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
5656: } else {
5657: /*
5658: * We always start out with values derived
5659: * from NVRAM or our platform default.
5660: */
5661: ISP_NODEWWN(isp) = fcp->isp_nodewwn;
5662: }
5663: if (isp->isp_confopts & ISP_CFG_OWNWWPN) {
5664: isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x",
5665: (u_int32_t) (DEFAULT_PORTWWN(isp) >> 32),
5666: (u_int32_t) (DEFAULT_PORTWWN(isp) & 0xffffffff));
5667: ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
5668: } else {
5669: /*
5670: * We always start out with values derived
5671: * from NVRAM or our platform default.
5672: */
5673: ISP_PORTWWN(isp) = fcp->isp_portwwn;
5674: }
5675: return;
5676: }
5677:
5678: sdp = (sdparam *) isp->isp_param;
5679: sdp += channel;
5680:
5681: /*
5682: * Been there, done that, got the T-shirt...
5683: */
5684: if (sdp->isp_gotdparms) {
5685: return;
5686: }
5687: sdp->isp_gotdparms = 1;
5688:
5689: /*
5690: * Establish some default parameters.
5691: */
5692: sdp->isp_cmd_dma_burst_enable = 0;
5693: sdp->isp_data_dma_burst_enabl = 1;
5694: sdp->isp_fifo_threshold = 0;
5695: sdp->isp_initiator_id = DEFAULT_IID(isp);
5696: if (isp->isp_type >= ISP_HA_SCSI_1040) {
5697: sdp->isp_async_data_setup = 9;
5698: } else {
5699: sdp->isp_async_data_setup = 6;
5700: }
5701: sdp->isp_selection_timeout = 250;
5702: sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
5703: sdp->isp_tag_aging = 8;
5704: sdp->isp_bus_reset_delay = 5;
5705: /*
5706: * Don't retry selection, busy or queue full automatically- reflect
5707: * these back to us.
5708: */
5709: sdp->isp_retry_count = 0;
5710: sdp->isp_retry_delay = 0;
5711:
5712: for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
5713: sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
5714: sdp->isp_devparam[tgt].dev_enable = 1;
5715: }
5716:
5717: /*
5718: * If we've not been told to avoid reading NVRAM, try and read it.
5719: * If we're successful reading it, we can then return because NVRAM
5720: * will tell us what the desired settings are. Otherwise, we establish
5721: * some reasonable 'fake' nvram and goal defaults.
5722: */
5723:
5724: if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
5725: if (isp_read_nvram(isp) == 0) {
5726: return;
5727: }
5728: }
5729:
5730: /*
5731: * Now try and see whether we have specific values for them.
5732: */
5733: if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
5734: mbs.param[0] = MBOX_GET_ACT_NEG_STATE;
5735: isp_mboxcmd(isp, &mbs, MBLOGNONE);
5736: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
5737: sdp->isp_req_ack_active_neg = 1;
5738: sdp->isp_data_line_active_neg = 1;
5739: } else {
5740: sdp->isp_req_ack_active_neg =
5741: (mbs.param[1+channel] >> 4) & 0x1;
5742: sdp->isp_data_line_active_neg =
5743: (mbs.param[1+channel] >> 5) & 0x1;
5744: }
5745: }
5746:
5747: isp_prt(isp, ISP_LOGDEBUG0, sc0, sc3,
5748: 0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
5749: sdp->isp_bus_reset_delay, sdp->isp_retry_count,
5750: sdp->isp_retry_delay, sdp->isp_async_data_setup);
5751: isp_prt(isp, ISP_LOGDEBUG0, sc1, sc3,
5752: sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
5753: sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
5754: sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
5755:
5756: /*
5757: * The trick here is to establish a default for the default (honk!)
5758: * state (goal_flags). Then try and get the current status from
5759: * the card to fill in the current state. We don't, in fact, set
5760: * the default to the SAFE default state- that's not the goal state.
5761: */
5762: for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
5763: u_int8_t off, per;
5764: sdp->isp_devparam[tgt].actv_offset = 0;
5765: sdp->isp_devparam[tgt].actv_period = 0;
5766: sdp->isp_devparam[tgt].actv_flags = 0;
5767:
5768: sdp->isp_devparam[tgt].goal_flags =
5769: sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
5770:
5771: /*
5772: * We default to Wide/Fast for versions less than a 1040
5773: * (unless its SBus).
5774: */
5775: if (IS_ULTRA3(isp)) {
5776: off = ISP_80M_SYNCPARMS >> 8;
5777: per = ISP_80M_SYNCPARMS & 0xff;
5778: } else if (IS_ULTRA2(isp)) {
5779: off = ISP_40M_SYNCPARMS >> 8;
5780: per = ISP_40M_SYNCPARMS & 0xff;
5781: } else if (IS_1240(isp)) {
5782: off = ISP_20M_SYNCPARMS >> 8;
5783: per = ISP_20M_SYNCPARMS & 0xff;
5784: } else if ((isp->isp_bustype == ISP_BT_SBUS &&
5785: isp->isp_type < ISP_HA_SCSI_1020A) ||
5786: (isp->isp_bustype == ISP_BT_PCI &&
5787: isp->isp_type < ISP_HA_SCSI_1040) ||
5788: (isp->isp_clock && isp->isp_clock < 60) ||
5789: (sdp->isp_ultramode == 0)) {
5790: off = ISP_10M_SYNCPARMS >> 8;
5791: per = ISP_10M_SYNCPARMS & 0xff;
5792: } else {
5793: off = ISP_20M_SYNCPARMS_1040 >> 8;
5794: per = ISP_20M_SYNCPARMS_1040 & 0xff;
5795: }
5796: sdp->isp_devparam[tgt].goal_offset =
5797: sdp->isp_devparam[tgt].nvrm_offset = off;
5798: sdp->isp_devparam[tgt].goal_period =
5799: sdp->isp_devparam[tgt].nvrm_period = per;
5800:
5801: isp_prt(isp, ISP_LOGDEBUG0, sc2, sc3,
5802: channel, tgt, sdp->isp_devparam[tgt].nvrm_flags,
5803: sdp->isp_devparam[tgt].nvrm_offset,
5804: sdp->isp_devparam[tgt].nvrm_period);
5805: }
5806: }
5807:
5808: /*
5809: * Re-initialize the ISP and complete all orphaned commands
5810: * with a 'botched' notice. The reset/init routines should
5811: * not disturb an already active list of commands.
5812: *
5813: * Locks held prior to coming here.
5814: */
5815:
5816: void
5817: isp_reinit(struct ispsoftc *isp)
5818: {
5819: XS_T *xs;
5820: u_int16_t handle;
5821:
5822: isp_reset(isp);
5823: if (isp->isp_state != ISP_RESETSTATE) {
5824: isp_prt(isp, ISP_LOGERR, "isp_reinit cannot reset card");
5825: } else if (isp->isp_role != ISP_ROLE_NONE) {
5826: isp_init(isp);
5827: if (isp->isp_state == ISP_INITSTATE) {
5828: isp->isp_state = ISP_RUNSTATE;
5829: }
5830: if (isp->isp_state != ISP_RUNSTATE) {
5831: isp_prt(isp, ISP_LOGERR,
5832: "isp_reinit cannot restart card");
5833: }
5834: }
5835: isp->isp_nactive = 0;
5836:
5837: for (handle = 1; (int) handle <= isp->isp_maxcmds; handle++) {
5838: xs = isp_find_xs(isp, handle);
5839: if (xs == NULL) {
5840: continue;
5841: }
5842: isp_destroy_handle(isp, handle);
5843: if (XS_XFRLEN(xs)) {
5844: ISP_DMAFREE(isp, xs, handle);
5845: XS_RESID(xs) = XS_XFRLEN(xs);
5846: } else {
5847: XS_RESID(xs) = 0;
5848: }
5849: XS_SETERR(xs, HBA_BUSRESET);
5850: isp_done(xs);
5851: }
5852: }
5853:
5854: /*
5855: * NVRAM Routines
5856: */
5857: static int
5858: isp_read_nvram(struct ispsoftc *isp)
5859: {
5860: int i, amt;
5861: u_int8_t csum, minversion;
5862: union {
5863: u_int8_t _x[ISP2100_NVRAM_SIZE];
5864: u_int16_t _s[ISP2100_NVRAM_SIZE>>1];
5865: } _n;
5866: #define nvram_data _n._x
5867: #define nvram_words _n._s
5868:
5869: if (IS_FC(isp)) {
5870: amt = ISP2100_NVRAM_SIZE;
5871: minversion = 1;
5872: } else if (IS_ULTRA2(isp)) {
5873: amt = ISP1080_NVRAM_SIZE;
5874: minversion = 0;
5875: } else {
5876: amt = ISP_NVRAM_SIZE;
5877: minversion = 2;
5878: }
5879:
5880: /*
5881: * Just read the first two words first to see if we have a valid
5882: * NVRAM to continue reading the rest with.
5883: */
5884: for (i = 0; i < 2; i++) {
5885: isp_rdnvram_word(isp, i, &nvram_words[i]);
5886: }
5887: if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
5888: nvram_data[2] != 'P') {
5889: if (isp->isp_bustype != ISP_BT_SBUS) {
5890: isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
5891: isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
5892: nvram_data[0], nvram_data[1], nvram_data[2]);
5893: }
5894: return (-1);
5895: }
5896: for (i = 2; i < amt>>1; i++) {
5897: isp_rdnvram_word(isp, i, &nvram_words[i]);
5898: }
5899: for (csum = 0, i = 0; i < amt; i++) {
5900: csum += nvram_data[i];
5901: }
5902: if (csum != 0) {
5903: isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
5904: return (-1);
5905: }
5906: if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
5907: isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
5908: ISP_NVRAM_VERSION(nvram_data));
5909: return (-1);
5910: }
5911:
5912: if (IS_ULTRA3(isp)) {
5913: isp_parse_nvram_12160(isp, 0, nvram_data);
5914: if (IS_12160(isp))
5915: isp_parse_nvram_12160(isp, 1, nvram_data);
5916: } else if (IS_1080(isp)) {
5917: isp_parse_nvram_1080(isp, 0, nvram_data);
5918: } else if (IS_1280(isp) || IS_1240(isp)) {
5919: isp_parse_nvram_1080(isp, 0, nvram_data);
5920: isp_parse_nvram_1080(isp, 1, nvram_data);
5921: } else if (IS_SCSI(isp)) {
5922: isp_parse_nvram_1020(isp, nvram_data);
5923: } else {
5924: isp_parse_nvram_2100(isp, nvram_data);
5925: }
5926: return (0);
5927: #undef nvram_data
5928: #undef nvram_words
5929: }
5930:
5931: static void
5932: isp_rdnvram_word(struct ispsoftc *isp, int wo, u_int16_t *rp)
5933: {
5934: int i, cbits;
5935: u_int16_t bit, rqst;
5936:
5937: ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
5938: USEC_DELAY(2);
5939: ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
5940: USEC_DELAY(2);
5941:
5942: if (IS_FC(isp)) {
5943: wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
5944: if (IS_2312(isp) && isp->isp_port) {
5945: wo += 128;
5946: }
5947: rqst = (ISP_NVRAM_READ << 8) | wo;
5948: cbits = 10;
5949: } else if (IS_ULTRA2(isp)) {
5950: wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
5951: rqst = (ISP_NVRAM_READ << 8) | wo;
5952: cbits = 10;
5953: } else {
5954: wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
5955: rqst = (ISP_NVRAM_READ << 6) | wo;
5956: cbits = 8;
5957: }
5958:
5959: /*
5960: * Clock the word select request out...
5961: */
5962: for (i = cbits; i >= 0; i--) {
5963: if ((rqst >> i) & 1) {
5964: bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
5965: } else {
5966: bit = BIU_NVRAM_SELECT;
5967: }
5968: ISP_WRITE(isp, BIU_NVRAM, bit);
5969: USEC_DELAY(2);
5970: ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
5971: USEC_DELAY(2);
5972: ISP_WRITE(isp, BIU_NVRAM, bit);
5973: USEC_DELAY(2);
5974: }
5975: /*
5976: * Now read the result back in (bits come back in MSB format).
5977: */
5978: *rp = 0;
5979: for (i = 0; i < 16; i++) {
5980: u_int16_t rv;
5981: *rp <<= 1;
5982: ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
5983: USEC_DELAY(2);
5984: rv = ISP_READ(isp, BIU_NVRAM);
5985: if (rv & BIU_NVRAM_DATAIN) {
5986: *rp |= 1;
5987: }
5988: USEC_DELAY(2);
5989: ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
5990: USEC_DELAY(2);
5991: }
5992: ISP_WRITE(isp, BIU_NVRAM, 0);
5993: USEC_DELAY(2);
5994: ISP_SWIZZLE_NVRAM_WORD(isp, rp);
5995: }
5996:
5997: static void
5998: isp_parse_nvram_1020(struct ispsoftc *isp, u_int8_t *nvram_data)
5999: {
6000: sdparam *sdp = (sdparam *) isp->isp_param;
6001: int tgt;
6002:
6003: sdp->isp_fifo_threshold =
6004: ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
6005: (ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
6006:
6007: if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
6008: sdp->isp_initiator_id =
6009: ISP_NVRAM_INITIATOR_ID(nvram_data);
6010:
6011: sdp->isp_bus_reset_delay =
6012: ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
6013:
6014: sdp->isp_retry_count =
6015: ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
6016:
6017: sdp->isp_retry_delay =
6018: ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
6019:
6020: sdp->isp_async_data_setup =
6021: ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
6022:
6023: if (isp->isp_type >= ISP_HA_SCSI_1040) {
6024: if (sdp->isp_async_data_setup < 9) {
6025: sdp->isp_async_data_setup = 9;
6026: }
6027: } else {
6028: if (sdp->isp_async_data_setup != 6) {
6029: sdp->isp_async_data_setup = 6;
6030: }
6031: }
6032:
6033: sdp->isp_req_ack_active_neg =
6034: ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
6035:
6036: sdp->isp_data_line_active_neg =
6037: ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
6038:
6039: sdp->isp_data_dma_burst_enabl =
6040: ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
6041:
6042: sdp->isp_cmd_dma_burst_enable =
6043: ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
6044:
6045: sdp->isp_tag_aging =
6046: ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
6047:
6048: sdp->isp_selection_timeout =
6049: ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
6050:
6051: sdp->isp_max_queue_depth =
6052: ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
6053:
6054: sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
6055:
6056: isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
6057: 0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
6058: sdp->isp_bus_reset_delay, sdp->isp_retry_count,
6059: sdp->isp_retry_delay, sdp->isp_async_data_setup);
6060: isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
6061: sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
6062: sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
6063: sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
6064:
6065: for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
6066: sdp->isp_devparam[tgt].dev_enable =
6067: ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
6068: sdp->isp_devparam[tgt].exc_throttle =
6069: ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
6070: sdp->isp_devparam[tgt].nvrm_offset =
6071: ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
6072: sdp->isp_devparam[tgt].nvrm_period =
6073: ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
6074: /*
6075: * We probably shouldn't lie about this, but it
6076: * it makes it much safer if we limit NVRAM values
6077: * to sanity.
6078: */
6079: if (isp->isp_type < ISP_HA_SCSI_1040) {
6080: /*
6081: * If we're not ultra, we can't possibly
6082: * be a shorter period than this.
6083: */
6084: if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
6085: sdp->isp_devparam[tgt].nvrm_period = 0x19;
6086: }
6087: if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
6088: sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
6089: }
6090: } else {
6091: if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
6092: sdp->isp_devparam[tgt].nvrm_offset = 0x8;
6093: }
6094: }
6095: sdp->isp_devparam[tgt].nvrm_flags = 0;
6096: if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
6097: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
6098: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
6099: if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
6100: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
6101: if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
6102: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
6103: if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
6104: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
6105: if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
6106: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
6107: if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
6108: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
6109: sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
6110: isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
6111: 0, tgt, sdp->isp_devparam[tgt].nvrm_flags,
6112: sdp->isp_devparam[tgt].nvrm_offset,
6113: sdp->isp_devparam[tgt].nvrm_period);
6114: sdp->isp_devparam[tgt].goal_offset =
6115: sdp->isp_devparam[tgt].nvrm_offset;
6116: sdp->isp_devparam[tgt].goal_period =
6117: sdp->isp_devparam[tgt].nvrm_period;
6118: sdp->isp_devparam[tgt].goal_flags =
6119: sdp->isp_devparam[tgt].nvrm_flags;
6120: }
6121: }
6122:
6123: static void
6124: isp_parse_nvram_1080(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
6125: {
6126: sdparam *sdp = (sdparam *) isp->isp_param;
6127: int tgt;
6128:
6129: sdp += bus;
6130:
6131: sdp->isp_fifo_threshold =
6132: ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
6133:
6134: if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
6135: sdp->isp_initiator_id =
6136: ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
6137:
6138: sdp->isp_bus_reset_delay =
6139: ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
6140:
6141: sdp->isp_retry_count =
6142: ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
6143:
6144: sdp->isp_retry_delay =
6145: ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
6146:
6147: sdp->isp_async_data_setup =
6148: ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
6149:
6150: sdp->isp_req_ack_active_neg =
6151: ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
6152:
6153: sdp->isp_data_line_active_neg =
6154: ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
6155:
6156: sdp->isp_data_dma_burst_enabl =
6157: ISP1080_NVRAM_BURST_ENABLE(nvram_data);
6158:
6159: sdp->isp_cmd_dma_burst_enable =
6160: ISP1080_NVRAM_BURST_ENABLE(nvram_data);
6161:
6162: sdp->isp_selection_timeout =
6163: ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
6164:
6165: sdp->isp_max_queue_depth =
6166: ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
6167:
6168: isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
6169: bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
6170: sdp->isp_bus_reset_delay, sdp->isp_retry_count,
6171: sdp->isp_retry_delay, sdp->isp_async_data_setup);
6172: isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
6173: sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
6174: sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
6175: sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
6176:
6177:
6178: for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
6179: sdp->isp_devparam[tgt].dev_enable =
6180: ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
6181: sdp->isp_devparam[tgt].exc_throttle =
6182: ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
6183: sdp->isp_devparam[tgt].nvrm_offset =
6184: ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
6185: sdp->isp_devparam[tgt].nvrm_period =
6186: ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
6187: sdp->isp_devparam[tgt].nvrm_flags = 0;
6188: if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
6189: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
6190: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
6191: if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
6192: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
6193: if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
6194: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
6195: if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
6196: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
6197: if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
6198: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
6199: if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
6200: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
6201: sdp->isp_devparam[tgt].actv_flags = 0;
6202: isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
6203: bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
6204: sdp->isp_devparam[tgt].nvrm_offset,
6205: sdp->isp_devparam[tgt].nvrm_period);
6206: sdp->isp_devparam[tgt].goal_offset =
6207: sdp->isp_devparam[tgt].nvrm_offset;
6208: sdp->isp_devparam[tgt].goal_period =
6209: sdp->isp_devparam[tgt].nvrm_period;
6210: sdp->isp_devparam[tgt].goal_flags =
6211: sdp->isp_devparam[tgt].nvrm_flags;
6212: }
6213: }
6214:
6215: static void
6216: isp_parse_nvram_12160(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
6217: {
6218: sdparam *sdp = (sdparam *) isp->isp_param;
6219: int tgt;
6220:
6221: sdp += bus;
6222:
6223: sdp->isp_fifo_threshold =
6224: ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
6225:
6226: if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
6227: sdp->isp_initiator_id =
6228: ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
6229:
6230: sdp->isp_bus_reset_delay =
6231: ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
6232:
6233: sdp->isp_retry_count =
6234: ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
6235:
6236: sdp->isp_retry_delay =
6237: ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
6238:
6239: sdp->isp_async_data_setup =
6240: ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
6241:
6242: sdp->isp_req_ack_active_neg =
6243: ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
6244:
6245: sdp->isp_data_line_active_neg =
6246: ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
6247:
6248: sdp->isp_data_dma_burst_enabl =
6249: ISP12160_NVRAM_BURST_ENABLE(nvram_data);
6250:
6251: sdp->isp_cmd_dma_burst_enable =
6252: ISP12160_NVRAM_BURST_ENABLE(nvram_data);
6253:
6254: sdp->isp_selection_timeout =
6255: ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
6256:
6257: sdp->isp_max_queue_depth =
6258: ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
6259:
6260: isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
6261: bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
6262: sdp->isp_bus_reset_delay, sdp->isp_retry_count,
6263: sdp->isp_retry_delay, sdp->isp_async_data_setup);
6264: isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
6265: sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
6266: sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
6267: sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
6268:
6269: for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
6270: sdp->isp_devparam[tgt].dev_enable =
6271: ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
6272: sdp->isp_devparam[tgt].exc_throttle =
6273: ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
6274: sdp->isp_devparam[tgt].nvrm_offset =
6275: ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
6276: sdp->isp_devparam[tgt].nvrm_period =
6277: ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
6278: sdp->isp_devparam[tgt].nvrm_flags = 0;
6279: if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
6280: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
6281: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
6282: if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
6283: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
6284: if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
6285: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
6286: if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
6287: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
6288: if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
6289: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
6290: if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
6291: sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
6292: sdp->isp_devparam[tgt].actv_flags = 0;
6293: isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
6294: bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
6295: sdp->isp_devparam[tgt].nvrm_offset,
6296: sdp->isp_devparam[tgt].nvrm_period);
6297: sdp->isp_devparam[tgt].goal_offset =
6298: sdp->isp_devparam[tgt].nvrm_offset;
6299: sdp->isp_devparam[tgt].goal_period =
6300: sdp->isp_devparam[tgt].nvrm_period;
6301: sdp->isp_devparam[tgt].goal_flags =
6302: sdp->isp_devparam[tgt].nvrm_flags;
6303: }
6304: }
6305:
6306: static void
6307: isp_parse_nvram_2100(struct ispsoftc *isp, u_int8_t *nvram_data)
6308: {
6309: fcparam *fcp = (fcparam *) isp->isp_param;
6310: u_int64_t wwn;
6311:
6312: /*
6313: * There is NVRAM storage for both Port and Node entities-
6314: * but the Node entity appears to be unused on all the cards
6315: * I can find. However, we should account for this being set
6316: * at some point in the future.
6317: *
6318: * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
6319: * bits 48..60. In the case of the 2202, it appears that they do
6320: * use bit 48 to distinguish between the two instances on the card.
6321: * The 2204, which I've never seen, *probably* extends this method.
6322: */
6323: wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
6324: if (wwn) {
6325: isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
6326: (u_int32_t) (wwn >> 32), (u_int32_t) (wwn & 0xffffffff));
6327: if ((wwn >> 60) == 0) {
6328: wwn |= (((u_int64_t) 2)<< 60);
6329: }
6330: }
6331: fcp->isp_portwwn = wwn;
6332: if (IS_2200(isp) || IS_23XX(isp)) {
6333: wwn = ISP2200_NVRAM_NODE_NAME(nvram_data);
6334: if (wwn) {
6335: isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
6336: (u_int32_t) (wwn >> 32),
6337: (u_int32_t) (wwn & 0xffffffff));
6338: if ((wwn >> 60) == 0) {
6339: wwn |= (((u_int64_t) 2)<< 60);
6340: }
6341: }
6342: } else {
6343: wwn &= ~((u_int64_t) 0xfff << 48);
6344: }
6345: fcp->isp_nodewwn = wwn;
6346:
6347: /*
6348: * Make sure we have both Node and Port as non-zero values.
6349: */
6350: if (fcp->isp_nodewwn != 0 && fcp->isp_portwwn == 0) {
6351: fcp->isp_portwwn = fcp->isp_nodewwn;
6352: } else if (fcp->isp_nodewwn == 0 && fcp->isp_portwwn != 0) {
6353: fcp->isp_nodewwn = fcp->isp_portwwn;
6354: }
6355:
6356: /*
6357: * Make the Node and Port values sane if they're NAA == 2.
6358: * This means to clear bits 48..56 for the Node WWN and
6359: * make sure that there's some non-zero value in 48..56
6360: * for the Port WWN.
6361: */
6362: if (fcp->isp_nodewwn && fcp->isp_portwwn) {
6363: if ((fcp->isp_nodewwn & (((u_int64_t) 0xfff) << 48)) != 0 &&
6364: (fcp->isp_nodewwn >> 60) == 2) {
6365: fcp->isp_nodewwn &= ~((u_int64_t) 0xfff << 48);
6366: }
6367: if ((fcp->isp_portwwn & (((u_int64_t) 0xfff) << 48)) == 0 &&
6368: (fcp->isp_portwwn >> 60) == 2) {
6369: fcp->isp_portwwn |= ((u_int64_t) 1 << 56);
6370: }
6371: }
6372:
6373: isp_prt(isp, ISP_LOGDEBUG0,
6374: "NVRAM: maxfrmlen %d execthrottle %d fwoptions 0x%x loopid %x",
6375: ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data),
6376: ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
6377: ISP2100_NVRAM_OPTIONS(nvram_data),
6378: ISP2100_NVRAM_HARDLOOPID(nvram_data));
6379:
6380: fcp->isp_maxalloc =
6381: ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
6382: if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0)
6383: fcp->isp_maxfrmlen =
6384: ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
6385: fcp->isp_retry_delay =
6386: ISP2100_NVRAM_RETRY_DELAY(nvram_data);
6387: fcp->isp_retry_count =
6388: ISP2100_NVRAM_RETRY_COUNT(nvram_data);
6389: if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
6390: fcp->isp_loopid =
6391: ISP2100_NVRAM_HARDLOOPID(nvram_data);
6392: if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0)
6393: fcp->isp_execthrottle =
6394: ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
6395: fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
6396: }
6397:
6398: #ifdef ISP_FW_CRASH_DUMP
6399: static void isp2200_fw_dump(struct ispsoftc *);
6400: static void isp2300_fw_dump(struct ispsoftc *);
6401:
6402: static void
6403: isp2200_fw_dump(struct ispsoftc *isp)
6404: {
6405: int i, j;
6406: mbreg_t mbs;
6407: u_int16_t *ptr;
6408:
6409: ptr = FCPARAM(isp)->isp_dump_data;
6410: if (ptr == NULL) {
6411: isp_prt(isp, ISP_LOGERR,
6412: "No place to dump RISC registers and SRAM");
6413: return;
6414: }
6415: if (*ptr++) {
6416: isp_prt(isp, ISP_LOGERR,
6417: "dump area for RISC registers and SRAM already used");
6418: return;
6419: }
6420: ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
6421: for (i = 0; i < 100; i++) {
6422: USEC_DELAY(100);
6423: if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6424: break;
6425: }
6426: }
6427: if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6428: /*
6429: * PBIU Registers
6430: */
6431: for (i = 0; i < 8; i++) {
6432: *ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
6433: }
6434:
6435: /*
6436: * Mailbox Registers
6437: */
6438: for (i = 0; i < 8; i++) {
6439: *ptr++ = ISP_READ(isp, MBOX_BLOCK + (i << 1));
6440: }
6441:
6442: /*
6443: * DMA Registers
6444: */
6445: for (i = 0; i < 48; i++) {
6446: *ptr++ = ISP_READ(isp, DMA_BLOCK + 0x20 + (i << 1));
6447: }
6448:
6449: /*
6450: * RISC H/W Registers
6451: */
6452: ISP_WRITE(isp, BIU2100_CSR, 0);
6453: for (i = 0; i < 16; i++) {
6454: *ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
6455: }
6456:
6457: /*
6458: * RISC GP Registers
6459: */
6460: for (j = 0; j < 8; j++) {
6461: ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 8));
6462: for (i = 0; i < 16; i++) {
6463: *ptr++ =
6464: ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6465: }
6466: }
6467:
6468: /*
6469: * Frame Buffer Hardware Registers
6470: */
6471: ISP_WRITE(isp, BIU2100_CSR, 0x10);
6472: for (i = 0; i < 16; i++) {
6473: *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6474: }
6475:
6476: /*
6477: * Fibre Protocol Module 0 Hardware Registers
6478: */
6479: ISP_WRITE(isp, BIU2100_CSR, 0x20);
6480: for (i = 0; i < 64; i++) {
6481: *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6482: }
6483:
6484: /*
6485: * Fibre Protocol Module 1 Hardware Registers
6486: */
6487: ISP_WRITE(isp, BIU2100_CSR, 0x30);
6488: for (i = 0; i < 64; i++) {
6489: *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6490: }
6491: } else {
6492: isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
6493: return;
6494: }
6495: isp_prt(isp, ISP_LOGALL,
6496: "isp_fw_dump: RISC registers dumped successfully");
6497: ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
6498: for (i = 0; i < 100; i++) {
6499: USEC_DELAY(100);
6500: if (ISP_READ(isp, OUTMAILBOX0) == 0) {
6501: break;
6502: }
6503: }
6504: if (ISP_READ(isp, OUTMAILBOX0) != 0) {
6505: isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
6506: return;
6507: }
6508: ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
6509: for (i = 0; i < 100; i++) {
6510: USEC_DELAY(100);
6511: if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6512: break;
6513: }
6514: }
6515: if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
6516: isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause After Reset");
6517: return;
6518: }
6519: ISP_WRITE(isp, RISC_EMB, 0xf2);
6520: ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
6521: for (i = 0; i < 100; i++) {
6522: USEC_DELAY(100);
6523: if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
6524: break;
6525: }
6526: }
6527: ENABLE_INTS(isp);
6528: mbs.param[0] = MBOX_READ_RAM_WORD;
6529: mbs.param[1] = 0x1000;
6530: isp->isp_mbxworkp = (void *) ptr;
6531: isp->isp_mbxwrk0 = 0xefff; /* continuation count */
6532: isp->isp_mbxwrk1 = 0x1001; /* next SRAM address */
6533: isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
6534: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
6535: isp_prt(isp, ISP_LOGWARN,
6536: "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
6537: return;
6538: }
6539: ptr = isp->isp_mbxworkp; /* finish fetch of final word */
6540: *ptr++ = isp->isp_mboxtmp[2];
6541: isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped successfully");
6542: FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
6543: (void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
6544: }
6545:
6546: static void
6547: isp2300_fw_dump(struct ispsoftc *isp)
6548: {
6549: int i, j;
6550: mbreg_t mbs;
6551: u_int16_t *ptr;
6552:
6553: ptr = FCPARAM(isp)->isp_dump_data;
6554: if (ptr == NULL) {
6555: isp_prt(isp, ISP_LOGERR,
6556: "No place to dump RISC registers and SRAM");
6557: return;
6558: }
6559: if (*ptr++) {
6560: isp_prt(isp, ISP_LOGERR,
6561: "dump area for RISC registers and SRAM already used");
6562: return;
6563: }
6564: ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
6565: for (i = 0; i < 100; i++) {
6566: USEC_DELAY(100);
6567: if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6568: break;
6569: }
6570: }
6571: if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6572: /*
6573: * PBIU registers
6574: */
6575: for (i = 0; i < 8; i++) {
6576: *ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
6577: }
6578:
6579: /*
6580: * ReqQ-RspQ-Risc2Host Status registers
6581: */
6582: for (i = 0; i < 8; i++) {
6583: *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x10 + (i << 1));
6584: }
6585:
6586: /*
6587: * Mailbox Registers
6588: */
6589: for (i = 0; i < 32; i++) {
6590: *ptr++ =
6591: ISP_READ(isp, PCI_MBOX_REGS2300_OFF + (i << 1));
6592: }
6593:
6594: /*
6595: * Auto Request Response DMA registers
6596: */
6597: ISP_WRITE(isp, BIU2100_CSR, 0x40);
6598: for (i = 0; i < 32; i++) {
6599: *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6600: }
6601:
6602: /*
6603: * DMA registers
6604: */
6605: ISP_WRITE(isp, BIU2100_CSR, 0x50);
6606: for (i = 0; i < 48; i++) {
6607: *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6608: }
6609:
6610: /*
6611: * RISC hardware registers
6612: */
6613: ISP_WRITE(isp, BIU2100_CSR, 0);
6614: for (i = 0; i < 16; i++) {
6615: *ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
6616: }
6617:
6618: /*
6619: * RISC GP? registers
6620: */
6621: for (j = 0; j < 8; j++) {
6622: ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 9));
6623: for (i = 0; i < 16; i++) {
6624: *ptr++ =
6625: ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6626: }
6627: }
6628:
6629: /*
6630: * frame buffer hardware registers
6631: */
6632: ISP_WRITE(isp, BIU2100_CSR, 0x10);
6633: for (i = 0; i < 64; i++) {
6634: *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6635: }
6636:
6637: /*
6638: * FPM B0 hardware registers
6639: */
6640: ISP_WRITE(isp, BIU2100_CSR, 0x20);
6641: for (i = 0; i < 64; i++) {
6642: *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6643: }
6644:
6645: /*
6646: * FPM B1 hardware registers
6647: */
6648: ISP_WRITE(isp, BIU2100_CSR, 0x30);
6649: for (i = 0; i < 64; i++) {
6650: *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6651: }
6652: } else {
6653: isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
6654: return;
6655: }
6656: isp_prt(isp, ISP_LOGALL,
6657: "isp_fw_dump: RISC registers dumped successfully");
6658: ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
6659: for (i = 0; i < 100; i++) {
6660: USEC_DELAY(100);
6661: if (ISP_READ(isp, OUTMAILBOX0) == 0) {
6662: break;
6663: }
6664: }
6665: if (ISP_READ(isp, OUTMAILBOX0) != 0) {
6666: isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
6667: return;
6668: }
6669: ENABLE_INTS(isp);
6670: mbs.param[0] = MBOX_READ_RAM_WORD;
6671: mbs.param[1] = 0x800;
6672: isp->isp_mbxworkp = (void *) ptr;
6673: isp->isp_mbxwrk0 = 0xf7ff; /* continuation count */
6674: isp->isp_mbxwrk1 = 0x801; /* next SRAM address */
6675: isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
6676: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
6677: isp_prt(isp, ISP_LOGWARN,
6678: "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
6679: return;
6680: }
6681: ptr = isp->isp_mbxworkp; /* finish fetch of final word */
6682: *ptr++ = isp->isp_mboxtmp[2];
6683:
6684: /*
6685: * We don't have access to mailbox registers 8.. onward
6686: * in our 'common' device model- so we have to set it
6687: * here and hope it stays the same!
6688: */
6689: ISP_WRITE(isp, PCI_MBOX_REGS2300_OFF + (8 << 1), 0x1);
6690:
6691: mbs.param[0] = MBOX_READ_RAM_WORD_EXTENDED;
6692: mbs.param[1] = 0;
6693: isp->isp_mbxworkp = (void *) ptr;
6694: isp->isp_mbxwrk0 = 0xffff; /* continuation count */
6695: isp->isp_mbxwrk1 = 0x1; /* next SRAM address */
6696: isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
6697: if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
6698: isp_prt(isp, ISP_LOGWARN,
6699: "RAM DUMP FAILED @ WORD %x", 0x10000 + isp->isp_mbxwrk1);
6700: return;
6701: }
6702: ptr = isp->isp_mbxworkp; /* finish final word */
6703: *ptr++ = mbs.param[2];
6704: isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped successfully");
6705: FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
6706: (void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
6707: }
6708:
6709: void
6710: isp_fw_dump(struct ispsoftc *isp)
6711: {
6712: if (IS_2200(isp))
6713: isp2200_fw_dump(isp);
6714: else if (IS_23XX(isp))
6715: isp2300_fw_dump(isp);
6716: }
6717: #endif
CVSweb