1 /* $FreeBSD: src/sys/dev/isp/isp_freebsd.c,v 1.20.2.5 2000/03/04 06:04:52 mjacob Exp $ */
2 /*
3 * Platform (FreeBSD 2.X) dependent common attachment code for Qlogic adapters.
4 *
5 *---------------------------------------
6 * Copyright (c) 1997, 1998 by Matthew Jacob
7 * NASA/Ames Research Center
8 * All rights reserved.
9 *---------------------------------------
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice immediately at the beginning of the file, without modification,
16 * this list of conditions, and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
27 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35 #include <dev/isp/isp_freebsd.h>
36
37 static void ispminphys(struct buf *);
38 static u_int32_t isp_adapter_info(int);
39 static int ispcmd_slow(struct scsi_xfer *);
40 static int ispcmd(struct scsi_xfer *);
41 static struct scsi_adapter isp_switch = {
42 ispcmd_slow, ispminphys, 0, 0, isp_adapter_info, "isp", { 0, 0 }
43 };
44 static struct scsi_device isp_dev = {
45 NULL, NULL, NULL, NULL, "isp", 0, { 0, 0 }
46 };
47 static int isp_poll(struct ispsoftc *, struct scsi_xfer *, int);
48 static void isp_watch(void *);
49 static void isp_command_requeue(void *);
50 static void isp_internal_restart(void *);
51
52 /*
53 * Complete attachment of hardware, include subdevices.
54 */
55 void
56 isp_attach(struct ispsoftc *isp)
57 {
58 struct scsibus_data *scbus, *scbusb = NULL;
59
60 scbus = scsi_alloc_bus();
61 if(!scbus) {
62 return;
63 }
64
65 isp->isp_state = ISP_RUNSTATE;
66
67 isp->isp_osinfo._link.adapter_unit = isp->isp_osinfo.unit;
68 isp->isp_osinfo._link.adapter_softc = isp;
69 isp->isp_osinfo._link.device = &isp_dev;
70 isp->isp_osinfo._link.flags = 0;
71 isp->isp_osinfo._link.opennings = isp->isp_maxcmds;
72 isp->isp_osinfo._link.adapter = &isp_switch;
73 isp->isp_osinfo.wqf = isp->isp_osinfo.wqt = NULL;
74
75 if (IS_FC(isp)) {
76 int i, j;
77 fcparam *fcp = isp->isp_param;
78 SYS_DELAY(2 * 1000000);
79 for (j = 0; j < 5; j++) {
80 for (i = 0; i < 5; i++) {
81 if (isp_control(isp, ISPCTL_FCLINK_TEST, NULL))
82 continue;
83 #ifdef ISP2100_FABRIC
84 /*
85 * Wait extra time to see if the f/w
86 * eventually completed an FLOGI that
87 * will allow us to know we're on a
88 * fabric.
89 */
90 if (fcp->isp_onfabric == 0) {
91 SYS_DELAY(1 * 1000000);
92 continue;
93 }
94 #endif
95 break;
96 }
97 if (fcp->isp_fwstate == FW_READY &&
98 fcp->isp_loopstate >= LOOP_PDB_RCVD) {
99 break;
100 }
101 }
102 isp->isp_osinfo._link.adapter_targ = fcp->isp_loopid;
103 scbus->maxtarg = MAX_FC_TARG-1;
104 } else {
105 int bus = 0;
106 sdparam *sdp = isp->isp_param;
107
108 (void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
109
110 isp->isp_osinfo.discovered[0] = 1 << sdp->isp_initiator_id;
111 isp->isp_osinfo._link.adapter_targ = sdp->isp_initiator_id;
112 scbus->maxtarg = MAX_TARGETS-1;
113 if (IS_DUALBUS(isp) && (scbusb = scsi_alloc_bus()) != NULL) {
114 sdp++;
115 isp->isp_osinfo._link_b = isp->isp_osinfo._link;
116 isp->isp_osinfo._link_b.adapter_targ =
117 sdp->isp_initiator_id;
118 isp->isp_osinfo.discovered[1] =
119 1 << sdp->isp_initiator_id;
120 isp->isp_osinfo._link_b.adapter_bus = 1;
121 scbusb->maxtarg = MAX_TARGETS-1;
122 bus++;
123 (void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
124 }
125 SYS_DELAY(2*1000000);
126 }
127
128
129 /*
130 * Start the watchdog.
131 */
132 timeout(isp_watch, isp, WATCH_INTERVAL * hz);
133 isp->isp_dogactive = 1;
134
135 /*
136 * Prepare the scsibus_data area for the upperlevel scsi code.
137 */
138 scbus->adapter_link = &isp->isp_osinfo._link;
139
140 /*
141 * ask the adapter what subunits are present
142 */
143 scsi_attachdevs(scbus);
144
145 /*
146 * Attach second bus if there.
147 */
148 if (scbusb) {
149 scbusb->adapter_link = &isp->isp_osinfo._link_b;
150 scsi_attachdevs(scbusb);
151 }
152 }
153
154
155 /*
156 * minphys our xfers
157 *
158 * Unfortunately, the buffer pointer describes the target device- not the
159 * adapter device, so we can't use the pointer to find out what kind of
160 * adapter we are and adjust accordingly.
161 */
162
163 static void
164 ispminphys(struct buf *bp)
165 {
166 /*
167 * Only the 1020/1040 has a 24 bit limit.
168 */
169 if (bp->b_bcount >= (1 << 24)) {
170 bp->b_bcount = (1 << 24);
171 }
172 }
173
174 static u_int32_t
175 isp_adapter_info(int unit)
176 {
177 return (2);
178 }
179
180 static int
181 ispcmd_slow(struct scsi_xfer *xs)
182 {
183 struct ispsoftc *isp = XS_ISP(xs);
184 /*
185 * Have we completed discovery for this adapter?
186 */
187 if (IS_SCSI(isp) && (xs->flags & SCSI_NOMASK) == 0) {
188 sdparam *sdp = isp->isp_param;
189 int s = splbio();
190 int chan = XS_CHANNEL(xs), chmax = IS_DUALBUS(isp)? 2 : 1;
191 u_int16_t f = DPARM_DEFAULT;
192
193 sdp += chan;
194 if (xs->sc_link->quirks & SCSI_Q_NO_SYNC) {
195 f ^= DPARM_SYNC;
196 }
197 if (xs->sc_link->quirks & SCSI_Q_NO_WIDE) {
198 f ^= DPARM_WIDE;
199 }
200 if (xs->sc_link->quirks & SD_Q_NO_TAGS) {
201 f ^= DPARM_TQING;
202 }
203 sdp->isp_devparam[XS_TGT(xs)].dev_flags = f;
204 sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
205 isp->isp_update |= (1 << chan);
206 isp->isp_osinfo.discovered[chan] |= (1 << XS_TGT(xs));
207 for (chan = 0; chan < chmax; chan++) {
208 sdp = isp->isp_param;
209 sdp += chan;
210 f = 0xffff & ~(1 << sdp->isp_initiator_id);
211 if (isp->isp_osinfo.discovered[chan] != f) {
212 break;
213 }
214 }
215 if (chan == chmax) {
216 isp_switch.scsi_cmd = ispcmd;
217 }
218 (void) splx(s);
219 }
220 return (ispcmd(xs));
221 }
222
223 static int
224 ispcmd(struct scsi_xfer *xs)
225 {
226 struct ispsoftc *isp;
227 int result, s;
228
229 isp = XS_ISP(xs);
230 s = splbio();
231 if (isp->isp_state < ISP_RUNSTATE) {
232 DISABLE_INTS(isp);
233 isp_init(isp);
234 if (isp->isp_state != ISP_INITSTATE) {
235 ENABLE_INTS(isp);
236 (void) splx(s);
237 XS_SETERR(xs, HBA_BOTCH);
238 return (CMD_COMPLETE);
239 }
240 isp->isp_state = ISP_RUNSTATE;
241 ENABLE_INTS(isp);
242 }
243
244 /*
245 * Check for queue blockage...
246 */
247 if (isp->isp_osinfo.blocked) {
248 if (xs->flags & SCSI_NOMASK) {
249 xs->error = XS_DRIVER_STUFFUP;
250 splx(s);
251 return (TRY_AGAIN_LATER);
252 }
253 if (isp->isp_osinfo.wqf != NULL) {
254 isp->isp_osinfo.wqt->next = xs;
255 } else {
256 isp->isp_osinfo.wqf = xs;
257 }
258 isp->isp_osinfo.wqt = xs;
259 xs->next = NULL;
260 splx(s);
261 return (SUCCESSFULLY_QUEUED);
262 }
263 DISABLE_INTS(isp);
264 result = ispscsicmd(xs);
265 ENABLE_INTS(isp);
266
267 if ((xs->flags & SCSI_NOMASK) == 0) {
268 switch (result) {
269 case CMD_QUEUED:
270 result = SUCCESSFULLY_QUEUED;
271 break;
272 case CMD_EAGAIN:
273 result = TRY_AGAIN_LATER;
274 break;
275 case CMD_RQLATER:
276 result = SUCCESSFULLY_QUEUED;
277 timeout(isp_command_requeue, xs, hz);
278 break;
279 case CMD_COMPLETE:
280 result = COMPLETE;
281 break;
282 }
283 (void) splx(s);
284 return (result);
285 }
286
287 switch (result) {
288 case CMD_QUEUED:
289 result = SUCCESSFULLY_QUEUED;
290 break;
291 case CMD_RQLATER:
292 case CMD_EAGAIN:
293 if (XS_NOERR(xs)) {
294 xs->error = XS_DRIVER_STUFFUP;
295 }
296 result = TRY_AGAIN_LATER;
297 break;
298 case CMD_COMPLETE:
299 result = COMPLETE;
300 break;
301
302 }
303
304 /*
305 * We can't use interrupts so poll on completion.
306 */
307 if (result == SUCCESSFULLY_QUEUED) {
308 if (isp_poll(isp, xs, xs->timeout)) {
309 /*
310 * If no other error occurred but we didn't finish,
311 * something bad happened.
312 */
313 if (XS_IS_CMD_DONE(xs) == 0) {
314 if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) {
315 isp_restart(isp);
316 }
317 if (XS_NOERR(xs)) {
318 XS_SETERR(xs, HBA_BOTCH);
319 }
320 }
321 }
322 result = COMPLETE;
323 }
324 (void) splx(s);
325 return (result);
326 }
327
328 static int
329 isp_poll(struct ispsoftc *isp, struct scsi_xfer *xs, int mswait)
330 {
331
332 while (mswait) {
333 /* Try the interrupt handling routine */
334 (void)isp_intr((void *)isp);
335
336 /* See if the xs is now done */
337 if (XS_IS_CMD_DONE(xs))
338 return (0);
339 SYS_DELAY(1000); /* wait one millisecond */
340 mswait--;
341 }
342 return (1);
343 }
344
345 static void
346 isp_watch(void *arg)
347 {
348 int i;
349 struct ispsoftc *isp = arg;
350 struct scsi_xfer *xs;
351 int s;
352
353 /*
354 * Look for completely dead commands (but not polled ones).
355 */
356 s = splbio();
357 for (i = 0; i < isp->isp_maxcmds; i++) {
358 if ((xs = (struct scsi_xfer *) isp->isp_xflist[i]) == NULL) {
359 continue;
360 }
361 if (xs->timeout == 0 || (xs->flags & SCSI_NOMASK)) {
362 continue;
363 }
364 xs->timeout -= (WATCH_INTERVAL * 1000);
365
366 /*
367 * Avoid later thinking that this
368 * transaction is not being timed.
369 * Then give ourselves to watchdog
370 * periods of grace.
371 */
372 if (xs->timeout == 0) {
373 xs->timeout = 1;
374 } else if (xs->timeout > -(2 * WATCH_INTERVAL * 1000)) {
375 continue;
376 }
377 if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) {
378 printf("%s: isp_watch failed to abort command\n",
379 isp->isp_name);
380 isp_restart(isp);
381 break;
382 }
383 }
384 timeout(isp_watch, isp, WATCH_INTERVAL * hz);
385 isp->isp_dogactive = 1;
386 splx(s);
387 }
388
389 /*
390 * Free any associated resources prior to decommissioning and
391 * set the card to a known state (so it doesn't wake up and kick
392 * us when we aren't expecting it to).
393 *
394 * Locks are held before coming here.
395 */
396 void
397 isp_uninit(isp)
398 struct ispsoftc *isp;
399 {
400 int s = splbio();
401 /*
402 * Leave with interrupts disabled.
403 */
404 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
405 DISABLE_INTS(isp);
406
407 /*
408 * Turn off the watchdog (if active).
409 */
410 if (isp->isp_dogactive) {
411 untimeout(isp_watch, isp);
412 isp->isp_dogactive = 0;
413 }
414 /*
415 * And out...
416 */
417 splx(s);
418 }
419
420 /*
421 * Restart function for a command to be requeued later.
422 */
423 static void
424 isp_command_requeue(void *arg)
425 {
426 struct scsi_xfer *xs = arg;
427 struct ispsoftc *isp = XS_ISP(xs);
428 int s = splbio();
429 switch (ispcmd_slow(xs)) {
430 case SUCCESSFULLY_QUEUED:
431 printf("%s: isp_command_reque: queued %d.%d\n",
432 isp->isp_name, XS_TGT(xs), XS_LUN(xs));
433 break;
434 case TRY_AGAIN_LATER:
435 printf("%s: EAGAIN for %d.%d\n",
436 isp->isp_name, XS_TGT(xs), XS_LUN(xs));
437 /* FALLTHROUGH */
438 case COMPLETE:
439 /* can only be an error */
440 if (XS_NOERR(xs))
441 XS_SETERR(xs, XS_DRIVER_STUFFUP);
442 XS_CMD_DONE(xs);
443 break;
444 }
445 (void) splx(s);
446 }
447
448 /*
449 * Restart function after a LOOP UP event (e.g.),
450 * done as a timeout for some hysteresis.
451 */
452 static void
453 isp_internal_restart(void *arg)
454 {
455 struct ispsoftc *isp = arg;
456 int result, nrestarted = 0, s;
457
458 s = splbio();
459 if (isp->isp_osinfo.blocked == 0) {
460 struct scsi_xfer *xs;
461 while ((xs = isp->isp_osinfo.wqf) != NULL) {
462 isp->isp_osinfo.wqf = xs->next;
463 xs->next = NULL;
464 DISABLE_INTS(isp);
465 result = ispscsicmd(xs);
466 ENABLE_INTS(isp);
467 if (result != CMD_QUEUED) {
468 printf("%s: botched command restart (0x%x)\n",
469 isp->isp_name, result);
470 if (XS_NOERR(xs))
471 XS_SETERR(xs, XS_DRIVER_STUFFUP);
472 XS_CMD_DONE(xs);
473 }
474 nrestarted++;
475 }
476 printf("%s: requeued %d commands\n", isp->isp_name, nrestarted);
477 }
478 (void) splx(s);
479 }
480
481 int
482 isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
483 {
484 int bus, tgt;
485 int s = splbio();
486 switch (cmd) {
487 case ISPASYNC_NEW_TGT_PARAMS:
488 if (IS_SCSI(isp) && isp->isp_dblev) {
489 sdparam *sdp = isp->isp_param;
490 char *wt;
491 int mhz, flags, period;
492
493 tgt = *((int *) arg);
494 bus = (tgt >> 16) & 0xffff;
495 tgt &= 0xffff;
496
497 flags = sdp->isp_devparam[tgt].cur_dflags;
498 period = sdp->isp_devparam[tgt].cur_period;
499 if ((flags & DPARM_SYNC) && period &&
500 (sdp->isp_devparam[tgt].cur_offset) != 0) {
501 if (sdp->isp_lvdmode) {
502 switch (period) {
503 case 0x9:
504 mhz = 80;
505 break;
506 case 0xa:
507 mhz = 40;
508 break;
509 case 0xb:
510 mhz = 33;
511 break;
512 case 0xc:
513 mhz = 25;
514 break;
515 default:
516 mhz = 1000 / (period * 4);
517 break;
518 }
519 } else {
520 mhz = 1000 / (period * 4);
521 }
522 } else {
523 mhz = 0;
524 }
525 switch (flags & (DPARM_WIDE|DPARM_TQING)) {
526 case DPARM_WIDE:
527 wt = ", 16 bit wide\n";
528 break;
529 case DPARM_TQING:
530 wt = ", Tagged Queueing Enabled\n";
531 break;
532 case DPARM_WIDE|DPARM_TQING:
533 wt = ", 16 bit wide, Tagged Queueing Enabled\n";
534 break;
535 default:
536 wt = "\n";
537 break;
538 }
539 if (mhz) {
540 printf("%s: Bus %d Target %d at %dMHz Max "
541 "Offset %d%s", isp->isp_name, bus, tgt, mhz,
542 sdp->isp_devparam[tgt].cur_offset, wt);
543 } else {
544 printf("%s: Bus %d Target %d Async Mode%s",
545 isp->isp_name, bus, tgt, wt);
546 }
547 break;
548 }
549 case ISPASYNC_BUS_RESET:
550 if (arg)
551 bus = *((int *) arg);
552 else
553 bus = 0;
554 printf("%s: SCSI bus %d reset detected\n", isp->isp_name, bus);
555 break;
556 case ISPASYNC_LOOP_DOWN:
557 /*
558 * Hopefully we get here in time to minimize the number
559 * of commands we are firing off that are sure to die.
560 */
561 isp->isp_osinfo.blocked = 1;
562 printf("%s: Loop DOWN\n", isp->isp_name);
563 break;
564 case ISPASYNC_LOOP_UP:
565 isp->isp_osinfo.blocked = 0;
566 timeout(isp_internal_restart, isp, 1);
567 printf("%s: Loop UP\n", isp->isp_name);
568 break;
569 case ISPASYNC_PDB_CHANGED:
570 if (IS_FC(isp) && isp->isp_dblev) {
571 const char *fmt = "%s: Target %d (Loop 0x%x) Port ID 0x%x "
572 "role %s %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x\n";
573 const static char *roles[4] = {
574 "No", "Target", "Initiator", "Target/Initiator"
575 };
576 char *ptr;
577 fcparam *fcp = isp->isp_param;
578 int tgt = *((int *) arg);
579 struct lportdb *lp = &fcp->portdb[tgt];
580
581 if (lp->valid) {
582 ptr = "arrived";
583 } else {
584 ptr = "disappeared";
585 }
586 printf(fmt, isp->isp_name, tgt, lp->loopid, lp->portid,
587 roles[lp->roles & 0x3], ptr,
588 (u_int32_t) (lp->port_wwn >> 32),
589 (u_int32_t) (lp->port_wwn & 0xffffffffLL),
590 (u_int32_t) (lp->node_wwn >> 32),
591 (u_int32_t) (lp->node_wwn & 0xffffffffLL));
592 break;
593 }
594 #ifdef ISP2100_FABRIC
595 case ISPASYNC_CHANGE_NOTIFY:
596 printf("%s: Name Server Database Changed\n", isp->isp_name);
597 break;
598 case ISPASYNC_FABRIC_DEV:
599 {
600 int target;
601 struct lportdb *lp;
602 sns_scrsp_t *resp = (sns_scrsp_t *) arg;
603 u_int32_t portid;
604 u_int64_t wwn;
605 fcparam *fcp = isp->isp_param;
606
607 portid =
608 (((u_int32_t) resp->snscb_port_id[0]) << 16) |
609 (((u_int32_t) resp->snscb_port_id[1]) << 8) |
610 (((u_int32_t) resp->snscb_port_id[2]));
611 wwn =
612 (((u_int64_t)resp->snscb_portname[0]) << 56) |
613 (((u_int64_t)resp->snscb_portname[1]) << 48) |
614 (((u_int64_t)resp->snscb_portname[2]) << 40) |
615 (((u_int64_t)resp->snscb_portname[3]) << 32) |
616 (((u_int64_t)resp->snscb_portname[4]) << 24) |
617 (((u_int64_t)resp->snscb_portname[5]) << 16) |
618 (((u_int64_t)resp->snscb_portname[6]) << 8) |
619 (((u_int64_t)resp->snscb_portname[7]));
620 printf("%s: Fabric Device (Type 0x%x)@PortID 0x%x WWN "
621 "0x%08x%08x\n", isp->isp_name, resp->snscb_port_type,
622 portid, ((u_int32_t)(wwn >> 32)),
623 ((u_int32_t)(wwn & 0xffffffff)));
624 if (resp->snscb_port_type != 2)
625 break;
626 for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
627 lp = &fcp->portdb[target];
628 if (lp->port_wwn == wwn)
629 break;
630 }
631 if (target < MAX_FC_TARG) {
632 break;
633 }
634 for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
635 lp = &fcp->portdb[target];
636 if (lp->port_wwn == 0)
637 break;
638 }
639 if (target == MAX_FC_TARG) {
640 printf("%s: no more space for fabric devices\n",
641 isp->isp_name);
642 return (-1);
643 }
644 lp->port_wwn = lp->node_wwn = wwn;
645 lp->portid = portid;
646 break;
647 }
648 #endif
649 default:
650 break;
651 }
652 (void) splx(s);
653 return (0);
654 }
Cache object: 1e6a79cb151478315638f9a235056751
|