isp_netbsd.c revision 1.18.2.5 1 /* $NetBSD: isp_netbsd.c,v 1.18.2.5 1999/10/26 23:10:16 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_xfer_mode *xm = arg;
301 u_int16_t flags;
302
303 sdp = &sdp[chan->chan_channel];
304
305 flags =
306 sdp->isp_devparam[xm->xm_target].dev_flags;
307 flags &= ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING);
308
309 if (xm->xm_mode & PERIPH_CAP_SYNC)
310 flags |= DPARM_SYNC;
311
312 if (xm->xm_mode & PERIPH_CAP_WIDE16)
313 flags |= DPARM_WIDE;
314
315 if (xm->xm_mode & PERIPH_CAP_TQING)
316 flags |= DPARM_TQING;
317
318 sdp->isp_devparam[xm->xm_target].dev_flags =
319 flags;
320 sdp->isp_devparam[xm->xm_target].dev_update = 1;
321 isp->isp_update |= (1 << chan->chan_channel);
322 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL);
323 }
324 return;
325 }
326 }
327
328 static int
329 isp_poll(isp, xs, mswait)
330 struct ispsoftc *isp;
331 ISP_SCSI_XFER_T *xs;
332 int mswait;
333 {
334
335 while (mswait) {
336 /* Try the interrupt handling routine */
337 (void)isp_intr((void *)isp);
338
339 /* See if the xs is now done */
340 if (XS_IS_CMD_DONE(xs)) {
341 return (0);
342 }
343 SYS_DELAY(1000); /* wait one millisecond */
344 mswait--;
345 }
346 return (1);
347 }
348
349 static void
350 isp_watch(arg)
351 void *arg;
352 {
353 int i;
354 struct ispsoftc *isp = arg;
355 struct scsipi_xfer *xs;
356 int s;
357
358 /*
359 * Look for completely dead commands (but not polled ones).
360 */
361 s = splbio();
362 for (i = 0; i < isp->isp_maxcmds; i++) {
363 xs = isp->isp_xflist[i];
364 if (xs == NULL) {
365 continue;
366 }
367 if (xs->timeout == 0 || (xs->xs_control & XS_CTL_POLL)) {
368 continue;
369 }
370 xs->timeout -= (WATCH_INTERVAL * 1000);
371 /*
372 * Avoid later thinking that this
373 * transaction is not being timed.
374 * Then give ourselves to watchdog
375 * periods of grace.
376 */
377 if (xs->timeout == 0) {
378 xs->timeout = 1;
379 } else if (xs->timeout > -(2 * WATCH_INTERVAL * 1000)) {
380 continue;
381 }
382 if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) {
383 printf("%s: isp_watch failed to abort command\n",
384 isp->isp_name);
385 isp_restart(isp);
386 break;
387 }
388 }
389 timeout(isp_watch, isp, WATCH_INTERVAL * hz);
390 isp->isp_dogactive = 1;
391 (void) splx(s);
392 }
393
394 /*
395 * Free any associated resources prior to decommissioning and
396 * set the card to a known state (so it doesn't wake up and kick
397 * us when we aren't expecting it to).
398 *
399 * Locks are held before coming here.
400 */
401 void
402 isp_uninit(isp)
403 struct ispsoftc *isp;
404 {
405 ISP_ILOCKVAL_DECL;
406 ISP_ILOCK(isp);
407 /*
408 * Leave with interrupts disabled.
409 */
410 DISABLE_INTS(isp);
411
412 /*
413 * Turn off the watchdog (if active).
414 */
415 if (isp->isp_dogactive) {
416 untimeout(isp_watch, isp);
417 isp->isp_dogactive = 0;
418 }
419
420 ISP_IUNLOCK(isp);
421 }
422
423 /*
424 * Restart function for a command to be requeued later.
425 */
426 static void
427 isp_command_requeue(arg)
428 void *arg;
429 {
430 struct scsipi_xfer *xs = arg;
431 int s;
432
433 s = splbio();
434 scsipi_adapter_request(xs->xs_periph->periph_channel,
435 ADAPTER_REQ_RUN_XFER, xs);
436 (void) splx(s);
437 }
438
439 int
440 isp_async(isp, cmd, arg)
441 struct ispsoftc *isp;
442 ispasync_t cmd;
443 void *arg;
444 {
445 int bus, tgt;
446 int s = splbio();
447 switch (cmd) {
448 case ISPASYNC_NEW_TGT_PARAMS:
449 if (isp->isp_type & ISP_HA_SCSI) {
450 struct scsipi_xfer_mode xm;
451 sdparam *sdp = isp->isp_param;
452 u_int16_t flags;
453
454 tgt = *((int *) arg);
455 bus = (tgt >> 16) & 0xffff;
456 tgt &= 0xffff;
457
458 sdp = &sdp[bus];
459
460 xm.xm_target = tgt;
461 xm.xm_mode = 0;
462 xm.xm_period = 0;
463 xm.xm_offset = 0;
464
465 flags = sdp->isp_devparam[tgt].cur_dflags;
466
467 if (flags & DPARM_SYNC) {
468 xm.xm_mode |= PERIPH_CAP_SYNC;
469 xm.xm_period = sdp->isp_devparam[tgt].cur_period;
470 xm.xm_offset = sdp->isp_devparam[tgt].cur_offset;
471 }
472 if (flags & DPARM_WIDE)
473 xm.xm_mode |= PERIPH_CAP_WIDE16;
474 if (flags & DPARM_TQING)
475 xm.xm_mode |= PERIPH_CAP_TQING;
476
477 scsipi_async_event(&isp->isp_osinfo._channels[bus],
478 ASYNC_EVENT_XFER_MODE, &xm);
479 break;
480 }
481 case ISPASYNC_BUS_RESET:
482 if (arg)
483 bus = *((int *) arg);
484 else
485 bus = 0;
486 printf("%s: SCSI bus %d reset detected\n", isp->isp_name, bus);
487 break;
488 case ISPASYNC_LOOP_DOWN:
489 /*
490 * Hopefully we get here in time to minimize the number
491 * of commands we are firing off that are sure to die.
492 *
493 * XXX Hard-code channel 0, but only one channel on FC
494 * XXX adapters, right?
495 */
496 scsipi_channel_freeze(&isp->isp_osinfo._channels[0], 1);
497 printf("%s: Loop DOWN\n", isp->isp_name);
498 break;
499 case ISPASYNC_LOOP_UP:
500 /*
501 * XXX Hard-code channel 0, but only one channel on FC
502 * XXX adapters, right?
503 */
504 timeout(scsipi_channel_timed_thaw,
505 &isp->isp_osinfo._channels[0], 1);
506 printf("%s: Loop UP\n", isp->isp_name);
507 break;
508 case ISPASYNC_PDB_CHANGED:
509 if (IS_FC(isp) && isp->isp_dblev) {
510 const char *fmt = "%s: Target %d (Loop 0x%x) Port ID 0x%x "
511 "role %s %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x\n";
512 const static char *roles[4] = {
513 "No", "Target", "Initiator", "Target/Initiator"
514 };
515 char *ptr;
516 fcparam *fcp = isp->isp_param;
517 int tgt = *((int *) arg);
518 struct lportdb *lp = &fcp->portdb[tgt];
519
520 if (lp->valid) {
521 ptr = "arrived";
522 } else {
523 ptr = "disappeared";
524 }
525 printf(fmt, isp->isp_name, tgt, lp->loopid, lp->portid,
526 roles[lp->roles & 0x3], ptr,
527 (u_int32_t) (lp->port_wwn >> 32),
528 (u_int32_t) (lp->port_wwn & 0xffffffffLL),
529 (u_int32_t) (lp->node_wwn >> 32),
530 (u_int32_t) (lp->node_wwn & 0xffffffffLL));
531 break;
532 }
533 #ifdef ISP2100_FABRIC
534 case ISPASYNC_CHANGE_NOTIFY:
535 printf("%s: Name Server Database Changed\n", isp->isp_name);
536 break;
537 case ISPASYNC_FABRIC_DEV:
538 {
539 int target;
540 struct lportdb *lp;
541 sns_scrsp_t *resp = (sns_scrsp_t *) arg;
542 u_int32_t portid;
543 u_int64_t wwn;
544 fcparam *fcp = isp->isp_param;
545
546 portid =
547 (((u_int32_t) resp->snscb_port_id[0]) << 16) |
548 (((u_int32_t) resp->snscb_port_id[1]) << 8) |
549 (((u_int32_t) resp->snscb_port_id[2]));
550 wwn =
551 (((u_int64_t)resp->snscb_portname[0]) << 56) |
552 (((u_int64_t)resp->snscb_portname[1]) << 48) |
553 (((u_int64_t)resp->snscb_portname[2]) << 40) |
554 (((u_int64_t)resp->snscb_portname[3]) << 32) |
555 (((u_int64_t)resp->snscb_portname[4]) << 24) |
556 (((u_int64_t)resp->snscb_portname[5]) << 16) |
557 (((u_int64_t)resp->snscb_portname[6]) << 8) |
558 (((u_int64_t)resp->snscb_portname[7]));
559 printf("%s: Fabric Device (Type 0x%x)@PortID 0x%x WWN "
560 "0x%08x%08x\n", isp->isp_name, resp->snscb_port_type,
561 portid, ((u_int32_t)(wwn >> 32)),
562 ((u_int32_t)(wwn & 0xffffffff)));
563 if (resp->snscb_port_type != 2)
564 break;
565 for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
566 lp = &fcp->portdb[target];
567 if (lp->port_wwn == wwn)
568 break;
569 }
570 if (target < MAX_FC_TARG) {
571 break;
572 }
573 for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
574 lp = &fcp->portdb[target];
575 if (lp->port_wwn == 0)
576 break;
577 }
578 if (target == MAX_FC_TARG) {
579 printf("%s: no more space for fabric devices\n",
580 isp->isp_name);
581 return (-1);
582 }
583 lp->port_wwn = lp->node_wwn = wwn;
584 lp->portid = portid;
585 break;
586 }
587 #endif
588 default:
589 break;
590 }
591 (void) splx(s);
592 return (0);
593 }
594