isp_netbsd.c revision 1.27 1 /* $NetBSD: isp_netbsd.c,v 1.27 2000/07/07 03:14:53 mjacob Exp $ */
2 /*
3 * Platform (NetBSD) dependent common attachment code for Qlogic adapters.
4 * Matthew Jacob <mjacob (at) nas.nasa.gov>
5 */
6 /*
7 * Copyright (C) 1997, 1998, 1999 National Aeronautics & Space Administration
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <dev/ic/isp_netbsd.h>
34 #include <sys/scsiio.h>
35
36
37 /*
38 * Set a timeout for the watchdogging of a command.
39 *
40 * The dimensional analysis is
41 *
42 * milliseconds * (seconds/millisecond) * (ticks/second) = ticks
43 *
44 * =
45 *
46 * (milliseconds / 1000) * hz = ticks
47 *
48 *
49 * For timeouts less than 1 second, we'll get zero. Because of this, and
50 * because we want to establish *our* timeout to be longer than what the
51 * firmware might do, we just add 3 seconds at the back end.
52 */
53 #define _XT(xs) ((((xs)->timeout/1000) * hz) + (3 * hz))
54
55 static void ispminphys __P((struct buf *));
56 static int32_t ispcmd_slow __P((ISP_SCSI_XFER_T *));
57 static int32_t ispcmd __P((ISP_SCSI_XFER_T *));
58 static int
59 ispioctl __P((struct scsipi_link *, u_long, caddr_t, int, struct proc *));
60
61 static struct scsipi_device isp_dev = { NULL, NULL, NULL, NULL };
62 static int isp_polled_cmd __P((struct ispsoftc *, ISP_SCSI_XFER_T *));
63 static void isp_dog __P((void *));
64 static void isp_command_requeue __P((void *));
65 static void isp_internal_restart __P((void *));
66
67 /*
68 * Complete attachment of hardware, include subdevices.
69 */
70 void
71 isp_attach(isp)
72 struct ispsoftc *isp;
73 {
74 int maxluns = isp->isp_maxluns - 1;
75
76 isp->isp_osinfo._adapter.scsipi_minphys = ispminphys;
77 isp->isp_osinfo._adapter.scsipi_ioctl = ispioctl;
78
79 isp->isp_state = ISP_RUNSTATE;
80 isp->isp_osinfo._link.scsipi_scsi.channel =
81 (IS_DUALBUS(isp))? 0 : SCSI_CHANNEL_ONLY_ONE;
82 isp->isp_osinfo._link.adapter_softc = isp;
83 isp->isp_osinfo._link.device = &isp_dev;
84 isp->isp_osinfo._link.adapter = &isp->isp_osinfo._adapter;
85 isp->isp_osinfo._link.openings = isp->isp_maxcmds;
86 isp->isp_osinfo._link.scsipi_scsi.max_lun = maxluns;
87 TAILQ_INIT(&isp->isp_osinfo.waitq); /* XXX 2nd Bus? */
88
89 if (IS_FC(isp)) {
90 /*
91 * Give it another chance here to come alive...
92 */
93 isp->isp_osinfo._adapter.scsipi_cmd = ispcmd;
94 isp->isp_osinfo._link.scsipi_scsi.max_target = MAX_FC_TARG-1;
95 /*
96 * But we have to be reasonable until the midlayer is fixed.
97 */
98 if (maxluns > 255)
99 isp->isp_osinfo._link.scsipi_scsi.max_lun = 255;
100 } else {
101 sdparam *sdp = isp->isp_param;
102 isp->isp_osinfo._adapter.scsipi_cmd = ispcmd_slow;
103 isp->isp_osinfo._link.scsipi_scsi.max_target = MAX_TARGETS-1;
104 isp->isp_osinfo._link.scsipi_scsi.adapter_target =
105 sdp->isp_initiator_id;
106 isp->isp_osinfo.discovered[0] = 1 << sdp->isp_initiator_id;
107 /*
108 * But we have to be reasonable until the midlayer is fixed.
109 */
110 if (maxluns > 7)
111 isp->isp_osinfo._link.scsipi_scsi.max_lun = 7;
112 if (IS_DUALBUS(isp)) {
113 isp->isp_osinfo._link_b = isp->isp_osinfo._link;
114 sdp++;
115 isp->isp_osinfo.discovered[1] =
116 1 << sdp->isp_initiator_id;
117 isp->isp_osinfo._link_b.scsipi_scsi.adapter_target =
118 sdp->isp_initiator_id;
119 isp->isp_osinfo._link_b.scsipi_scsi.channel = 1;
120 isp->isp_osinfo._link_b.scsipi_scsi.max_lun =
121 isp->isp_osinfo._link.scsipi_scsi.max_lun;
122 }
123 }
124 isp->isp_osinfo._link.type = BUS_SCSI;
125
126 /*
127 * Send a SCSI Bus Reset.
128 */
129 if (IS_SCSI(isp)) {
130 int bus = 0;
131 (void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
132 if (IS_DUALBUS(isp)) {
133 bus++;
134 (void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
135 }
136 } else {
137 int i, j;
138 fcparam *fcp = isp->isp_param;
139 delay(2 * 1000000);
140 for (j = 0; j < 5; j++) {
141 for (i = 0; i < 5; i++) {
142 if (isp_control(isp, ISPCTL_FCLINK_TEST, NULL))
143 continue;
144 #ifdef ISP2100_FABRIC
145 /*
146 * Wait extra time to see if the f/w
147 * eventually completed an FLOGI that
148 * will allow us to know we're on a
149 * fabric.
150 */
151 if (fcp->isp_onfabric == 0) {
152 delay(1 * 1000000);
153 continue;
154 }
155 #endif
156 break;
157 }
158 if (fcp->isp_fwstate == FW_READY &&
159 fcp->isp_loopstate >= LOOP_PDB_RCVD) {
160 break;
161 }
162 }
163 isp->isp_osinfo._link.scsipi_scsi.adapter_target =
164 fcp->isp_loopid;
165 }
166
167 /*
168 * And attach children (if any).
169 */
170 config_found((void *)isp, &isp->isp_osinfo._link, scsiprint);
171 if (IS_DUALBUS(isp)) {
172 config_found((void *)isp, &isp->isp_osinfo._link_b, scsiprint);
173 }
174 }
175
176 /*
177 * minphys our xfers
178 *
179 * Unfortunately, the buffer pointer describes the target device- not the
180 * adapter device, so we can't use the pointer to find out what kind of
181 * adapter we are and adjust accordingly.
182 */
183
184 static void
185 ispminphys(bp)
186 struct buf *bp;
187 {
188 /*
189 * XX: Only the 1020 has a 24 bit limit.
190 */
191 if (bp->b_bcount >= (1 << 24)) {
192 bp->b_bcount = (1 << 24);
193 }
194 minphys(bp);
195 }
196
197 static int32_t
198 ispcmd_slow(xs)
199 ISP_SCSI_XFER_T *xs;
200 {
201 sdparam *sdp;
202 int tgt, chan, s;
203 u_int16_t flags;
204 struct ispsoftc *isp = XS_ISP(xs);
205
206 /*
207 * Have we completed discovery for this target on this adapter?
208 */
209 tgt = XS_TGT(xs);
210 chan = XS_CHANNEL(xs);
211 if ((xs->xs_control & XS_CTL_DISCOVERY) != 0 ||
212 (isp->isp_osinfo.discovered[chan] & (1 << tgt)) != 0) {
213 return (ispcmd(xs));
214 }
215
216 flags = DPARM_DEFAULT;
217 if (xs->sc_link->quirks & SDEV_NOSYNC) {
218 flags ^= DPARM_SYNC;
219 #ifdef DEBUG
220 } else {
221 printf("%s: channel %d target %d can do SYNC xfers\n",
222 isp->isp_name, chan, tgt);
223 #endif
224 }
225 if (xs->sc_link->quirks & SDEV_NOWIDE) {
226 flags ^= DPARM_WIDE;
227 #ifdef DEBUG
228 } else {
229 printf("%s: channel %d target %d can do WIDE xfers\n",
230 isp->isp_name, chan, tgt);
231 #endif
232 }
233 if (xs->sc_link->quirks & SDEV_NOTAG) {
234 flags ^= DPARM_TQING;
235 #ifdef DEBUG
236 } else {
237 printf("%s: channel %d target %d can do TAGGED xfers\n",
238 isp->isp_name, chan, tgt);
239 #endif
240 }
241 /*
242 * Okay, we know about this device now,
243 * so mark parameters to be updated for it.
244 */
245 s = splbio();
246 isp->isp_osinfo.discovered[chan] |= (1 << tgt);
247 sdp = isp->isp_param;
248 sdp += chan;
249 sdp->isp_devparam[tgt].dev_flags = flags;
250 sdp->isp_devparam[tgt].dev_update = 1;
251 isp->isp_update |= (1 << chan);
252 splx(s);
253 return (ispcmd(xs));
254 }
255
256 static int
257 ispioctl(sc_link, cmd, addr, flag, p)
258 struct scsipi_link *sc_link;
259 u_long cmd;
260 caddr_t addr;
261 int flag;
262 struct proc *p;
263 {
264 struct ispsoftc *isp = sc_link->adapter_softc;
265 int s, chan, retval = ENOTTY;
266
267 switch (cmd) {
268 case SCBUSIORESET:
269 chan = sc_link->scsipi_scsi.channel;
270 s = splbio();
271 if (isp_control(isp, ISPCTL_RESET_BUS, &chan))
272 retval = EIO;
273 else
274 retval = 0;
275 (void) splx(s);
276 break;
277 default:
278 break;
279 }
280 return (retval);
281 }
282
283
284 static int32_t
285 ispcmd(xs)
286 ISP_SCSI_XFER_T *xs;
287 {
288 struct ispsoftc *isp;
289 int result, s;
290
291 isp = XS_ISP(xs);
292 s = splbio();
293 if (isp->isp_state < ISP_RUNSTATE) {
294 DISABLE_INTS(isp);
295 isp_init(isp);
296 if (isp->isp_state != ISP_INITSTATE) {
297 ENABLE_INTS(isp);
298 (void) splx(s);
299 XS_SETERR(xs, HBA_BOTCH);
300 return (COMPLETE);
301 }
302 isp->isp_state = ISP_RUNSTATE;
303 ENABLE_INTS(isp);
304 }
305
306 /*
307 * Check for queue blockage...
308 */
309 if (isp->isp_osinfo.blocked) {
310 if (xs->xs_control & XS_CTL_POLL) {
311 xs->error = XS_DRIVER_STUFFUP;
312 splx(s);
313 return (TRY_AGAIN_LATER);
314 }
315 TAILQ_INSERT_TAIL(&isp->isp_osinfo.waitq, xs, adapter_q);
316 splx(s);
317 return (SUCCESSFULLY_QUEUED);
318 }
319
320 if (xs->xs_control & XS_CTL_POLL) {
321 result = isp_polled_cmd(isp, xs);
322 (void) splx(s);
323 return (result);
324 }
325
326 result = ispscsicmd(xs);
327 switch (result) {
328 case CMD_QUEUED:
329 result = SUCCESSFULLY_QUEUED;
330 if (xs->timeout) {
331 callout_reset(&xs->xs_callout, _XT(xs), isp_dog, xs);
332 }
333 break;
334 case CMD_EAGAIN:
335 result = TRY_AGAIN_LATER;
336 break;
337 case CMD_RQLATER:
338 result = SUCCESSFULLY_QUEUED;
339 callout_reset(&xs->xs_callout, hz, isp_command_requeue, xs);
340 break;
341 case CMD_COMPLETE:
342 result = COMPLETE;
343 break;
344 }
345 (void) splx(s);
346 return (result);
347 }
348
349 static int
350 isp_polled_cmd(isp, xs)
351 struct ispsoftc *isp;
352 ISP_SCSI_XFER_T *xs;
353 {
354 int result;
355 int infinite = 0, mswait;
356
357 result = ispscsicmd(xs);
358
359 switch (result) {
360 case CMD_QUEUED:
361 result = SUCCESSFULLY_QUEUED;
362 break;
363 case CMD_RQLATER:
364 case CMD_EAGAIN:
365 if (XS_NOERR(xs)) {
366 xs->error = XS_DRIVER_STUFFUP;
367 }
368 result = TRY_AGAIN_LATER;
369 break;
370 case CMD_COMPLETE:
371 result = COMPLETE;
372 break;
373
374 }
375
376 if (result != SUCCESSFULLY_QUEUED) {
377 return (result);
378 }
379
380 /*
381 * If we can't use interrupts, poll on completion.
382 */
383 if ((mswait = XS_TIME(xs)) == 0)
384 infinite = 1;
385
386 while (mswait || infinite) {
387 if (isp_intr((void *)isp)) {
388 if (XS_CMD_DONE_P(xs)) {
389 break;
390 }
391 }
392 SYS_DELAY(1000);
393 mswait -= 1;
394 }
395
396 /*
397 * If no other error occurred but we didn't finish,
398 * something bad happened.
399 */
400 if (XS_CMD_DONE_P(xs) == 0) {
401 if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) {
402 isp_restart(isp);
403 }
404 if (XS_NOERR(xs)) {
405 XS_SETERR(xs, HBA_BOTCH);
406 }
407 }
408 result = COMPLETE;
409 return (result);
410 }
411
412 void
413 isp_done(xs)
414 ISP_SCSI_XFER_T *xs;
415 {
416 XS_CMD_S_DONE(xs);
417 if (XS_CMD_WDOG_P(xs) == 0) {
418 struct ispsoftc *isp = XS_ISP(xs);
419 callout_stop(&xs->xs_callout);
420 if (XS_CMD_GRACE_P(xs)) {
421 PRINTF("%s: finished command on borrowed time\n",
422 isp->isp_name);
423 }
424 XS_CMD_S_CLEAR(xs);
425 scsipi_done(xs);
426 }
427 }
428
429 static void
430 isp_dog(arg)
431 void *arg;
432 {
433 ISP_SCSI_XFER_T *xs = arg;
434 struct ispsoftc *isp = XS_ISP(xs);
435 u_int32_t handle;
436 int s = splbio();
437
438 /*
439 * We've decided this command is dead. Make sure we're not trying
440 * to kill a command that's already dead by getting it's handle and
441 * and seeing whether it's still alive.
442 */
443 handle = isp_find_handle(isp, xs);
444 if (handle) {
445 u_int16_t r, r1, i;
446
447 if (XS_CMD_DONE_P(xs)) {
448 PRINTF("%s: watchdog found done cmd (handle 0x%x)\n",
449 isp->isp_name, handle);
450 (void) splx(s);
451 return;
452 }
453
454 if (XS_CMD_WDOG_P(xs)) {
455 PRINTF("%s: recursive watchdog (handle 0x%x)\n",
456 isp->isp_name, handle);
457 (void) splx(s);
458 return;
459 }
460
461 XS_CMD_S_WDOG(xs);
462
463 i = 0;
464 do {
465 r = ISP_READ(isp, BIU_ISR);
466 SYS_DELAY(1);
467 r1 = ISP_READ(isp, BIU_ISR);
468 } while (r != r1 && ++i < 1000);
469
470 if (INT_PENDING(isp, r) && isp_intr(isp) && XS_CMD_DONE_P(xs)) {
471 IDPRINTF(1, ("%s: watchdog cleanup (%x, %x)\n",
472 isp->isp_name, handle, r));
473 XS_CMD_C_WDOG(xs);
474 isp_done(xs);
475 } else if (XS_CMD_GRACE_P(xs)) {
476 IDPRINTF(1, ("%s: watchdog timeout (%x, %x)\n",
477 isp->isp_name, handle, r));
478 /*
479 * Make sure the command is *really* dead before we
480 * release the handle (and DMA resources) for reuse.
481 */
482 (void) isp_control(isp, ISPCTL_ABORT_CMD, arg);
483
484 /*
485 * After this point, the comamnd is really dead.
486 */
487 if (XS_XFRLEN(xs)) {
488 ISP_DMAFREE(isp, xs, handle);
489 }
490 isp_destroy_handle(isp, handle);
491 XS_SETERR(xs, XS_TIMEOUT);
492 XS_CMD_S_CLEAR(xs);
493 isp_done(xs);
494 } else {
495 u_int16_t iptr, optr;
496 ispreq_t *mp;
497
498 IDPRINTF(2, ("%s: possible command timeout (%x, %x)\n",
499 isp->isp_name, handle, r));
500
501 XS_CMD_C_WDOG(xs);
502 callout_reset(&xs->xs_callout, hz, isp_dog, xs);
503 if (isp_getrqentry(isp, &iptr, &optr, (void **) &mp)) {
504 (void) splx(s);
505 return;
506 }
507 XS_CMD_S_GRACE(xs);
508 MEMZERO((void *) mp, sizeof (*mp));
509 mp->req_header.rqs_entry_count = 1;
510 mp->req_header.rqs_entry_type = RQSTYPE_MARKER;
511 mp->req_modifier = SYNC_ALL;
512 mp->req_target = XS_CHANNEL(xs) << 7;
513 ISP_SWIZZLE_REQUEST(isp, mp);
514 MemoryBarrier();
515 ISP_ADD_REQUEST(isp, iptr);
516 }
517 } else if (isp->isp_dblev) {
518 PRINTF("%s: watchdog with no command\n", isp->isp_name);
519 }
520 (void) splx(s);
521 }
522
523 /*
524 * Free any associated resources prior to decommissioning and
525 * set the card to a known state (so it doesn't wake up and kick
526 * us when we aren't expecting it to).
527 *
528 * Locks are held before coming here.
529 */
530 void
531 isp_uninit(isp)
532 struct ispsoftc *isp;
533 {
534 ISP_ILOCKVAL_DECL;
535 ISP_ILOCK(isp);
536 /*
537 * Leave with interrupts disabled.
538 */
539 DISABLE_INTS(isp);
540
541 ISP_IUNLOCK(isp);
542 }
543
544 /*
545 * Restart function for a command to be requeued later.
546 */
547 static void
548 isp_command_requeue(arg)
549 void *arg;
550 {
551 struct scsipi_xfer *xs = arg;
552 struct ispsoftc *isp = XS_ISP(xs);
553 int s = splbio();
554 switch (ispcmd_slow(xs)) {
555 case SUCCESSFULLY_QUEUED:
556 printf("%s: isp_command_requeue: requeued for %d.%d\n",
557 isp->isp_name, XS_TGT(xs), XS_LUN(xs));
558 if (xs->timeout) {
559 callout_reset(&xs->xs_callout, _XT(xs), isp_dog, xs);
560 }
561 break;
562 case TRY_AGAIN_LATER:
563 printf("%s: EAGAIN for %d.%d\n",
564 isp->isp_name, XS_TGT(xs), XS_LUN(xs));
565 /* FALLTHROUGH */
566 case COMPLETE:
567 /* can only be an error */
568 XS_CMD_S_DONE(xs);
569 callout_stop(&xs->xs_callout);
570 if (XS_NOERR(xs)) {
571 XS_SETERR(xs, HBA_BOTCH);
572 }
573 scsipi_done(xs);
574 break;
575 }
576 (void) splx(s);
577 }
578
579 /*
580 * Restart function after a LOOP UP event (e.g.),
581 * done as a timeout for some hysteresis.
582 */
583 static void
584 isp_internal_restart(arg)
585 void *arg;
586 {
587 struct ispsoftc *isp = arg;
588 int result, nrestarted = 0, s;
589
590 s = splbio();
591 if (isp->isp_osinfo.blocked == 0) {
592 struct scsipi_xfer *xs;
593 while ((xs = TAILQ_FIRST(&isp->isp_osinfo.waitq)) != NULL) {
594 TAILQ_REMOVE(&isp->isp_osinfo.waitq, xs, adapter_q);
595 result = ispscsicmd(xs);
596 if (result != CMD_QUEUED) {
597 printf("%s: botched command restart (0x%x)\n",
598 isp->isp_name, result);
599 XS_CMD_S_DONE(xs);
600 if (xs->error == XS_NOERROR)
601 xs->error = XS_DRIVER_STUFFUP;
602 callout_stop(&xs->xs_callout);
603 scsipi_done(xs);
604 } else if (xs->timeout) {
605 callout_reset(&xs->xs_callout,
606 _XT(xs), isp_dog, xs);
607 }
608 nrestarted++;
609 }
610 printf("%s: requeued %d commands\n", isp->isp_name, nrestarted);
611 }
612 (void) splx(s);
613 }
614
615 int
616 isp_async(isp, cmd, arg)
617 struct ispsoftc *isp;
618 ispasync_t cmd;
619 void *arg;
620 {
621 int bus, tgt;
622 int s = splbio();
623 switch (cmd) {
624 case ISPASYNC_NEW_TGT_PARAMS:
625 if (IS_SCSI(isp) && isp->isp_dblev) {
626 sdparam *sdp = isp->isp_param;
627 char *wt;
628 int mhz, flags, period;
629
630 tgt = *((int *) arg);
631 bus = (tgt >> 16) & 0xffff;
632 tgt &= 0xffff;
633 sdp += bus;
634 flags = sdp->isp_devparam[tgt].cur_dflags;
635 period = sdp->isp_devparam[tgt].cur_period;
636
637 if ((flags & DPARM_SYNC) && period &&
638 (sdp->isp_devparam[tgt].cur_offset) != 0) {
639 #if 0
640 /* CAUSES PANICS */
641 static char *m = "%s: bus %d now %s mode\n";
642 u_int16_t r, l;
643 if (bus == 1)
644 r = SXP_PINS_DIFF | SXP_BANK1_SELECT;
645 else
646 r = SXP_PINS_DIFF;
647 l = ISP_READ(isp, r) & ISP1080_MODE_MASK;
648 switch (l) {
649 case ISP1080_LVD_MODE:
650 sdp->isp_lvdmode = 1;
651 printf(m, isp->isp_name, bus, "LVD");
652 break;
653 case ISP1080_HVD_MODE:
654 sdp->isp_diffmode = 1;
655 printf(m, isp->isp_name, bus, "Differential");
656 break;
657 case ISP1080_SE_MODE:
658 sdp->isp_ultramode = 1;
659 printf(m, isp->isp_name, bus, "Single-Ended");
660 break;
661 default:
662 printf("%s: unknown mode on bus %d (0x%x)\n",
663 isp->isp_name, bus, l);
664 break;
665 }
666 #endif
667 /*
668 * There's some ambiguity about our negotiated speed
669 * if we haven't detected LVD mode correctly (which
670 * seems to happen, unfortunately). If we're in LVD
671 * mode, then different rules apply about speed.
672 */
673 if (sdp->isp_lvdmode || period < 0xc) {
674 switch (period) {
675 case 0x9:
676 mhz = 80;
677 break;
678 case 0xa:
679 mhz = 40;
680 break;
681 case 0xb:
682 mhz = 33;
683 break;
684 case 0xc:
685 mhz = 25;
686 break;
687 default:
688 mhz = 1000 / (period * 4);
689 break;
690 }
691 } else {
692 mhz = 1000 / (period * 4);
693 }
694 } else {
695 mhz = 0;
696 }
697 switch (flags & (DPARM_WIDE|DPARM_TQING)) {
698 case DPARM_WIDE:
699 wt = ", 16 bit wide\n";
700 break;
701 case DPARM_TQING:
702 wt = ", Tagged Queueing Enabled\n";
703 break;
704 case DPARM_WIDE|DPARM_TQING:
705 wt = ", 16 bit wide, Tagged Queueing Enabled\n";
706 break;
707 default:
708 wt = "\n";
709 break;
710 }
711 if (mhz) {
712 CFGPRINTF("%s: Bus %d Target %d at %dMHz Max "
713 "Offset %d%s", isp->isp_name, bus, tgt, mhz,
714 sdp->isp_devparam[tgt].cur_offset, wt);
715 } else {
716 CFGPRINTF("%s: Bus %d Target %d Async Mode%s",
717 isp->isp_name, bus, tgt, wt);
718 }
719 break;
720 }
721 case ISPASYNC_BUS_RESET:
722 if (arg)
723 bus = *((int *) arg);
724 else
725 bus = 0;
726 printf("%s: SCSI bus %d reset detected\n", isp->isp_name, bus);
727 break;
728 case ISPASYNC_LOOP_DOWN:
729 /*
730 * Hopefully we get here in time to minimize the number
731 * of commands we are firing off that are sure to die.
732 */
733 isp->isp_osinfo.blocked = 1;
734 printf("%s: Loop DOWN\n", isp->isp_name);
735 break;
736 case ISPASYNC_LOOP_UP:
737 isp->isp_osinfo.blocked = 0;
738 callout_reset(&isp->isp_osinfo._restart, 1,
739 isp_internal_restart, isp);
740 printf("%s: Loop UP\n", isp->isp_name);
741 break;
742 case ISPASYNC_PDB_CHANGED:
743 if (IS_FC(isp) && isp->isp_dblev) {
744 const char *fmt = "%s: Target %d (Loop 0x%x) Port ID 0x%x "
745 "role %s %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x\n";
746 const static char *roles[4] = {
747 "No", "Target", "Initiator", "Target/Initiator"
748 };
749 char *ptr;
750 fcparam *fcp = isp->isp_param;
751 int tgt = *((int *) arg);
752 struct lportdb *lp = &fcp->portdb[tgt];
753
754 if (lp->valid) {
755 ptr = "arrived";
756 } else {
757 ptr = "disappeared";
758 }
759 printf(fmt, isp->isp_name, tgt, lp->loopid, lp->portid,
760 roles[lp->roles & 0x3], ptr,
761 (u_int32_t) (lp->port_wwn >> 32),
762 (u_int32_t) (lp->port_wwn & 0xffffffffLL),
763 (u_int32_t) (lp->node_wwn >> 32),
764 (u_int32_t) (lp->node_wwn & 0xffffffffLL));
765 break;
766 }
767 #ifdef ISP2100_FABRIC
768 case ISPASYNC_CHANGE_NOTIFY:
769 printf("%s: Name Server Database Changed\n", isp->isp_name);
770 break;
771 case ISPASYNC_FABRIC_DEV:
772 {
773 int target;
774 struct lportdb *lp;
775 sns_scrsp_t *resp = (sns_scrsp_t *) arg;
776 u_int32_t portid;
777 u_int64_t wwn;
778 fcparam *fcp = isp->isp_param;
779
780 portid =
781 (((u_int32_t) resp->snscb_port_id[0]) << 16) |
782 (((u_int32_t) resp->snscb_port_id[1]) << 8) |
783 (((u_int32_t) resp->snscb_port_id[2]));
784 wwn =
785 (((u_int64_t)resp->snscb_portname[0]) << 56) |
786 (((u_int64_t)resp->snscb_portname[1]) << 48) |
787 (((u_int64_t)resp->snscb_portname[2]) << 40) |
788 (((u_int64_t)resp->snscb_portname[3]) << 32) |
789 (((u_int64_t)resp->snscb_portname[4]) << 24) |
790 (((u_int64_t)resp->snscb_portname[5]) << 16) |
791 (((u_int64_t)resp->snscb_portname[6]) << 8) |
792 (((u_int64_t)resp->snscb_portname[7]));
793 printf("%s: Fabric Device (Type 0x%x)@PortID 0x%x WWN "
794 "0x%08x%08x\n", isp->isp_name, resp->snscb_port_type,
795 portid, ((u_int32_t)(wwn >> 32)),
796 ((u_int32_t)(wwn & 0xffffffff)));
797 if (resp->snscb_port_type != 2)
798 break;
799 for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
800 lp = &fcp->portdb[target];
801 if (lp->port_wwn == wwn)
802 break;
803 }
804 if (target < MAX_FC_TARG) {
805 break;
806 }
807 for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
808 lp = &fcp->portdb[target];
809 if (lp->port_wwn == 0)
810 break;
811 }
812 if (target == MAX_FC_TARG) {
813 printf("%s: no more space for fabric devices\n",
814 isp->isp_name);
815 return (-1);
816 }
817 lp->port_wwn = lp->node_wwn = wwn;
818 lp->portid = portid;
819 break;
820 }
821 #endif
822 default:
823 break;
824 }
825 (void) splx(s);
826 return (0);
827 }
828