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