1 /* $OpenBSD: isp_openbsd.c,v 1.30 2007/04/10 17:47:55 miod Exp $ */
2 /*
3 * Platform (OpenBSD) dependent common attachment code for Qlogic adapters.
4 *
5 * Copyright (c) 1999, 2000, 2001 by Matthew Jacob
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice immediately at the beginning of the file, without modification,
13 * this list of conditions, and the following disclaimer.
14 * documentation and/or other materials provided with the distribution.
15 * 2. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * The author may be reached via electronic communications at
31 *
32 * mjacob@feral.com
33 *
34 * or, via United States Postal Address
35 *
36 * Matthew Jacob
37 * Feral Software
38 * PMB#825
39 * 5214-F Diamond Heights Blvd.
40 * San Francisco, CA, 94131
41 */
42
43 /* expand expensive inline functions here. */
44 #define EXPENSIVE_INLINE
45 #include <dev/ic/isp_openbsd.h>
46
47 /*
48 * Set a timeout for the watchdogging of a command.
49 *
50 * The dimensional analysis is
51 *
52 * milliseconds * (seconds/millisecond) * (ticks/second) = ticks
53 *
54 * =
55 *
56 * (milliseconds / 1000) * hz = ticks
57 *
58 *
59 * For timeouts less than 1 second, we'll get zero. Because of this, and
60 * because we want to establish *our* timeout to be longer than what the
61 * firmware might do, we just add 3 seconds at the back end.
62 */
63 #define _XT(xs) ((((xs)->timeout/1000) * hz) + (3 * hz))
64
65 static void ispminphys(struct buf *);
66 static int32_t ispcmd_slow(XS_T *);
67 static int32_t ispcmd(XS_T *);
68
69 static struct scsi_device isp_dev = { NULL, NULL, NULL, NULL };
70
71 static int isp_polled_cmd (struct ispsoftc *, XS_T *);
72 static void isp_wdog (void *);
73 static void isp_requeue(void *);
74 static void isp_trestart(void *);
75 static void isp_restart(struct ispsoftc *);
76
77 struct cfdriver isp_cd = {
78 NULL, "isp", DV_DULL
79 };
80
81
82 /*
83 * Complete attachment of hardware, include subdevices.
84 */
85 void
86 isp_attach(struct ispsoftc *isp)
87 {
88 struct scsibus_attach_args saa;
89 struct scsi_link *lptr = &isp->isp_osinfo._link[0];
90 isp->isp_osinfo._adapter.scsi_minphys = ispminphys;
91
92 isp->isp_state = ISP_RUNSTATE;
93
94 /*
95 * We only manage a single wait queues for dual bus controllers.
96 * This is arguably broken.
97 */
98 isp->isp_osinfo.wqf = isp->isp_osinfo.wqt = NULL;
99
100 lptr->adapter_softc = isp;
101 lptr->device = &isp_dev;
102 lptr->adapter = &isp->isp_osinfo._adapter;
103 lptr->openings = imin(isp->isp_maxcmds, MAXISPREQUEST(isp));
104 isp->isp_osinfo._adapter.scsi_cmd = ispcmd_slow;
105 if (IS_FC(isp)) {
106 lptr->adapter_buswidth = MAX_FC_TARG;
107 /* We can set max lun width here */
108 /* loopid set below */
109 } else {
110 sdparam *sdp = isp->isp_param;
111 lptr->adapter_buswidth = MAX_TARGETS;
112 /* We can set max lun width here */
113 lptr->adapter_target = sdp->isp_initiator_id;
114 isp->isp_osinfo.discovered[0] = 1 << sdp->isp_initiator_id;
115 if (IS_DUALBUS(isp)) {
116 struct scsi_link *lptrb = &isp->isp_osinfo._link[1];
117 lptrb->adapter_softc = isp;
118 lptrb->device = &isp_dev;
119 lptrb->adapter = &isp->isp_osinfo._adapter;
120 lptrb->openings = lptr->openings;
121 lptrb->adapter_buswidth = MAX_TARGETS;
122 lptrb->adapter_target = sdp->isp_initiator_id;
123 lptrb->flags = SDEV_2NDBUS;
124 isp->isp_osinfo.discovered[1] =
125 1 << (sdp+1)->isp_initiator_id;
126 }
127 }
128
129 /*
130 * Send a SCSI Bus Reset (used to be done as part of attach,
131 * but now left to the OS outer layers).
132 *
133 * We don't do 'bus resets' for FC because the LIP that occurs
134 * when we start the firmware does all that for us.
135 */
136 if (IS_SCSI(isp)) {
137 int bus = 0;
138 ISP_LOCK(isp);
139 (void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
140 if (IS_DUALBUS(isp)) {
141 bus++;
142 (void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
143 }
144 ISP_UNLOCK(isp);
145 /*
146 * wait for the bus to settle.
147 */
148 delay(4 * 1000000);
149 } else {
150 fcparam *fcp = isp->isp_param;
151 int defid = MAX_FC_TARG;
152 delay(2 * 1000000);
153 ISP_LOCK(isp);
154 isp_fc_runstate(isp, 10 * 1000000);
155 if (fcp->isp_fwstate == FW_READY &&
156 fcp->isp_loopstate >= LOOP_PDB_RCVD) {
157 defid = fcp->isp_loopid;
158 }
159 ISP_UNLOCK(isp);
160 lptr->adapter_target = defid;
161 }
162
163 bzero(&saa, sizeof(saa));
164 saa.saa_sc_link = lptr;
165
166 /*
167 * And attach children (if any).
168 */
169 config_found((void *)isp, &saa, scsiprint);
170 if (IS_DUALBUS(isp)) {
171 lptr++;
172 bzero(&saa, sizeof(saa));
173 saa.saa_sc_link = lptr;
174 config_found((void *)isp, &saa, scsiprint);
175 }
176 }
177
178 /*
179 * minphys our xfers
180 *
181 * Unfortunately, the buffer pointer describes the target device- not the
182 * adapter device, so we can't use the pointer to find out what kind of
183 * adapter we are and adjust accordingly.
184 */
185
186 static void
187 ispminphys(struct buf *bp)
188 {
189 /*
190 * XX: Only the 1020 has a 24 bit limit.
191 */
192 if (bp->b_bcount >= (1 << 24)) {
193 bp->b_bcount = (1 << 24);
194 }
195 minphys(bp);
196 }
197
198 static int32_t
199 ispcmd_slow(XS_T *xs)
200 {
201 sdparam *sdp;
202 int tgt, chan;
203 u_int16_t f;
204 struct ispsoftc *isp = XS_ISP(xs);
205
206 if (IS_FC(isp)) {
207 if (cold == 0) {
208 isp->isp_osinfo.no_mbox_ints = 0;
209 isp->isp_osinfo._adapter.scsi_cmd = ispcmd;
210 }
211 return (ispcmd(xs));
212 }
213
214 /*
215 * Have we completed discovery for this target on this adapter?
216 */
217 sdp = isp->isp_param;
218 tgt = XS_TGT(xs);
219 chan = XS_CHANNEL(xs);
220 sdp += chan;
221 if ((xs->flags & SCSI_POLL) != 0 ||
222 (isp->isp_osinfo.discovered[chan] & (1 << tgt)) != 0) {
223 return (ispcmd(xs));
224 }
225 if (cold == 0) {
226 isp->isp_osinfo.no_mbox_ints = 0;
227 }
228
229 f = DPARM_DEFAULT;
230 if (xs->sc_link->quirks & SDEV_NOSYNC) {
231 f &= ~DPARM_SYNC;
232 }
233 if (xs->sc_link->quirks & SDEV_NOWIDE) {
234 f &= ~DPARM_WIDE;
235 }
236 if (xs->sc_link->quirks & SDEV_NOTAGS) {
237 f &= ~DPARM_TQING;
238 }
239
240 /*
241 * Okay, we know about this device now,
242 * so mark parameters to be updated for it.
243 */
244 sdp->isp_devparam[tgt].goal_flags = f;
245 sdp->isp_devparam[tgt].dev_update = 1;
246 isp->isp_update |= (1 << chan);
247
248 /*
249 * Now check to see whether we can get out of this checking mode now.
250 * XXX: WE CANNOT AS YET BECAUSE THERE IS NO MECHANISM TO TELL US
251 * XXX: WHEN WE'RE DONE DISCOVERY BECAUSE WE NEED ONE COMMAND AFTER
252 * XXX: DISCOVERY IS DONE FOR EACH TARGET TO TELL US THAT WE'RE DONE
253 * XXX: AND THAT DOESN'T HAPPEN HERE. AT BEST WE CAN MARK OURSELVES
254 * XXX: DONE WITH DISCOVERY FOR THIS TARGET AND SO SAVE MAYBE 20
255 * XXX: LINES OF C CODE.
256 */
257 isp->isp_osinfo.discovered[chan] |= (1 << tgt);
258 /* do not bother with these lines- they'll never execute correctly */
259 #if 0
260 sdp = isp->isp_param;
261 for (chan = 0; chan < (IS_12X0(isp)? 2 : 1); chan++, sdp++) {
262 f = 0xffff & ~(1 << sdp->isp_initiator_id);
263 if (isp->isp_osinfo.discovered[chan] != f) {
264 break;
265 }
266 }
267 if (chan == (IS_12X0(isp)? 2 : 1)) {
268 isp->isp_osinfo._adapter.scsipi_cmd = ispcmd;
269 if (IS_12X0(isp))
270 isp->isp_update |= 2;
271 }
272 #endif
273 return (ispcmd(xs));
274 }
275
276 static INLINE void isp_add2_blocked_queue(struct ispsoftc *, XS_T *);
277
278 static INLINE void
279 isp_add2_blocked_queue(struct ispsoftc *isp, XS_T *xs)
280 {
281 if (isp->isp_osinfo.wqf != NULL) {
282 isp->isp_osinfo.wqt->free_list.le_next = xs;
283 } else {
284 isp->isp_osinfo.wqf = xs;
285 }
286 isp->isp_osinfo.wqt = xs;
287 xs->free_list.le_next = NULL;
288 }
289
290 static int32_t
291 ispcmd(XS_T *xs)
292 {
293 struct ispsoftc *isp;
294 int result;
295
296
297 /*
298 * Make sure that there's *some* kind of sane setting.
299 */
300 isp = XS_ISP(xs);
301
302 timeout_set(&xs->stimeout, isp_wdog, isp);
303
304 if (XS_LUN(xs) >= isp->isp_maxluns) {
305 xs->error = XS_SELTIMEOUT;
306 return (COMPLETE);
307 }
308
309 ISP_LOCK(isp);
310 if (isp->isp_state < ISP_RUNSTATE) {
311 DISABLE_INTS(isp);
312 isp_init(isp);
313 if (isp->isp_state != ISP_INITSTATE) {
314 ENABLE_INTS(isp);
315 ISP_UNLOCK(isp);
316 XS_SETERR(xs, HBA_BOTCH);
317 return (CMD_COMPLETE);
318 }
319 isp->isp_state = ISP_RUNSTATE;
320 ENABLE_INTS(isp);
321 }
322
323 /*
324 * Check for queue blockage...
325 */
326 if (isp->isp_osinfo.blocked) {
327 if (xs->flags & SCSI_POLL) {
328 ISP_UNLOCK(isp);
329 return (TRY_AGAIN_LATER);
330 }
331 if (isp->isp_osinfo.blocked == 2) {
332 isp_restart(isp);
333 }
334 if (isp->isp_osinfo.blocked) {
335 isp_add2_blocked_queue(isp, xs);
336 ISP_UNLOCK(isp);
337 isp_prt(isp, ISP_LOGDEBUG0, "added to blocked queue");
338 return (SUCCESSFULLY_QUEUED);
339 }
340 }
341
342 if (xs->flags & SCSI_POLL) {
343 volatile u_int8_t ombi = isp->isp_osinfo.no_mbox_ints;
344 isp->isp_osinfo.no_mbox_ints = 1;
345 result = isp_polled_cmd(isp, xs);
346 isp->isp_osinfo.no_mbox_ints = ombi;
347 ISP_UNLOCK(isp);
348 return (result);
349 }
350
351 result = isp_start(xs);
352
353 switch (result) {
354 case CMD_QUEUED:
355 result = SUCCESSFULLY_QUEUED;
356 if (xs->timeout) {
357 timeout_add(&xs->stimeout, _XT(xs));
358 XS_CMD_S_TIMER(xs);
359 }
360 if (isp->isp_osinfo.hiwater < isp->isp_nactive) {
361 isp->isp_osinfo.hiwater = isp->isp_nactive;
362 isp_prt(isp, ISP_LOGDEBUG0,
363 "Active Hiwater Mark=%d", isp->isp_nactive);
364 }
365 break;
366 case CMD_EAGAIN:
367 isp->isp_osinfo.blocked |= 2;
368 isp_prt(isp, ISP_LOGDEBUG0, "blocking queue");
369 isp_add2_blocked_queue(isp, xs);
370 result = SUCCESSFULLY_QUEUED;
371 break;
372 case CMD_RQLATER:
373 result = SUCCESSFULLY_QUEUED; /* Lie */
374 isp_prt(isp, ISP_LOGDEBUG1, "retrying later for %d.%d",
375 XS_TGT(xs), XS_LUN(xs));
376 timeout_set(&xs->stimeout, isp_requeue, xs);
377 timeout_add(&xs->stimeout, hz);
378 XS_CMD_S_TIMER(xs);
379 break;
380 case CMD_COMPLETE:
381 result = COMPLETE;
382 break;
383 }
384 ISP_UNLOCK(isp);
385 return (result);
386 }
387
388 static int
389 isp_polled_cmd(struct ispsoftc *isp, XS_T *xs)
390 {
391 int result;
392 int infinite = 0, mswait;
393
394 result = isp_start(xs);
395
396 switch (result) {
397 case CMD_QUEUED:
398 result = SUCCESSFULLY_QUEUED;
399 break;
400 case CMD_RQLATER:
401 case CMD_EAGAIN:
402 result = TRY_AGAIN_LATER;
403 break;
404 case CMD_COMPLETE:
405 result = COMPLETE;
406 break;
407
408 }
409
410 if (result != SUCCESSFULLY_QUEUED) {
411 return (result);
412 }
413
414 /*
415 * If we can't use interrupts, poll on completion.
416 */
417 if ((mswait = XS_TIME(xs)) == 0)
418 infinite = 1;
419
420 while (mswait || infinite) {
421 u_int16_t isr, sema, mbox;
422 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
423 isp_intr(isp, isr, sema, mbox);
424 if (XS_CMD_DONE_P(xs)) {
425 break;
426 }
427 }
428 USEC_DELAY(1000);
429 mswait -= 1;
430 }
431
432 /*
433 * If no other error occurred but we didn't finish,
434 * something bad happened.
435 */
436 if (XS_CMD_DONE_P(xs) == 0) {
437 if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) {
438 isp_reinit(isp);
439 }
440 if (XS_NOERR(xs)) {
441 XS_SETERR(xs, HBA_BOTCH);
442 }
443 }
444 result = COMPLETE;
445 return (result);
446 }
447
448 void
449 isp_done(XS_T *xs)
450 {
451 XS_CMD_S_DONE(xs);
452 if (XS_CMD_WDOG_P(xs) == 0) {
453 struct ispsoftc *isp = XS_ISP(xs);
454 if (XS_CMD_TIMER_P(xs)) {
455 timeout_del(&xs->stimeout);
456 XS_CMD_C_TIMER(xs);
457 }
458 if (XS_CMD_GRACE_P(xs)) {
459 struct ispsoftc *isp = XS_ISP(xs);
460 isp_prt(isp, ISP_LOGWARN,
461 "finished command on borrowed time");
462 }
463 XS_CMD_S_CLEAR(xs);
464 scsi_done(xs);
465 if (isp->isp_osinfo.blocked == 2) {
466 isp->isp_osinfo.blocked = 0;
467 isp_prt(isp, ISP_LOGDEBUG0, "restarting blocked queue");
468 isp_restart(isp);
469 }
470 }
471 }
472
473 static void
474 isp_wdog(void *arg)
475 {
476 XS_T *xs = arg;
477 struct ispsoftc *isp = XS_ISP(xs);
478 u_int32_t handle;
479
480 /*
481 * We've decided this command is dead. Make sure we're not trying
482 * to kill a command that's already dead by getting its handle and
483 * and seeing whether it's still alive.
484 */
485 ISP_LOCK(isp);
486 handle = isp_find_handle(isp, xs);
487 if (handle) {
488 u_int16_t isr, sema, mbox;
489
490 if (XS_CMD_DONE_P(xs)) {
491 isp_prt(isp, ISP_LOGDEBUG1,
492 "watchdog found done cmd (handle 0x%x)",
493 handle);
494 ISP_UNLOCK(isp);
495 return;
496 }
497
498 if (XS_CMD_WDOG_P(xs)) {
499 isp_prt(isp, ISP_LOGDEBUG1,
500 "recursive watchdog (handle 0x%x)",
501 handle);
502 ISP_UNLOCK(isp);
503 return;
504 }
505
506 XS_CMD_S_WDOG(xs);
507
508 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
509 isp_intr(isp, isr, sema, mbox);
510 }
511
512 if (XS_CMD_DONE_P(xs)) {
513 isp_prt(isp, ISP_LOGINFO,
514 "watchdog cleanup for handle 0x%x", handle);
515 XS_CMD_C_WDOG(xs);
516 isp_done(xs);
517 } else if (XS_CMD_GRACE_P(xs)) {
518 /*
519 * Make sure the command is *really* dead before we
520 * release the handle (and DMA resources) for reuse.
521 */
522 (void) isp_control(isp, ISPCTL_ABORT_CMD, arg);
523
524 /*
525 * After this point, the command is really dead.
526 */
527 if (XS_XFRLEN(xs)) {
528 ISP_DMAFREE(isp, xs, handle);
529 }
530 isp_prt(isp, ISP_LOGWARN,
531 "watchdog timeout on handle %x", handle);
532 isp_destroy_handle(isp, handle);
533 XS_SETERR(xs, XS_TIMEOUT);
534 XS_CMD_S_CLEAR(xs);
535 isp_done(xs);
536 } else {
537 u_int16_t nxti, optr;
538 ispreq_t local, *mp = &local, *qe;
539
540 isp_prt(isp, ISP_LOGWARN,
541 "possible command timeout on handle %x", handle);
542
543 XS_CMD_C_WDOG(xs);
544 timeout_add(&xs->stimeout, _XT(xs));
545 XS_CMD_S_TIMER(xs);
546 if (isp_getrqentry(isp, &nxti, &optr, (void **) &qe)) {
547 ISP_UNLOCK(isp);
548 return;
549 }
550 XS_CMD_S_GRACE(xs);
551 MEMZERO((void *) mp, sizeof (*mp));
552 mp->req_header.rqs_entry_count = 1;
553 mp->req_header.rqs_entry_type = RQSTYPE_MARKER;
554 mp->req_modifier = SYNC_ALL;
555 mp->req_target = XS_CHANNEL(xs) << 7;
556 isp_put_request(isp, mp, qe);
557 ISP_ADD_REQUEST(isp, nxti);
558 }
559 } else if (isp->isp_dblev) {
560 isp_prt(isp, ISP_LOGDEBUG1, "watchdog with no command");
561 }
562 ISP_UNLOCK(isp);
563 }
564
565 /*
566 * Free any associated resources prior to decommissioning and
567 * set the card to a known state (so it doesn't wake up and kick
568 * us when we aren't expecting it to).
569 *
570 * Locks are held before coming here.
571 */
572 void
573 isp_uninit(struct ispsoftc *isp)
574 {
575 ISP_LOCK(isp);
576 /*
577 * Leave with interrupts disabled.
578 */
579 DISABLE_INTS(isp);
580
581 ISP_UNLOCK(isp);
582 }
583
584 /*
585 * Restart function for a command to be requeued later.
586 */
587 static void
588 isp_requeue(void *arg)
589 {
590 int r;
591 struct scsi_xfer *xs = arg;
592 struct ispsoftc *isp = XS_ISP(xs);
593 ISP_LOCK(isp);
594 r = isp_start(xs);
595 switch (r) {
596 case CMD_QUEUED:
597 isp_prt(isp, ISP_LOGDEBUG1, "restarted command for %d.%d",
598 XS_TGT(xs), XS_LUN(xs));
599 if (xs->timeout) {
600 timeout_set(&xs->stimeout, isp_wdog, isp);
601 timeout_add(&xs->stimeout, _XT(xs));
602 XS_CMD_S_TIMER(xs);
603 }
604 break;
605 case CMD_EAGAIN:
606 isp_prt(isp, ISP_LOGDEBUG0, "blocked cmd again");
607 isp->isp_osinfo.blocked |= 2;
608 isp_add2_blocked_queue(isp, xs);
609 break;
610 case CMD_RQLATER:
611 isp_prt(isp, ISP_LOGDEBUG0, "%s for %d.%d",
612 (r == CMD_EAGAIN)? "CMD_EAGAIN" : "CMD_RQLATER",
613 XS_TGT(xs), XS_LUN(xs));
614 timeout_set(&xs->stimeout, isp_requeue, xs);
615 timeout_add(&xs->stimeout, hz);
616 XS_CMD_S_TIMER(xs);
617 break;
618 case CMD_COMPLETE:
619 /* can only be an error */
620 if (XS_NOERR(xs))
621 XS_SETERR(xs, XS_DRIVER_STUFFUP);
622 isp_done(xs);
623 break;
624 }
625 ISP_UNLOCK(isp);
626 }
627
628 /*
629 * Restart function after a LOOP UP event or a command completing,
630 * sometimes done as a timeout for some hysteresis.
631 */
632 static void
633 isp_trestart(void *arg)
634 {
635 struct ispsoftc *isp = arg;
636 struct scsi_xfer *list;
637
638 ISP_LOCK(isp);
639 isp->isp_osinfo.rtpend = 0;
640 list = isp->isp_osinfo.wqf;
641 if (isp->isp_osinfo.blocked == 0 && list != NULL) {
642 int nrestarted = 0;
643
644 isp->isp_osinfo.wqf = NULL;
645 ISP_UNLOCK(isp);
646 do {
647 struct scsi_xfer *xs = list;
648 list = xs->free_list.le_next;
649 xs->free_list.le_next = NULL;
650 isp_requeue(xs);
651 if (isp->isp_osinfo.wqf == NULL)
652 nrestarted++;
653 } while (list != NULL);
654 isp_prt(isp, ISP_LOGDEBUG0, "requeued %d commands", nrestarted);
655 } else {
656 ISP_UNLOCK(isp);
657 }
658 }
659
660 static void
661 isp_restart(struct ispsoftc *isp)
662 {
663 struct scsi_xfer *list;
664
665 list = isp->isp_osinfo.wqf;
666 if (isp->isp_osinfo.blocked == 0 && list != NULL) {
667 int nrestarted = 0;
668
669 isp->isp_osinfo.wqf = NULL;
670 do {
671 struct scsi_xfer *xs = list;
672 list = xs->free_list.le_next;
673 xs->free_list.le_next = NULL;
674 isp_requeue(xs);
675 if (isp->isp_osinfo.wqf == NULL)
676 nrestarted++;
677 } while (list != NULL);
678 isp_prt(isp, ISP_LOGDEBUG0, "requeued %d commands", nrestarted);
679 }
680 }
681
682 int
683 isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
684 {
685 int bus, tgt;
686
687 switch (cmd) {
688 case ISPASYNC_NEW_TGT_PARAMS:
689 if (IS_SCSI(isp) && isp->isp_dblev) {
690 sdparam *sdp = isp->isp_param;
691 char *wt;
692 int mhz, flags, period;
693
694 tgt = *((int *) arg);
695 bus = (tgt >> 16) & 0xffff;
696 tgt &= 0xffff;
697 sdp += bus;
698 flags = sdp->isp_devparam[tgt].actv_flags;
699 period = sdp->isp_devparam[tgt].actv_period;
700
701 if ((flags & DPARM_SYNC) && period &&
702 (sdp->isp_devparam[tgt].actv_offset) != 0) {
703 /*
704 * There's some ambiguity about our negotiated speed
705 * if we haven't detected LVD mode correctly (which
706 * seems to happen, unfortunately). If we're in LVD
707 * mode, then different rules apply about speed.
708 */
709 if (sdp->isp_lvdmode || period < 0xc) {
710 switch (period) {
711 case 0x9:
712 mhz = 80;
713 break;
714 case 0xa:
715 mhz = 40;
716 break;
717 case 0xb:
718 mhz = 33;
719 break;
720 case 0xc:
721 mhz = 25;
722 break;
723 default:
724 mhz = 1000 / (period * 4);
725 break;
726 }
727 } else {
728 mhz = 1000 / (period * 4);
729 }
730 } else {
731 mhz = 0;
732 }
733 switch (flags & (DPARM_WIDE|DPARM_TQING)) {
734 case DPARM_WIDE:
735 wt = ", 16 bit wide";
736 break;
737 case DPARM_TQING:
738 wt = ", Tagged Queueing Enabled";
739 break;
740 case DPARM_WIDE|DPARM_TQING:
741 wt = ", 16 bit wide, Tagged Queueing Enabled";
742 break;
743 default:
744 wt = " ";
745 break;
746 }
747 if (mhz) {
748 isp_prt(isp, ISP_LOGINFO,
749 "Bus %d Target %d at %dMHz Max Offset %d%s",
750 bus, tgt, mhz, sdp->isp_devparam[tgt].actv_offset,
751 wt);
752 } else {
753 isp_prt(isp, ISP_LOGINFO,
754 "Bus %d Target %d Async Mode%s", bus, tgt, wt);
755 }
756 break;
757 }
758 case ISPASYNC_BUS_RESET:
759 if (arg)
760 bus = *((int *) arg);
761 else
762 bus = 0;
763 isp_prt(isp, ISP_LOGINFO, "SCSI bus %d reset detected", bus);
764 break;
765 case ISPASYNC_LOOP_DOWN:
766 /*
767 * Hopefully we get here in time to minimize the number
768 * of commands we are firing off that are sure to die.
769 */
770 isp->isp_osinfo.blocked |= 1;
771 isp_prt(isp, ISP_LOGINFO, "Loop DOWN");
772 break;
773 case ISPASYNC_LOOP_UP:
774 isp->isp_osinfo.blocked &= ~1;
775 if (isp->isp_osinfo.rtpend == 0) {
776 timeout_set(&isp->isp_osinfo.rqt, isp_trestart, isp);
777 isp->isp_osinfo.rtpend = 1;
778 }
779 timeout_add(&isp->isp_osinfo.rqt, 1);
780 isp_prt(isp, ISP_LOGINFO, "Loop UP");
781 break;
782 case ISPASYNC_PROMENADE:
783 if (IS_FC(isp) && isp->isp_dblev) {
784 const char *fmt = "Target %d (Loop 0x%x) Port ID 0x%x "
785 "role %s %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x";
786 const static char *roles[4] = {
787 "No", "Target", "Initiator", "Target/Initiator"
788 };
789 fcparam *fcp = isp->isp_param;
790 int tgt = *((int *) arg);
791 struct lportdb *lp = &fcp->portdb[tgt];
792
793 isp_prt(isp, ISP_LOGINFO, fmt, tgt, lp->loopid, lp->portid,
794 roles[lp->roles & 0x3],
795 (lp->valid)? "Arrived" : "Departed",
796 (u_int32_t) (lp->port_wwn >> 32),
797 (u_int32_t) (lp->port_wwn & 0xffffffffLL),
798 (u_int32_t) (lp->node_wwn >> 32),
799 (u_int32_t) (lp->node_wwn & 0xffffffffLL));
800 break;
801 }
802 case ISPASYNC_CHANGE_NOTIFY:
803 if (arg == (void *) 1) {
804 isp_prt(isp, ISP_LOGINFO,
805 "Name Server Database Changed");
806 } else {
807 isp_prt(isp, ISP_LOGINFO,
808 "Name Server Database Changed");
809 }
810 break;
811 case ISPASYNC_FABRIC_DEV:
812 {
813 int target, base, lim;
814 fcparam *fcp = isp->isp_param;
815 struct lportdb *lp = NULL;
816 struct lportdb *clp = (struct lportdb *) arg;
817 char *pt;
818
819 switch (clp->port_type) {
820 case 1:
821 pt = " N_Port";
822 break;
823 case 2:
824 pt = " NL_Port";
825 break;
826 case 3:
827 pt = "F/NL_Port";
828 break;
829 case 0x7f:
830 pt = " Nx_Port";
831 break;
832 case 0x81:
833 pt = " F_port";
834 break;
835 case 0x82:
836 pt = " FL_Port";
837 break;
838 case 0x84:
839 pt = " E_port";
840 break;
841 default:
842 pt = " ";
843 break;
844 }
845
846 isp_prt(isp, ISP_LOGINFO,
847 "%s Fabric Device @ PortID 0x%x", pt, clp->portid);
848
849 /*
850 * If we don't have an initiator role we bail.
851 *
852 * We just use ISPASYNC_FABRIC_DEV for announcement purposes.
853 */
854
855 if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
856 break;
857 }
858
859 /*
860 * Is this entry for us? If so, we bail.
861 */
862
863 if (fcp->isp_portid == clp->portid) {
864 break;
865 }
866
867 /*
868 * Else, the default policy is to find room for it in
869 * our local port database. Later, when we execute
870 * the call to isp_pdb_sync either this newly arrived
871 * or already logged in device will be (re)announced.
872 */
873
874 if (fcp->isp_topo == TOPO_FL_PORT)
875 base = FC_SNS_ID+1;
876 else
877 base = 0;
878
879 if (fcp->isp_topo == TOPO_N_PORT)
880 lim = 1;
881 else
882 lim = MAX_FC_TARG;
883
884 /*
885 * Is it already in our list?
886 */
887 for (target = base; target < lim; target++) {
888 if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
889 continue;
890 }
891 lp = &fcp->portdb[target];
892 if (lp->port_wwn == clp->port_wwn &&
893 lp->node_wwn == clp->node_wwn) {
894 lp->fabric_dev = 1;
895 break;
896 }
897 }
898 if (target < lim) {
899 break;
900 }
901 for (target = base; target < lim; target++) {
902 if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
903 continue;
904 }
905 lp = &fcp->portdb[target];
906 if (lp->port_wwn == 0) {
907 break;
908 }
909 }
910 if (target == lim) {
911 isp_prt(isp, ISP_LOGWARN,
912 "out of space for fabric devices");
913 break;
914 }
915 lp->port_type = clp->port_type;
916 lp->fc4_type = clp->fc4_type;
917 lp->node_wwn = clp->node_wwn;
918 lp->port_wwn = clp->port_wwn;
919 lp->portid = clp->portid;
920 lp->fabric_dev = 1;
921 break;
922 }
923 case ISPASYNC_FW_CRASH:
924 {
925 u_int16_t mbox1, mbox6;
926 mbox1 = ISP_READ(isp, OUTMAILBOX1);
927 if (IS_DUALBUS(isp)) {
928 mbox6 = ISP_READ(isp, OUTMAILBOX6);
929 } else {
930 mbox6 = 0;
931 }
932 isp_prt(isp, ISP_LOGERR,
933 "Internal Firmware Error on bus %d @ RISC Address 0x%x",
934 mbox6, mbox1);
935 #ifdef ISP_FW_CRASH_DUMP
936 if (IS_FC(isp)) {
937 isp->isp_osinfo.blocked |= 1;
938 isp_fw_dump(isp);
939 }
940 isp_reinit(isp);
941 isp_async(isp, ISPASYNC_FW_RESTART, NULL);
942 #endif
943 break;
944 }
945 default:
946 break;
947 }
948 return (0);
949 }
950
951 void
952 isp_prt(struct ispsoftc *isp, int level, const char *fmt, ...)
953 {
954 va_list ap;
955 if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
956 return;
957 }
958 printf("%s: ", isp->isp_name);
959 va_start(ap, fmt);
960 vprintf(fmt, ap);
961 va_end(ap);
962 printf("\n");
963 }