This source file includes following definitions.
- isp_reset
- isp_init
- isp_scsi_init
- isp_scsi_channel_init
- isp_fibre_init
- isp_getmap
- isp_mark_getpdb_all
- isp_getpdb
- isp_get_portname
- isp_fclink_test
- isp2100_fw_statename
- isp_pdb_sync
- isp_scan_loop
- isp_fabric_mbox_cmd
- isp_scan_fabric
- isp_scan_fabric
- isp_register_fc4_type
- isp_start
- isp_control
- isp_intr
- isp_parse_async
- isp_handle_other_response
- isp_parse_status
- isp_fastpost_complete
- isp_mbox_continue
- isp_mboxcmd_qnw
- isp_mboxcmd
- isp_fw_state
- isp_update
- isp_update_bus
- isp_setdfltparm
- isp_reinit
- isp_read_nvram
- isp_rdnvram_word
- isp_parse_nvram_1020
- isp_parse_nvram_1080
- isp_parse_nvram_12160
- isp_parse_nvram_2100
- isp2200_fw_dump
- isp2300_fw_dump
- isp_fw_dump
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
60
61
62 #define MBOX_DELAY_COUNT 1000000 / 100
63
64
65
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
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
153
154
155
156
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187 if (isp->isp_touched == 0) {
188
189
190
191
192
193
194
195
196
197
198
199 if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 ||
200 ISP_READ(isp, OUTMAILBOX2) != 0x5020 ||
201 ISP_READ(isp, OUTMAILBOX3) != 0x2020) {
202
203
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
221
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
237
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
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
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
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
354
355
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
384
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
403
404
405 isp->isp_clock = 60;
406 } else {
407 sdp->isp_ultramode = 0;
408
409
410
411 }
412
413
414
415
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
427
428 isp->isp_intcnt = isp->isp_intbogus = 0;
429
430
431
432
433 ISP_RESET0(isp);
434
435 again:
436
437
438
439
440
441
442 if (IS_SCSI(isp)) {
443 ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
444
445
446
447 USEC_DELAY(100);
448
449
450
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
462
463 USEC_DELAY(100);
464
465
466
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
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
497
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
508
509 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
510 USEC_DELAY(100);
511
512 ISP_WRITE(isp, BIU_SEMA, 0);
513
514
515
516
517
518
519 if (IS_SCSI(isp)) {
520 u_int16_t tmp = isp->isp_mdvec->dv_conf1;
521
522
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
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);
556
557
558
559
560 ISP_RESET1(isp);
561
562
563
564
565
566
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
584
585
586
587
588
589
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
622
623
624
625
626
627
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
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
672
673
674
675
676
677
678 mbs.param[0] = MBOX_EXEC_FIRMWARE;
679 mbs.param[1] = code_org;
680 isp_mboxcmd(isp, &mbs, MBLOGNONE);
681
682
683
684 USEC_DELAY(500);
685
686 if (IS_SCSI(isp)) {
687
688
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
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
706
707
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
733
734
735
736
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
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
783
784
785
786
787
788
789
790
791
792
793
794
795
796
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
819
820
821
822
823 void
824 isp_init(struct ispsoftc *isp)
825 {
826
827
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
854
855 if (isp->isp_role == ISP_ROLE_NONE) {
856 return;
857 }
858
859
860
861
862
863
864 if (sdp_chan0->isp_fast_mttr) {
865 ISP_WRITE(isp, RISC_MTR, 0x1313);
866 }
867
868
869
870
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
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
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
915
916 }
917
918
919
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
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
943 isp_scsi_channel_init(isp, 0);
944 if (IS_DUALBUS(isp))
945 isp_scsi_channel_init(isp, 1);
946
947
948
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
1003
1004
1005
1006
1007
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
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
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
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
1076
1077
1078
1079
1080 if (isp->isp_loaded_fw) {
1081 sdf |= DPARM_NARROW | DPARM_ASYNC;
1082 }
1083 #else
1084
1085
1086
1087
1088
1089
1090
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
1123
1124
1125
1126
1127
1128
1129
1130
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
1155
1156
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
1171
1172 isp_mark_getpdb_all(isp);
1173 fcp->isp_fwstate = FW_CONFIG_WAIT;
1174 fcp->isp_loopstate = LOOP_NIL;
1175
1176
1177
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
1189
1190
1191
1192
1193
1194
1195
1196
1197 if ((isp->isp_type == ISP_HA_FC_2100) && isp->isp_revision < 5) {
1198 fcp->isp_fwoptions &= ~ICBOPT_FAIRNESS;
1199 }
1200
1201
1202
1203
1204
1205
1206 if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
1207 fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
1208 }
1209
1210
1211
1212
1213 fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
1214
1215
1216
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
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
1254
1255
1256
1257
1258 if (IS_2200(isp) || IS_23XX(isp)) {
1259 icbp->icb_fwoptions |= ICBOPT_EXTENDED;
1260
1261
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
1280
1281
1282
1283
1284
1285
1286
1287 icbp->icb_xfwoptions |= ICBXOPT_ZIO;
1288 #if 0
1289
1290
1291
1292
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
1310
1311
1312
1313
1314
1315
1316
1317
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
1330
1331
1332 if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
1333
1334
1335
1336
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;
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
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
1408
1409 isp->isp_state = ISP_INITSTATE;
1410 }
1411
1412
1413
1414
1415
1416
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
1431
1432
1433
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
1472
1473
1474
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
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
1540
1541
1542
1543
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
1567
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
1578
1579
1580
1581
1582
1583
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
1607
1608 if (fcp->isp_fwstate != FW_READY) {
1609 return (-1);
1610 }
1611
1612
1613
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
1633
1634
1635
1636
1637 fcp->isp_onfabric = 0;
1638
1639 if (IS_2100(isp)) {
1640
1641
1642
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
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
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
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
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
1783
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
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
1815
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
1826
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;
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
1851
1852
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
1865
1866 if (lp->port_wwn == 0) {
1867 continue;
1868 }
1869
1870
1871
1872
1873 if ((portid = lp->portid) == fcp->isp_portid) {
1874 continue;
1875 }
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
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
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
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
1970
1971 loopid++;
1972 break;
1973 case MBOX_PORT_ID_USED:
1974
1975
1976
1977
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
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
1997 case MBOX_ALL_IDS_USED:
1998 default:
1999 loopid = MAX_FC_TARG;
2000 break;
2001 }
2002 } while (lp->loopid == FL_PORT_ID && loopid < MAX_FC_TARG);
2003
2004
2005
2006
2007
2008
2009 if (lp->loopid == FL_PORT_ID) {
2010 lp->loopid = 0;
2011 continue;
2012 }
2013
2014
2015
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
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
2084
2085
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
2118
2119 MEMZERO((void *)fcp->tport, sizeof (fcp->tport));
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129 for (lim = loopid = 0; loopid < hival; loopid++) {
2130 lp = &fcp->tport[loopid];
2131
2132
2133
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
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
2165
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
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
2206
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
2219
2220
2221 for (loopid = 0; loopid < hival; loopid++) {
2222 int i;
2223
2224
2225
2226
2227 if (fcp->tport[loopid].port_wwn == 0) {
2228 continue;
2229 }
2230
2231
2232
2233
2234 if (loopid == fcp->isp_iid) {
2235 continue;
2236 }
2237
2238
2239
2240
2241
2242
2243
2244
2245
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
2257
2258
2259
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
2274
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
2284
2285
2286
2287
2288 fcp->portdb[i].valid = 0;
2289 fcp->portdb[j].valid = 0;
2290 }
2291 break;
2292 }
2293
2294
2295
2296
2297
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
2307
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
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
2326
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
2337
2338 (void) isp_async(isp, ISPASYNC_PROMENADE, &i);
2339 }
2340
2341
2342
2343
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
2352
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
2429
2430
2431 last_port_same = 0;
2432 last_portid = 0xffffffff;
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
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
2497
2498
2499
2500
2501
2502
2503
2504
2505
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
2532
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
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
2648
2649
2650
2651
2652
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
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
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
2783
2784 #if 0
2785
2786
2787
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
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_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
2851
2852
2853
2854
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
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);
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
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
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
2936
2937 if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
2938 XS_SETERR(xs, HBA_SELTIMEOUT);
2939 return (CMD_COMPLETE);
2940 }
2941
2942
2943
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
2954
2955
2956
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
2969
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
2983
2984
2985
2986
2987
2988
2989
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
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012 }
3013 #else
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026 if (fcp->isp_fwstate != FW_READY) {
3027
3028
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
3042
3043
3044
3045
3046
3047
3048
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
3069
3070
3071
3072
3073
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
3086
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
3096
3097
3098
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
3112
3113
3114
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
3128
3129
3130 #endif
3131
3132
3133
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
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
3157
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
3171
3172
3173
3174 reqp = (ispreq_t *) local;
3175 if (isp->isp_sendmarker) {
3176 u_int8_t n = (IS_DUALBUS(isp)? 2: 1);
3177
3178
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;
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
3212
3213 if (IS_FC(isp)) {
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224 if (XS_TAG_P(xs)) {
3225 ((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
3226 } else {
3227
3228
3229
3230
3231 if (XS_CDBP(xs)[0] == 0x3)
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
3270
3271
3272 i = ISP_DMASETUP(isp, xs, reqp, &nxti, optr);
3273 if (i != CMD_QUEUED) {
3274 isp_destroy_handle(isp, handle);
3275
3276
3277
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
3293
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
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;
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
3383
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
3451
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
3472
3473
3474
3475
3476
3477
3478
3479
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
3495
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
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
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
3551
3552
3553
3554 if (IS_23XX(isp)) {
3555 optr = ISP_READ(isp, isp->isp_respoutrp);
3556
3557
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
3569
3570
3571
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
3596
3597
3598
3599
3600
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
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);
3663 continue;
3664 } else {
3665
3666
3667
3668
3669
3670 if (isp_handle_other_response(isp, type, hp, &optr)) {
3671 iptr = isp->isp_resodx;
3672 MEMZERO(hp, QENTRY_LEN);
3673 continue;
3674 }
3675
3676
3677
3678
3679
3680
3681 isp_get_response(isp, (ispstatusreq_t *) hp, sp);
3682
3683
3684
3685
3686
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);
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
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);
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);
3747
3748
3749
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
3776
3777
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
3802
3803
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
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
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
3862
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;
3891 MEMZERO(hp, QENTRY_LEN);
3892 if (ndone == MAX_REQUESTQ_COMPLETIONS) {
3893 break;
3894 }
3895 }
3896
3897
3898
3899
3900
3901
3902 if (nlooked) {
3903 WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
3904
3905
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
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
3953
3954
3955
3956
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
3978
3979
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
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
4051
4052
4053 isp->isp_sendmarker |= (1 << bus);
4054 break;
4055
4056
4057
4058
4059
4060 case ASYNC_RIO5:
4061 bus = 0x1ce;
4062 break;
4063
4064 case ASYNC_RIO4:
4065 bus = 0x14e;
4066 break;
4067
4068 case ASYNC_RIO3:
4069 bus = 0x10e;
4070 break;
4071
4072 case ASYNC_RIO2:
4073 bus = 0x106;
4074 break;
4075
4076 case ASYNC_RIO1:
4077 case ASYNC_CMD_CMPLT:
4078 bus = 0x102;
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++;
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
4113
4114
4115
4116
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
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
4276
4277
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++;
4299 #ifdef ISP_TARGET_MODE
4300 if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
4301 return (1);
4302 }
4303 #endif
4304
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
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
4567
4568
4569
4570
4571
4572
4573
4574
4575
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
4638
4639 case RQCS_PORT_LOGGED_OUT:
4640
4641
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
4651
4652
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
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
4717
4718
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
4754
4755 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
4756 ISP_WRITE(isp, BIU_SEMA, 0);
4757
4758
4759
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),
4786 ISPOPMAP(0x1f, 0x01),
4787 ISPOPMAP(0x03, 0x01),
4788 ISPOPMAP(0x1f, 0x01),
4789 ISPOPMAP(0x07, 0x07),
4790 ISPOPMAP(0x03, 0x07),
4791 ISPOPMAP(0x3f, 0x3f),
4792 ISPOPMAP(0x03, 0x07),
4793 ISPOPMAP(0x01, 0x0f),
4794 ISPOPMAP(0x00, 0x00),
4795 ISPOPMAP(0x00, 0x00),
4796 ISPOPMAP(0x00, 0x00),
4797 ISPOPMAP(0x00, 0x00),
4798 ISPOPMAP(0x00, 0x00),
4799 ISPOPMAP(0x01, 0x05),
4800 ISPOPMAP(0x00, 0x00),
4801 ISPOPMAP(0x1f, 0x1f),
4802 ISPOPMAP(0x3f, 0x3f),
4803 ISPOPMAP(0x0f, 0x0f),
4804 ISPOPMAP(0x03, 0x03),
4805 ISPOPMAP(0x01, 0x3f),
4806 ISPOPMAP(0x0f, 0x0f),
4807 ISPOPMAP(0x03, 0x03),
4808 ISPOPMAP(0x07, 0x07),
4809 ISPOPMAP(0x07, 0x07),
4810 ISPOPMAP(0x03, 0x07),
4811 ISPOPMAP(0x03, 0x07),
4812 ISPOPMAP(0x03, 0x07),
4813 ISPOPMAP(0x03, 0x07),
4814 ISPOPMAP(0x03, 0x4f),
4815 ISPOPMAP(0x00, 0x00),
4816 ISPOPMAP(0x01, 0x07),
4817 ISPOPMAP(0x01, 0x07),
4818 ISPOPMAP(0x01, 0x07),
4819 ISPOPMAP(0x01, 0xc7),
4820 ISPOPMAP(0x01, 0x07),
4821 ISPOPMAP(0x01, 0x03),
4822 ISPOPMAP(0x01, 0x07),
4823 ISPOPMAP(0x01, 0x07),
4824 ISPOPMAP(0x01, 0x07),
4825 ISPOPMAP(0x03, 0x4f),
4826 ISPOPMAP(0x03, 0x0f),
4827 ISPOPMAP(0x01, 0x07),
4828 ISPOPMAP(0x00, 0x00),
4829 ISPOPMAP(0x00, 0x00),
4830 ISPOPMAP(0x00, 0x00),
4831 ISPOPMAP(0x00, 0x00),
4832 ISPOPMAP(0x00, 0x00),
4833 ISPOPMAP(0x03, 0x03),
4834 ISPOPMAP(0x07, 0x07),
4835 ISPOPMAP(0xc7, 0xc7),
4836 ISPOPMAP(0x07, 0x07),
4837 ISPOPMAP(0x03, 0x03),
4838 ISPOPMAP(0x07, 0x07),
4839 ISPOPMAP(0x07, 0x07),
4840 ISPOPMAP(0x07, 0x07),
4841 ISPOPMAP(0x4f, 0x4f),
4842 ISPOPMAP(0x0f, 0x0f),
4843 ISPOPMAP(0x07, 0x07),
4844 ISPOPMAP(0x00, 0x00),
4845 ISPOPMAP(0x00, 0x00),
4846 ISPOPMAP(0x00, 0x00),
4847 ISPOPMAP(0x00, 0x00),
4848 ISPOPMAP(0x00, 0x00),
4849 ISPOPMAP(0x01, 0x03),
4850 ISPOPMAP(0x3f, 0x01),
4851 ISPOPMAP(0x03, 0x07),
4852 ISPOPMAP(0x00, 0x00),
4853 ISPOPMAP(0x00, 0x00),
4854 ISPOPMAP(0x03, 0x03),
4855 ISPOPMAP(0x01, 0x03),
4856 ISPOPMAP(0x00, 0x00),
4857 ISPOPMAP(0x01, 0xcf),
4858 ISPOPMAP(0xcf, 0xcf),
4859 ISPOPMAP(0x03, 0x03),
4860 ISPOPMAP(0x01, 0x03),
4861 ISPOPMAP(0x00, 0x00),
4862 ISPOPMAP(0x00, 0x00),
4863 ISPOPMAP(0x00, 0x00),
4864 ISPOPMAP(0x00, 0x00),
4865 ISPOPMAP(0xdf, 0xdf),
4866 ISPOPMAP(0xdf, 0xdf),
4867 ISPOPMAP(0xdf, 0xff),
4868 ISPOPMAP(0xef, 0xff),
4869 ISPOPMAP(0xcf, 0x01),
4870 ISPOPMAP(0x07, 0x01),
4871 ISPOPMAP(0x03, 0x0f),
4872 ISPOPMAP(0x00, 0x00),
4873 ISPOPMAP(0x00, 0x00),
4874 ISPOPMAP(0x00, 0x00),
4875 ISPOPMAP(0x03, 0x03),
4876 ISPOPMAP(0x01, 0x03),
4877 ISPOPMAP(0x0f, 0x0f),
4878 ISPOPMAP(0x01, 0x01)
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),
4986 ISPOPMAP(0x1f, 0x01),
4987 ISPOPMAP(0x03, 0x01),
4988 ISPOPMAP(0xdf, 0x01),
4989 ISPOPMAP(0x07, 0x07),
4990 ISPOPMAP(0x03, 0x07),
4991 ISPOPMAP(0xff, 0xff),
4992 ISPOPMAP(0x03, 0x05),
4993 ISPOPMAP(0x01, 0x4f),
4994 ISPOPMAP(0xdf, 0x01),
4995 ISPOPMAP(0xdf, 0x01),
4996 ISPOPMAP(0x00, 0x00),
4997 ISPOPMAP(0x00, 0x00),
4998 ISPOPMAP(0x00, 0x00),
4999 ISPOPMAP(0x01, 0x05),
5000 ISPOPMAP(0x03, 0x07),
5001 ISPOPMAP(0x1f, 0x11),
5002 ISPOPMAP(0x2f, 0x21),
5003 ISPOPMAP(0x0f, 0x01),
5004 ISPOPMAP(0x03, 0x03),
5005 ISPOPMAP(0x01, 0xff),
5006 ISPOPMAP(0x4f, 0x01),
5007 ISPOPMAP(0x07, 0x01),
5008 ISPOPMAP(0x07, 0x01),
5009 ISPOPMAP(0x03, 0x03),
5010 ISPOPMAP(0x07, 0x05),
5011 ISPOPMAP(0x07, 0x05),
5012 ISPOPMAP(0x07, 0x05),
5013 ISPOPMAP(0x07, 0x05),
5014 ISPOPMAP(0x07, 0x03),
5015 ISPOPMAP(0x00, 0x00),
5016 ISPOPMAP(0x01, 0x07),
5017 ISPOPMAP(0x01, 0x4f),
5018 ISPOPMAP(0x00, 0x00),
5019 ISPOPMAP(0x01, 0x07),
5020 ISPOPMAP(0x00, 0x00),
5021 ISPOPMAP(0x00, 0x00),
5022 ISPOPMAP(0x00, 0x00),
5023 ISPOPMAP(0x00, 0x00),
5024 ISPOPMAP(0x00, 0x00),
5025 ISPOPMAP(0x01, 0x03),
5026 ISPOPMAP(0x03, 0x07),
5027 ISPOPMAP(0x00, 0x00),
5028 ISPOPMAP(0x00, 0x00),
5029 ISPOPMAP(0x00, 0x00),
5030 ISPOPMAP(0x00, 0x00),
5031 ISPOPMAP(0x00, 0x00),
5032 ISPOPMAP(0x00, 0x00),
5033 ISPOPMAP(0x00, 0x00),
5034 ISPOPMAP(0x00, 0x00),
5035 ISPOPMAP(0x07, 0x07),
5036 ISPOPMAP(0x00, 0x00),
5037 ISPOPMAP(0x00, 0x00),
5038 ISPOPMAP(0x00, 0x00),
5039 ISPOPMAP(0x00, 0x00),
5040 ISPOPMAP(0x00, 0x00),
5041 ISPOPMAP(0x0f, 0x01),
5042 ISPOPMAP(0x0f, 0x07),
5043 ISPOPMAP(0x00, 0x00),
5044 ISPOPMAP(0x00, 0x00),
5045 ISPOPMAP(0x00, 0x00),
5046 ISPOPMAP(0x00, 0x00),
5047 ISPOPMAP(0x00, 0x00),
5048 ISPOPMAP(0x00, 0x00),
5049 ISPOPMAP(0x03, 0x01),
5050 ISPOPMAP(0x03, 0x01),
5051 ISPOPMAP(0x03, 0x07),
5052 ISPOPMAP(0x01, 0x01),
5053 ISPOPMAP(0x00, 0x00),
5054 ISPOPMAP(0x00, 0x00),
5055 ISPOPMAP(0x00, 0x00),
5056 ISPOPMAP(0xcf, 0x03),
5057 ISPOPMAP(0x00, 0x00),
5058 ISPOPMAP(0x00, 0x00),
5059 ISPOPMAP(0x00, 0x00),
5060 ISPOPMAP(0x00, 0x00),
5061 ISPOPMAP(0x00, 0x00),
5062 ISPOPMAP(0x00, 0x00),
5063 ISPOPMAP(0x00, 0x00),
5064 ISPOPMAP(0x00, 0x00),
5065 ISPOPMAP(0x00, 0x00),
5066 ISPOPMAP(0x00, 0x00),
5067 ISPOPMAP(0x00, 0x00),
5068 ISPOPMAP(0x00, 0x00),
5069 ISPOPMAP(0xcf, 0x01),
5070 ISPOPMAP(0x00, 0x00),
5071 ISPOPMAP(0x00, 0x00),
5072 ISPOPMAP(0x00, 0x00),
5073 ISPOPMAP(0x00, 0x00),
5074 ISPOPMAP(0x00, 0x00),
5075 ISPOPMAP(0x00, 0x00),
5076 ISPOPMAP(0x03, 0x01),
5077 ISPOPMAP(0xcf, 0x01),
5078 ISPOPMAP(0x07, 0x03),
5079 ISPOPMAP(0x00, 0x00),
5080 ISPOPMAP(0x00, 0x00),
5081 ISPOPMAP(0xfd, 0x31),
5082 ISPOPMAP(0x00, 0x00),
5083 ISPOPMAP(0x01, 0x01),
5084 ISPOPMAP(0xcd, 0x03),
5085 ISPOPMAP(0xcf, 0x01),
5086 ISPOPMAP(0x07, 0x01),
5087 ISPOPMAP(0x07, 0x01),
5088 ISPOPMAP(0x07, 0x01),
5089 ISPOPMAP(0x07, 0x01),
5090 ISPOPMAP(0x01, 0x07),
5091 ISPOPMAP(0x03, 0xcf),
5092 ISPOPMAP(0xcf, 0x01),
5093 ISPOPMAP(0x0f, 0x01),
5094 ISPOPMAP(0x00, 0x00),
5095 ISPOPMAP(0xcf, 0x03),
5096 ISPOPMAP(0x0f, 0x07),
5097 ISPOPMAP(0x03, 0x01),
5098 ISPOPMAP(0x03, 0x03),
5099 ISPOPMAP(0x0f, 0x0f),
5100 ISPOPMAP(0x00, 0x00),
5101 ISPOPMAP(0x07, 0x01),
5102 ISPOPMAP(0xcf, 0x03),
5103 ISPOPMAP(0x4f, 0x01),
5104 ISPOPMAP(0xcd, 0x01),
5105 ISPOPMAP(0x00, 0x00),
5106 ISPOPMAP(0x00, 0x00),
5107 ISPOPMAP(0x00, 0x00),
5108 ISPOPMAP(0x00, 0x00),
5109 ISPOPMAP(0x4f, 0x03),
5110 ISPOPMAP(0xcf, 0x01),
5111 ISPOPMAP(0x07, 0x01)
5112 };
5113
5114
5115
5116
5117
5118
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
5285
5286
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
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
5339
5340 isp->isp_obits = obits;
5341 isp->isp_mboxbsy = 1;
5342
5343
5344
5345
5346 ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
5347
5348
5349
5350
5351 MBOX_WAIT_COMPLETE(isp);
5352
5353 if (isp->isp_mboxbsy) {
5354
5355
5356
5357 isp->isp_mboxbsy = 0;
5358 MBOX_RELEASE(isp);
5359 return;
5360 }
5361
5362
5363
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
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:
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
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
5496
5497
5498
5499
5500
5501
5502
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
5512
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
5521
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
5536
5537
5538
5539
5540
5541
5542
5543
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
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
5627
5628
5629 fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
5630
5631
5632
5633
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
5644
5645
5646
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
5659
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
5671
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
5683
5684 if (sdp->isp_gotdparms) {
5685 return;
5686 }
5687 sdp->isp_gotdparms = 1;
5688
5689
5690
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
5707
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
5719
5720
5721
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
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
5758
5759
5760
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
5773
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
5810
5811
5812
5813
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
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
5882
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
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
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
6076
6077
6078
6079 if (isp->isp_type < ISP_HA_SCSI_1040) {
6080
6081
6082
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;
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
6314
6315
6316
6317
6318
6319
6320
6321
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
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
6358
6359
6360
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
6430
6431 for (i = 0; i < 8; i++) {
6432 *ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
6433 }
6434
6435
6436
6437
6438 for (i = 0; i < 8; i++) {
6439 *ptr++ = ISP_READ(isp, MBOX_BLOCK + (i << 1));
6440 }
6441
6442
6443
6444
6445 for (i = 0; i < 48; i++) {
6446 *ptr++ = ISP_READ(isp, DMA_BLOCK + 0x20 + (i << 1));
6447 }
6448
6449
6450
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
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
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
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
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;
6532 isp->isp_mbxwrk1 = 0x1001;
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;
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;
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
6574
6575 for (i = 0; i < 8; i++) {
6576 *ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
6577 }
6578
6579
6580
6581
6582 for (i = 0; i < 8; i++) {
6583 *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x10 + (i << 1));
6584 }
6585
6586
6587
6588
6589 for (i = 0; i < 32; i++) {
6590 *ptr++ =
6591 ISP_READ(isp, PCI_MBOX_REGS2300_OFF + (i << 1));
6592 }
6593
6594
6595
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
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
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
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
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
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
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;
6674 isp->isp_mbxwrk1 = 0x801;
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;
6682 *ptr++ = isp->isp_mboxtmp[2];
6683
6684
6685
6686
6687
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;
6695 isp->isp_mbxwrk1 = 0x1;
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;
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;
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