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