isp_netbsd.c revision 1.18.2.4 1 /* $NetBSD: isp_netbsd.c,v 1.18.2.4 1999/10/20 20:41:27 thorpej 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 static void ispminphys __P((struct buf *));
37 static void isp_scsipi_request __P((struct scsipi_channel *,
38 scsipi_adapter_req_t, void *));
39 static int
40 ispioctl __P((struct scsipi_channel *, u_long, caddr_t, int, struct proc *));
41
42 static int isp_poll __P((struct ispsoftc *, ISP_SCSI_XFER_T *, int));
43 static void isp_watch __P((void *));
44 static void isp_command_requeue __P((void *));
45
46 /*
47 * Complete attachment of hardware, include subdevices.
48 */
49 void
50 isp_attach(isp)
51 struct ispsoftc *isp;
52 {
53 struct scsipi_adapter *adapt = &isp->isp_osinfo._adapter;
54 struct scsipi_channel *chan;
55 int i;
56
57 isp->isp_state = ISP_RUNSTATE;
58
59 /*
60 * Fill in the scsipi_adapter.
61 */
62 adapt->adapt_dev = &isp->isp_osinfo._dev;
63 if (IS_FC(isp) == 0 && IS_12X0(isp) != 0)
64 adapt->adapt_nchannels = 2;
65 else
66 adapt->adapt_nchannels = 1;
67 adapt->adapt_openings = isp->isp_maxcmds;
68 adapt->adapt_max_periph = adapt->adapt_openings;
69 adapt->adapt_request = isp_scsipi_request;
70 adapt->adapt_minphys = ispminphys;
71 adapt->adapt_ioctl = ispioctl;
72
73 /*
74 * Fill in the scsipi_channel(s).
75 */
76 for (i = 0; i < adapt->adapt_nchannels; i++) {
77 chan = &isp->isp_osinfo._channels[i];
78 chan->chan_adapter = adapt;
79 chan->chan_bustype = &scsi_bustype;
80 chan->chan_channel = i;
81
82 if (IS_FC(isp)) {
83 fcparam *fcp = isp->isp_param;
84 fcp = &fcp[i];
85
86 /*
87 * Give it another chance here to come alive...
88 */
89 if (fcp->isp_fwstate != FW_READY) {
90 (void) isp_control(isp, ISPCTL_FCLINK_TEST,
91 NULL);
92 }
93 chan->chan_ntargets = MAX_FC_TARG;
94 #ifdef ISP2100_SCCLUN
95 /*
96 * 16 bits worth, but let's be reasonable..
97 */
98 chan->chan_nluns = 256;
99 #else
100 chan->chan_nluns = 16;
101 #endif
102 chan->chan_id = fcp->isp_loopid;
103 } else {
104 sdparam *sdp = isp->isp_param;
105 sdp = &sdp[i];
106
107 chan->chan_ntargets = MAX_TARGETS;
108 if (isp->isp_bustype == ISP_BT_SBUS)
109 chan->chan_nluns = 8;
110 else {
111 #if 0
112 /* Too many broken targets... */
113 if (isp->isp_fwrev >= ISP_FW_REV(7,55,0))
114 chan->chan_nluns = 32;
115 else
116 #endif
117 chan->chan_nluns = 7;
118 }
119 chan->chan_id = sdp->isp_initiator_id;
120 }
121 }
122
123 /*
124 * Send a SCSI Bus Reset (used to be done as part of attach,
125 * but now left to the OS outer layers).
126 */
127 if (IS_SCSI(isp)) {
128 for (i = 0; i < adapt->adapt_nchannels; i++)
129 (void) isp_control(isp, ISPCTL_RESET_BUS, &i);
130 SYS_DELAY(2*1000000);
131 }
132
133 /*
134 * Start the watchdog.
135 */
136 isp->isp_dogactive = 1;
137 timeout(isp_watch, isp, WATCH_INTERVAL * hz);
138
139 /*
140 * And attach children (if any).
141 */
142 for (i = 0; i < adapt->adapt_nchannels; i++)
143 (void) config_found((void *)isp, &isp->isp_osinfo._channels[i],
144 scsiprint);
145 }
146
147 /*
148 * minphys our xfers
149 *
150 * Unfortunately, the buffer pointer describes the target device- not the
151 * adapter device, so we can't use the pointer to find out what kind of
152 * adapter we are and adjust accordingly.
153 */
154
155 static void
156 ispminphys(bp)
157 struct buf *bp;
158 {
159 /*
160 * XX: Only the 1020 has a 24 bit limit.
161 */
162 if (bp->b_bcount >= (1 << 24)) {
163 bp->b_bcount = (1 << 24);
164 }
165 minphys(bp);
166 }
167
168 static int
169 ispioctl(chan, cmd, addr, flag, p)
170 struct scsipi_channel *chan;
171 u_long cmd;
172 caddr_t addr;
173 int flag;
174 struct proc *p;
175 {
176 struct ispsoftc *isp = (void *)chan->chan_adapter->adapt_dev;
177 int s, ch, retval = ENOTTY;
178
179 switch (cmd) {
180 case SCBUSIORESET:
181 ch = chan->chan_channel;
182 s = splbio();
183 if (isp_control(isp, ISPCTL_RESET_BUS, &ch))
184 retval = EIO;
185 else
186 retval = 0;
187 (void) splx(s);
188 break;
189 default:
190 break;
191 }
192 return (retval);
193 }
194
195 static void
196 isp_scsipi_request(chan, req, arg)
197 struct scsipi_channel *chan;
198 scsipi_adapter_req_t req;
199 void *arg;
200 {
201 struct scsipi_xfer *xs;
202 struct ispsoftc *isp = (void *)chan->chan_adapter->adapt_dev;
203 int result, s;
204
205 switch (req) {
206 case ADAPTER_REQ_RUN_XFER:
207 xs = arg;
208 s = splbio();
209 if (isp->isp_state < ISP_RUNSTATE) {
210 DISABLE_INTS(isp);
211 isp_init(isp);
212 if (isp->isp_state != ISP_INITSTATE) {
213 ENABLE_INTS(isp);
214 (void) splx(s);
215 XS_SETERR(xs, HBA_BOTCH);
216 XS_CMD_DONE(xs);
217 return;
218 }
219 isp->isp_state = ISP_RUNSTATE;
220 ENABLE_INTS(isp);
221 }
222
223 DISABLE_INTS(isp);
224 result = ispscsicmd(xs);
225 ENABLE_INTS(isp);
226
227 switch (result) {
228 case CMD_QUEUED:
229 /*
230 * If we're not polling for completion, just return.
231 */
232 if ((xs->xs_control & XS_CTL_POLL) == 0) {
233 (void) splx(s);
234 return;
235 }
236 break;
237
238 case CMD_EAGAIN:
239 /*
240 * Adapter resource shortage of some sort. Should
241 * retry later.
242 */
243 XS_SETERR(xs, XS_RESOURCE_SHORTAGE);
244 XS_CMD_DONE(xs);
245 (void) splx(s);
246 return;
247
248 case CMD_RQLATER:
249 /*
250 * XXX I think what we should do here is freeze
251 * XXX the channel queue, and do a timed thaw
252 * XXX of it. Need to add this to the mid-layer.
253 */
254 if ((xs->xs_control & XS_CTL_POLL) != 0) {
255 XS_SETERR(xs, XS_DRIVER_STUFFUP);
256 XS_CMD_DONE(xs);
257 } else
258 timeout(isp_command_requeue, xs, hz);
259 (void) splx(s);
260 return;
261
262 case CMD_COMPLETE:
263 /*
264 * Something went horribly wrong, xs->error is set,
265 * and we just need to finish it off.
266 */
267 XS_CMD_DONE(xs);
268 (void) splx(s);
269 return;
270 }
271
272 /*
273 * If we can't use interrupts, poll on completion.
274 */
275 if (isp_poll(isp, xs, XS_TIME(xs))) {
276 /*
277 * If no other error occurred but we didn't finish,
278 * something bad happened.
279 */
280 if (XS_IS_CMD_DONE(xs) == 0) {
281 if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) {
282 isp_restart(isp);
283 }
284 if (XS_NOERR(xs)) {
285 XS_SETERR(xs, HBA_BOTCH);
286 }
287 XS_CMD_DONE(xs);
288 }
289 }
290 (void) splx(s);
291 return;
292
293 case ADAPTER_REQ_GROW_RESOURCES:
294 /* XXX Not supported. */
295 return;
296
297 case ADAPTER_REQ_SET_XFER_MODE:
298 if (isp->isp_type & ISP_HA_SCSI) {
299 sdparam *sdp = isp->isp_param;
300 struct scsipi_periph *periph = arg;
301 u_int16_t flags;
302
303 sdp = &sdp[periph->periph_channel->chan_channel];
304
305 flags =
306 sdp->isp_devparam[periph->periph_target].dev_flags;
307 flags &= ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING);
308
309 if (periph->periph_cap & PERIPH_CAP_SYNC)
310 flags |= DPARM_SYNC;
311
312 if (periph->periph_cap & PERIPH_CAP_WIDE16)
313 flags |= DPARM_WIDE;
314
315 if (periph->periph_cap & PERIPH_CAP_TQING)
316 flags |= DPARM_TQING;
317
318 sdp->isp_devparam[periph->periph_target].dev_flags =
319 flags;
320 sdp->isp_devparam[periph->periph_target].dev_update = 1;
321 isp->isp_update |=
322 (1 << periph->periph_channel->chan_channel);
323 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL);
324 }
325 return;
326
327 case ADAPTER_REQ_GET_XFER_MODE:
328 if (isp->isp_type & ISP_HA_SCSI) {
329 sdparam *sdp = isp->isp_param;
330 struct scsipi_periph *periph = arg;
331 u_int16_t flags;
332
333 sdp = &sdp[periph->periph_channel->chan_channel];
334
335 periph->periph_mode = 0;
336 periph->periph_period = 0;
337 periph->periph_offset = 0;
338
339 flags =
340 sdp->isp_devparam[periph->periph_target].cur_dflags;
341
342 if (flags & DPARM_SYNC) {
343 periph->periph_mode |= PERIPH_CAP_SYNC;
344 periph->periph_period =
345 sdp->isp_devparam[periph->periph_target].cur_period;
346 periph->periph_offset =
347 sdp->isp_devparam[periph->periph_target].cur_offset;
348 }
349 if (flags & DPARM_WIDE)
350 periph->periph_mode |= PERIPH_CAP_WIDE16;
351 if (flags & DPARM_TQING)
352 periph->periph_mode |= PERIPH_CAP_TQING;
353
354 periph->periph_flags |= PERIPH_MODE_VALID;
355 }
356 return;
357 }
358 }
359
360 static int
361 isp_poll(isp, xs, mswait)
362 struct ispsoftc *isp;
363 ISP_SCSI_XFER_T *xs;
364 int mswait;
365 {
366
367 while (mswait) {
368 /* Try the interrupt handling routine */
369 (void)isp_intr((void *)isp);
370
371 /* See if the xs is now done */
372 if (XS_IS_CMD_DONE(xs)) {
373 return (0);
374 }
375 SYS_DELAY(1000); /* wait one millisecond */
376 mswait--;
377 }
378 return (1);
379 }
380
381 static void
382 isp_watch(arg)
383 void *arg;
384 {
385 int i;
386 struct ispsoftc *isp = arg;
387 struct scsipi_xfer *xs;
388 int s;
389
390 /*
391 * Look for completely dead commands (but not polled ones).
392 */
393 s = splbio();
394 for (i = 0; i < isp->isp_maxcmds; i++) {
395 xs = isp->isp_xflist[i];
396 if (xs == NULL) {
397 continue;
398 }
399 if (xs->timeout == 0 || (xs->xs_control & XS_CTL_POLL)) {
400 continue;
401 }
402 xs->timeout -= (WATCH_INTERVAL * 1000);
403 /*
404 * Avoid later thinking that this
405 * transaction is not being timed.
406 * Then give ourselves to watchdog
407 * periods of grace.
408 */
409 if (xs->timeout == 0) {
410 xs->timeout = 1;
411 } else if (xs->timeout > -(2 * WATCH_INTERVAL * 1000)) {
412 continue;
413 }
414 if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) {
415 printf("%s: isp_watch failed to abort command\n",
416 isp->isp_name);
417 isp_restart(isp);
418 break;
419 }
420 }
421 timeout(isp_watch, isp, WATCH_INTERVAL * hz);
422 isp->isp_dogactive = 1;
423 (void) splx(s);
424 }
425
426 /*
427 * Free any associated resources prior to decommissioning and
428 * set the card to a known state (so it doesn't wake up and kick
429 * us when we aren't expecting it to).
430 *
431 * Locks are held before coming here.
432 */
433 void
434 isp_uninit(isp)
435 struct ispsoftc *isp;
436 {
437 ISP_ILOCKVAL_DECL;
438 ISP_ILOCK(isp);
439 /*
440 * Leave with interrupts disabled.
441 */
442 DISABLE_INTS(isp);
443
444 /*
445 * Turn off the watchdog (if active).
446 */
447 if (isp->isp_dogactive) {
448 untimeout(isp_watch, isp);
449 isp->isp_dogactive = 0;
450 }
451
452 ISP_IUNLOCK(isp);
453 }
454
455 /*
456 * Restart function for a command to be requeued later.
457 */
458 static void
459 isp_command_requeue(arg)
460 void *arg;
461 {
462 struct scsipi_xfer *xs = arg;
463 int s;
464
465 s = splbio();
466 scsipi_adapter_request(xs->xs_periph->periph_channel,
467 ADAPTER_REQ_RUN_XFER, xs);
468 (void) splx(s);
469 }
470
471 int
472 isp_async(isp, cmd, arg)
473 struct ispsoftc *isp;
474 ispasync_t cmd;
475 void *arg;
476 {
477 int bus, tgt;
478 int s = splbio();
479 switch (cmd) {
480 case ISPASYNC_NEW_TGT_PARAMS: {
481 struct scsipi_xfer_mode xm;
482
483 tgt = *((int *) arg);
484 bus = (tgt >> 16) & 0xffff;
485 tgt &= 0xffff;
486
487 xm.xm_target = tgt;
488 scsipi_async_event(&isp->isp_osinfo._channels[bus],
489 ASYNC_EVENT_XFER_MODE, &xm);
490 break;
491 }
492 case ISPASYNC_BUS_RESET:
493 if (arg)
494 bus = *((int *) arg);
495 else
496 bus = 0;
497 printf("%s: SCSI bus %d reset detected\n", isp->isp_name, bus);
498 break;
499 case ISPASYNC_LOOP_DOWN:
500 /*
501 * Hopefully we get here in time to minimize the number
502 * of commands we are firing off that are sure to die.
503 *
504 * XXX Hard-code channel 0, but only one channel on FC
505 * XXX adapters, right?
506 */
507 scsipi_channel_freeze(&isp->isp_osinfo._channels[0], 1);
508 printf("%s: Loop DOWN\n", isp->isp_name);
509 break;
510 case ISPASYNC_LOOP_UP:
511 /*
512 * XXX Hard-code channel 0, but only one channel on FC
513 * XXX adapters, right?
514 */
515 timeout(scsipi_channel_timed_thaw,
516 &isp->isp_osinfo._channels[0], 1);
517 printf("%s: Loop UP\n", isp->isp_name);
518 break;
519 case ISPASYNC_PDB_CHANGED:
520 if (IS_FC(isp) && isp->isp_dblev) {
521 const char *fmt = "%s: Target %d (Loop 0x%x) Port ID 0x%x "
522 "role %s %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x\n";
523 const static char *roles[4] = {
524 "No", "Target", "Initiator", "Target/Initiator"
525 };
526 char *ptr;
527 fcparam *fcp = isp->isp_param;
528 int tgt = *((int *) arg);
529 struct lportdb *lp = &fcp->portdb[tgt];
530
531 if (lp->valid) {
532 ptr = "arrived";
533 } else {
534 ptr = "disappeared";
535 }
536 printf(fmt, isp->isp_name, tgt, lp->loopid, lp->portid,
537 roles[lp->roles & 0x3], ptr,
538 (u_int32_t) (lp->port_wwn >> 32),
539 (u_int32_t) (lp->port_wwn & 0xffffffffLL),
540 (u_int32_t) (lp->node_wwn >> 32),
541 (u_int32_t) (lp->node_wwn & 0xffffffffLL));
542 break;
543 }
544 #ifdef ISP2100_FABRIC
545 case ISPASYNC_CHANGE_NOTIFY:
546 printf("%s: Name Server Database Changed\n", isp->isp_name);
547 break;
548 case ISPASYNC_FABRIC_DEV:
549 {
550 int target;
551 struct lportdb *lp;
552 sns_scrsp_t *resp = (sns_scrsp_t *) arg;
553 u_int32_t portid;
554 u_int64_t wwn;
555 fcparam *fcp = isp->isp_param;
556
557 portid =
558 (((u_int32_t) resp->snscb_port_id[0]) << 16) |
559 (((u_int32_t) resp->snscb_port_id[1]) << 8) |
560 (((u_int32_t) resp->snscb_port_id[2]));
561 wwn =
562 (((u_int64_t)resp->snscb_portname[0]) << 56) |
563 (((u_int64_t)resp->snscb_portname[1]) << 48) |
564 (((u_int64_t)resp->snscb_portname[2]) << 40) |
565 (((u_int64_t)resp->snscb_portname[3]) << 32) |
566 (((u_int64_t)resp->snscb_portname[4]) << 24) |
567 (((u_int64_t)resp->snscb_portname[5]) << 16) |
568 (((u_int64_t)resp->snscb_portname[6]) << 8) |
569 (((u_int64_t)resp->snscb_portname[7]));
570 printf("%s: Fabric Device (Type 0x%x)@PortID 0x%x WWN "
571 "0x%08x%08x\n", isp->isp_name, resp->snscb_port_type,
572 portid, ((u_int32_t)(wwn >> 32)),
573 ((u_int32_t)(wwn & 0xffffffff)));
574 if (resp->snscb_port_type != 2)
575 break;
576 for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
577 lp = &fcp->portdb[target];
578 if (lp->port_wwn == wwn)
579 break;
580 }
581 if (target < MAX_FC_TARG) {
582 break;
583 }
584 for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
585 lp = &fcp->portdb[target];
586 if (lp->port_wwn == 0)
587 break;
588 }
589 if (target == MAX_FC_TARG) {
590 printf("%s: no more space for fabric devices\n",
591 isp->isp_name);
592 return (-1);
593 }
594 lp->port_wwn = lp->node_wwn = wwn;
595 lp->portid = portid;
596 break;
597 }
598 #endif
599 default:
600 break;
601 }
602 (void) splx(s);
603 return (0);
604 }
605