isp.c revision 1.8 1 /* $NetBSD: isp.c,v 1.8 1997/06/22 19:57:06 mjacob Exp $ */
2
3 /*
4 * Machine Independent (well, as best as possible)
5 * code for the Qlogic ISP SCSI adapters.
6 *
7 * Specific probe attach and support routines for Qlogic ISP SCSI adapters.
8 *
9 * Copyright (c) 1997 by Matthew Jacob
10 * NASA AMES Research Center.
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice immediately at the beginning of the file, without modification,
18 * this list of conditions, and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * 3. The name of the author may not be used to endorse or promote products
23 * derived from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
29 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37
38 /*
39 * Inspiration and ideas about this driver are from Erik Moe's Linux driver
40 * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c)
41 */
42
43 #include <sys/types.h>
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/errno.h>
48 #include <sys/ioctl.h>
49 #include <sys/device.h>
50 #include <sys/malloc.h>
51 #include <sys/buf.h>
52 #include <sys/proc.h>
53 #include <sys/user.h>
54
55
56 #include <scsi/scsi_all.h>
57 #include <scsi/scsiconf.h>
58
59 #include <scsi/scsi_message.h>
60 #include <scsi/scsi_debug.h>
61 #include <scsi/scsiconf.h>
62
63 #include <vm/vm.h>
64 #include <vm/vm_param.h>
65 #include <vm/pmap.h>
66
67 #include <dev/ic/ispreg.h>
68 #include <dev/ic/ispvar.h>
69 #include <dev/ic/ispmbox.h>
70
71 #define MBOX_DELAY_COUNT 1000000 / 100
72
73 struct cfdriver isp_cd = {
74 NULL, "isp", DV_DULL
75 };
76
77 static void ispminphys __P((struct buf *));
78 static int32_t ispscsicmd __P((struct scsi_xfer *xs));
79 static int isp_mboxcmd __P((struct ispsoftc *, mbreg_t *));
80
81 static struct scsi_adapter isp_switch = {
82 ispscsicmd, ispminphys, 0, 0
83 };
84
85 static struct scsi_device isp_dev = { NULL, NULL, NULL, NULL };
86
87 static int isp_poll __P((struct ispsoftc *, struct scsi_xfer *, int));
88 static int isp_parse_status __P((struct ispsoftc *, ispstatusreq_t *));
89 static void isp_lostcmd __P((struct ispsoftc *, struct scsi_xfer *));
90
91 /*
92 * Reset Hardware.
93 *
94 * Only looks at sc_dev.dv_xname, sc_iot and sc_ioh fields.
95 */
96 void
97 isp_reset(isp)
98 struct ispsoftc *isp;
99 {
100 mbreg_t mbs;
101 int loops, i;
102 u_int8_t clock;
103
104 isp->isp_state = ISP_NILSTATE;
105 /*
106 * Do MD specific pre initialization
107 */
108 ISP_RESET0(isp);
109
110 /*
111 * Try and get old clock rate out before we hit the
112 * chip over the head- but if and only if we don't
113 * know our desired clock rate.
114 */
115 clock = isp->isp_mdvec->dv_clock;
116 if (clock == 0) {
117 mbs.param[0] = MBOX_GET_CLOCK_RATE;
118 (void) isp_mboxcmd(isp, &mbs);
119 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
120 clock = mbs.param[1];
121 printf("%s: using board clock 0x%x\n",
122 isp->isp_name, clock);
123 } else {
124 clock = 0;
125 }
126 }
127
128 /*
129 * Hit the chip over the head with hammer.
130 */
131
132 ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
133 /*
134 * Give the ISP a chance to recover...
135 */
136 delay(100);
137
138 /*
139 * Clear data && control DMA engines.
140 */
141 ISP_WRITE(isp, CDMA_CONTROL,
142 DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
143 ISP_WRITE(isp, DDMA_CONTROL,
144 DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
145 /*
146 * Wait for ISP to be ready to go...
147 */
148 loops = MBOX_DELAY_COUNT;
149 while ((ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET) != 0) {
150 delay(100);
151 if (--loops < 0) {
152 printf("%s: chip reset timed out\n", isp->isp_name);
153 return;
154 }
155 }
156 /*
157 * More initialization
158 */
159
160 ISP_WRITE(isp, BIU_CONF1, 0);
161 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
162 delay(100);
163
164 if (isp->isp_mdvec->dv_conf1) {
165 ISP_SETBITS(isp, BIU_CONF1, isp->isp_mdvec->dv_conf1);
166 if (isp->isp_mdvec->dv_conf1 & BIU_BURST_ENABLE) {
167 ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
168 ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
169 }
170 } else {
171 ISP_WRITE(isp, BIU_CONF1, 0);
172 }
173
174 #if 0
175 ISP_WRITE(isp, RISC_MTR, 0x1212); /* FM */
176 #endif
177 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); /* release paused processor */
178
179 /*
180 * Do MD specific post initialization
181 */
182 ISP_RESET1(isp);
183
184 /*
185 * Enable interrupts
186 */
187 ISP_WRITE(isp, BIU_ICR,
188 BIU_ICR_ENABLE_RISC_INT | BIU_ICR_ENABLE_ALL_INTS);
189
190 /*
191 * Do some sanity checking.
192 */
193
194 mbs.param[0] = MBOX_NO_OP;
195 (void) isp_mboxcmd(isp, &mbs);
196 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
197 printf("%s: NOP test failed\n", isp->isp_name);
198 return;
199 }
200
201 mbs.param[0] = MBOX_MAILBOX_REG_TEST;
202 mbs.param[1] = 0xdead;
203 mbs.param[2] = 0xbeef;
204 mbs.param[3] = 0xffff;
205 mbs.param[4] = 0x1111;
206 mbs.param[5] = 0xa5a5;
207 (void) isp_mboxcmd(isp, &mbs);
208 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
209 printf("%s: Mailbox Register test didn't complete\n",
210 isp->isp_name);
211 return;
212 }
213 i = 0;
214 if (mbs.param[1] != 0xdead) {
215 printf("%s: Register Test Failed @reg %d (got %x)\n",
216 isp->isp_name, 1, mbs.param[1]);
217 i++;
218 }
219 if (mbs.param[2] != 0xbeef) {
220 printf("%s: Register Test Failed @reg %d (got %x)\n",
221 isp->isp_name, 2, mbs.param[2]);
222 i++;
223 }
224 if (mbs.param[3] != 0xffff) {
225 printf("%s: Register Test Failed @reg %d (got %x)\n",
226 isp->isp_name, 3, mbs.param[3]);
227 i++;
228 }
229 if (mbs.param[4] != 0x1111) {
230 printf("%s: Register Test Failed @reg %d (got %x)\n",
231 isp->isp_name, 4, mbs.param[4]);
232 i++;
233 }
234 if (mbs.param[5] != 0xa5a5) {
235 printf("%s: Register Test Failed @reg %d (got %x)\n",
236 isp->isp_name, 5, mbs.param[5]);
237 i++;
238 }
239 if (i) {
240 return;
241 }
242
243 /*
244 * Download new Firmware
245 */
246 for (i = 0; i < isp->isp_mdvec->dv_fwlen; i++) {
247 mbs.param[0] = MBOX_WRITE_RAM_WORD;
248 mbs.param[1] = isp->isp_mdvec->dv_codeorg + i;
249 mbs.param[2] = isp->isp_mdvec->dv_ispfw[i];
250 (void) isp_mboxcmd(isp, &mbs);
251 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
252 printf("%s: f/w download failed\n", isp->isp_name);
253 return;
254 }
255 }
256
257 /*
258 * Verify that it downloaded correctly.
259 */
260 mbs.param[0] = MBOX_VERIFY_CHECKSUM;
261 mbs.param[1] = isp->isp_mdvec->dv_codeorg;
262 (void) isp_mboxcmd(isp, &mbs);
263 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
264 printf("%s: ram checksum failure\n", isp->isp_name);
265 return;
266 }
267
268 /*
269 * Now start it rolling...
270 */
271
272 mbs.param[0] = MBOX_EXEC_FIRMWARE;
273 mbs.param[1] = isp->isp_mdvec->dv_codeorg;
274 (void) isp_mboxcmd(isp, &mbs);
275
276 /*
277 * Set CLOCK RATE
278 */
279 if (clock) {
280 mbs.param[0] = MBOX_SET_CLOCK_RATE;
281 mbs.param[1] = clock;
282 (void) isp_mboxcmd(isp, &mbs);
283 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
284 printf("%s: failed to set CLOCKRATE\n", isp->isp_name);
285 return;
286 }
287 }
288 mbs.param[0] = MBOX_ABOUT_FIRMWARE;
289 (void) isp_mboxcmd(isp, &mbs);
290 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
291 printf("%s: ABOUT FIRMWARE command failed\n", isp->isp_name);
292 return;
293 }
294 printf("%s: F/W Revision %d.%d\n", isp->isp_name,
295 mbs.param[1], mbs.param[2]);
296 isp->isp_state = ISP_RESETSTATE;
297 }
298
299 /*
300 * Initialize Hardware to known state
301 */
302 void
303 isp_init(isp)
304 struct ispsoftc *isp;
305 {
306 mbreg_t mbs;
307 int s, i, l;
308
309 /*
310 * Set Default Host Adapter Parameters
311 * XXX: Should try and get them out of NVRAM
312 */
313
314 isp->isp_adapter_enabled = 1;
315 isp->isp_req_ack_active_neg = 1;
316 isp->isp_data_line_active_neg = 1;
317 isp->isp_cmd_dma_burst_enable = 1;
318 isp->isp_data_dma_burst_enabl = 1;
319 isp->isp_fifo_threshold = 2;
320 isp->isp_initiator_id = 7;
321 isp->isp_async_data_setup = 6;
322 isp->isp_selection_timeout = 250;
323 isp->isp_max_queue_depth = 256;
324 isp->isp_tag_aging = 8;
325 isp->isp_bus_reset_delay = 3;
326 isp->isp_retry_count = 0;
327 isp->isp_retry_delay = 1;
328 for (i = 0; i < MAX_TARGETS; i++) {
329 isp->isp_devparam[i].dev_flags = DPARM_DEFAULT;
330 isp->isp_devparam[i].exc_throttle = 16;
331 isp->isp_devparam[i].sync_period = 25;
332 isp->isp_devparam[i].sync_offset = 12;
333 isp->isp_devparam[i].dev_enable = 1;
334 }
335
336
337 s = splbio();
338
339 mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
340 mbs.param[1] = isp->isp_initiator_id;
341 (void) isp_mboxcmd(isp, &mbs);
342 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
343 (void) splx(s);
344 printf("%s: failed to set initiator id\n", isp->isp_name);
345 return;
346 }
347
348 mbs.param[0] = MBOX_SET_RETRY_COUNT;
349 mbs.param[1] = isp->isp_retry_count;
350 mbs.param[2] = isp->isp_retry_delay;
351 (void) isp_mboxcmd(isp, &mbs);
352 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
353 (void) splx(s);
354 printf("%s: failed to set retry count and delay\n",
355 isp->isp_name);
356 return;
357 }
358
359 mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
360 mbs.param[1] = isp->isp_async_data_setup;
361 (void) isp_mboxcmd(isp, &mbs);
362 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
363 (void) splx(s);
364 printf("%s: failed to set async data setup time\n",
365 isp->isp_name);
366 return;
367 }
368
369 mbs.param[0] = MBOX_SET_ACTIVE_NEG_STATE;
370 mbs.param[1] =
371 (isp->isp_req_ack_active_neg << 4) |
372 (isp->isp_data_line_active_neg << 5);
373 (void) isp_mboxcmd(isp, &mbs);
374 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
375 (void) splx(s);
376 printf("%s: failed to set active negation state\n",
377 isp->isp_name);
378 return;
379 }
380
381
382 mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT;
383 mbs.param[1] = isp->isp_tag_aging;
384 (void) isp_mboxcmd(isp, &mbs);
385 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
386 (void) splx(s);
387 printf("%s: failed to set tag age limit\n", isp->isp_name);
388 return;
389 }
390
391 mbs.param[0] = MBOX_SET_SELECT_TIMEOUT;
392 mbs.param[1] = isp->isp_selection_timeout;
393 (void) isp_mboxcmd(isp, &mbs);
394 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
395 (void) splx(s);
396 printf("%s: failed to set selection timeout\n", isp->isp_name);
397 return;
398 }
399
400 for (i = 0; i < MAX_TARGETS; i++) {
401 if (isp->isp_devparam[i].dev_enable == 0)
402 continue;
403
404 mbs.param[0] = MBOX_SET_TARGET_PARAMS;
405 mbs.param[1] = i << 8;
406 mbs.param[2] = isp->isp_devparam[i].dev_flags << 8;
407 mbs.param[3] =
408 (isp->isp_devparam[i].sync_offset << 8) |
409 (isp->isp_devparam[i].sync_period);
410 (void) isp_mboxcmd(isp, &mbs);
411 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
412 (void) splx(s);
413 printf("%s: failed to set target parameters\n",
414 isp->isp_name);
415 return;
416 }
417
418 for (l = 0; l < MAX_LUNS; l++) {
419 mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
420 mbs.param[1] = (i << 8) | l;
421 mbs.param[2] = isp->isp_max_queue_depth;
422 mbs.param[3] = isp->isp_devparam[i].exc_throttle;
423 (void) isp_mboxcmd(isp, &mbs);
424 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
425 (void) splx(s);
426 printf("%s: failed to set device queue "
427 "parameters\n", isp->isp_name);
428 return;
429 }
430 }
431 }
432
433
434 /*
435 * Set up DMA for the request and result mailboxes.
436 */
437 if (ISP_MBOXDMASETUP(isp)) {
438 (void) splx(s);
439 printf("%s: can't setup DMA for mailboxes\n", isp->isp_name);
440 return;
441 }
442
443 mbs.param[0] = MBOX_INIT_RES_QUEUE;
444 mbs.param[1] = RESULT_QUEUE_LEN;
445 mbs.param[2] = (u_int16_t) (isp->isp_result_dma >> 16);
446 mbs.param[3] = (u_int16_t) (isp->isp_result_dma & 0xffff);
447 mbs.param[4] = 0;
448 mbs.param[5] = 0;
449 (void) isp_mboxcmd(isp, &mbs);
450 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
451 (void) splx(s);
452 printf("%s: set of response queue failed\n", isp->isp_name);
453 return;
454 }
455 isp->isp_residx = 0;
456
457 mbs.param[0] = MBOX_INIT_REQ_QUEUE;
458 mbs.param[1] = RQUEST_QUEUE_LEN;
459 mbs.param[2] = (u_int16_t) (isp->isp_rquest_dma >> 16);
460 mbs.param[3] = (u_int16_t) (isp->isp_rquest_dma & 0xffff);
461 mbs.param[4] = 0;
462 (void) isp_mboxcmd(isp, &mbs);
463 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
464 (void) splx(s);
465 printf("%s: set of request queue failed\n", isp->isp_name);
466 return;
467 }
468 isp->isp_reqidx = 0;
469
470 /*
471 * Unfortunately, this is the only way right now for
472 * forcing a sync renegotiation. If we boot off of
473 * an Alpha, it's put the chip in SYNC mode, but we
474 * haven't necessarily set up the parameters the
475 * same, so we'll have to yank the reset line to
476 * get everyone to renegotiate.
477 */
478
479
480 mbs.param[0] = MBOX_BUS_RESET;
481 mbs.param[1] = 2;
482 (void) isp_mboxcmd(isp, &mbs);
483 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
484 (void) splx(s);
485 printf("%s: SCSI bus reset failed\n", isp->isp_name);
486 }
487 isp->isp_sendmarker = 1;
488 (void) splx(s);
489 isp->isp_state = ISP_INITSTATE;
490 }
491
492 /*
493 * Complete attachment of Hardware, include subdevices.
494 */
495 void
496 isp_attach(isp)
497 struct ispsoftc *isp;
498 {
499 isp->isp_state = ISP_RUNSTATE;
500 isp->isp_link.channel = SCSI_CHANNEL_ONLY_ONE;
501 isp->isp_link.adapter_softc = isp;
502 isp->isp_link.adapter_target = isp->isp_initiator_id;
503 isp->isp_link.adapter = &isp_switch;
504 isp->isp_link.device = &isp_dev;
505 isp->isp_link.openings = RQUEST_QUEUE_LEN / (MAX_TARGETS - 1);
506 isp->isp_link.max_target = MAX_TARGETS-1;
507 config_found((void *)isp, &isp->isp_link, scsiprint);
508 }
509
510
511 /*
512 * Free any associated resources prior to decommissioning.
513 */
514 void
515 isp_uninit(isp)
516 struct ispsoftc *isp;
517 {
518 }
519
520 /*
521 * minphys our xfers
522 */
523
524 static void
525 ispminphys(bp)
526 struct buf *bp;
527 {
528 /*
529 * XX: Only the 1020 has a 24 bit limit.
530 */
531 if (bp->b_bcount >= (1 << 24)) {
532 bp->b_bcount = (1 << 24) - 1;
533 }
534 minphys(bp);
535 }
536
537 /*
538 * start an xfer
539 */
540 static int32_t
541 ispscsicmd(xs)
542 struct scsi_xfer *xs;
543 {
544 struct ispsoftc *isp;
545 u_int8_t iptr, optr;
546 ispreq_t *req;
547 int s, i;
548
549 isp = xs->sc_link->adapter_softc;
550
551 optr = ISP_READ(isp, OUTMAILBOX4);
552 iptr = isp->isp_reqidx;
553
554 req = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, iptr);
555 iptr = (iptr + 1) & (RQUEST_QUEUE_LEN - 1);
556 if (iptr == optr) {
557 printf("%s: Request Queue Overflow\n", isp->isp_name);
558 xs->error = XS_DRIVER_STUFFUP;
559 return (TRY_AGAIN_LATER);
560 }
561
562 s = splbio();
563 if (isp->isp_sendmarker) {
564 ipsmarkreq_t *marker = (ipsmarkreq_t *) req;
565
566 bzero((void *) marker, sizeof (*marker));
567 marker->req_header.rqs_entry_count = 1;
568 marker->req_header.rqs_entry_type = RQSTYPE_MARKER;
569 marker->req_modifier = SYNC_ALL;
570
571 isp->isp_sendmarker = 0;
572
573 if (((iptr + 1) & (RQUEST_QUEUE_LEN - 1)) == optr) {
574 ISP_WRITE(isp, INMAILBOX4, iptr);
575 isp->isp_reqidx = iptr;
576 (void) splx(s);
577 printf("%s: Request Queue Overflow+\n", isp->isp_name);
578 xs->error = XS_DRIVER_STUFFUP;
579 return (TRY_AGAIN_LATER);
580 }
581 req = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, iptr);
582 iptr = (iptr + 1) & (RQUEST_QUEUE_LEN - 1);
583 }
584
585
586 bzero((void *) req, sizeof (*req));
587 req->req_header.rqs_entry_count = 1;
588 req->req_header.rqs_entry_type = RQSTYPE_REQUEST;
589 req->req_header.rqs_flags = 0;
590 req->req_header.rqs_seqno = isp->isp_seqno++;
591
592 for (i = 0; i < RQUEST_QUEUE_LEN; i++) {
593 if (isp->isp_xflist[i] == NULL)
594 break;
595 }
596 if (i == RQUEST_QUEUE_LEN) {
597 panic("%s: ran out of xflist pointers\n", isp->isp_name);
598 /* NOTREACHED */
599 } else {
600 isp->isp_xflist[i] = xs;
601 req->req_handle = i;
602 }
603
604 req->req_flags = 0;
605 req->req_lun_trn = xs->sc_link->lun;
606 req->req_target = xs->sc_link->target;
607 req->req_cdblen = xs->cmdlen;
608 bcopy((void *)xs->cmd, req->req_cdb, xs->cmdlen);
609
610 #if 0
611 printf("%s(%d.%d): START%d cmd 0x%x datalen %d\n", isp->isp_name,
612 xs->sc_link->target, xs->sc_link->lun,
613 req->req_header.rqs_seqno, *(u_char *) xs->cmd, xs->datalen);
614 #endif
615
616 req->req_time = xs->timeout / 1000;
617 req->req_seg_count = 0;
618 if (ISP_DMASETUP(isp, xs, req, &iptr, optr)) {
619 (void) splx(s);
620 xs->error = XS_DRIVER_STUFFUP;
621 return (COMPLETE);
622 }
623 xs->error = 0;
624 ISP_WRITE(isp, INMAILBOX4, iptr);
625 isp->isp_reqidx = iptr;
626 (void) splx(s);
627 if ((xs->flags & SCSI_POLL) == 0) {
628 return (SUCCESSFULLY_QUEUED);
629 }
630
631 /*
632 * If we can't use interrupts, poll on completion.
633 */
634 if (isp_poll(isp, xs, xs->timeout)) {
635 #if 0
636 /* XXX try to abort it, or whatever */
637 if (isp_poll(isp, xs, xs->timeout) {
638 /* XXX really nuke it */
639 }
640 #endif
641 /*
642 * If no other error occurred but we didn't finish,
643 * something bad happened.
644 */
645 if ((xs->flags & ITSDONE) == 0 && xs->error == XS_NOERROR) {
646 isp_lostcmd(isp, xs);
647 xs->error = XS_DRIVER_STUFFUP;
648 }
649 }
650 return (COMPLETE);
651 }
652
653 /*
654 * Interrupt Service Routine(s)
655 */
656
657 int
658 isp_poll(isp, xs, mswait)
659 struct ispsoftc *isp;
660 struct scsi_xfer *xs;
661 int mswait;
662 {
663
664 while (mswait) {
665 /* Try the interrupt handling routine */
666 (void)isp_intr((void *)isp);
667
668 /* See if the xs is now done */
669 if (xs->flags & ITSDONE)
670 return (0);
671 delay(1000); /* wait one millisecond */
672 mswait--;
673 }
674 return (1);
675 }
676
677 int
678 isp_intr(arg)
679 void *arg;
680 {
681 struct scsi_xfer *xs;
682 struct ispsoftc *isp = arg;
683 u_int16_t iptr, optr, isr;
684
685 isr = ISP_READ(isp, BIU_ISR);
686 if (isr == 0 || (isr & BIU_ISR_RISC_INT) == 0) {
687 #if 0
688 if (isr) {
689 printf("%s: isp_intr isr=%x\n", isp->isp_name, isr);
690 }
691 #endif
692 return (0);
693 }
694
695 optr = isp->isp_residx;
696 iptr = ISP_READ(isp, OUTMAILBOX5);
697 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
698 ISP_WRITE(isp, BIU_ICR,
699 BIU_ICR_ENABLE_RISC_INT | BIU_ICR_ENABLE_ALL_INTS);
700
701 if (ISP_READ(isp, BIU_SEMA) & 1) {
702 u_int16_t mbox0 = ISP_READ(isp, OUTMAILBOX0);
703 switch (mbox0) {
704 case ASYNC_BUS_RESET:
705 case ASYNC_TIMEOUT_RESET:
706 printf("%s: bus or timeout reset\n", isp->isp_name);
707 isp->isp_sendmarker = 1;
708 break;
709 default:
710 printf("%s: async %x\n", isp->isp_name, mbox0);
711 break;
712 }
713 ISP_WRITE(isp, BIU_SEMA, 0);
714 #if 0
715 } else {
716 if (optr == iptr) {
717 printf("why'd we interrupt? isr %x iptr %x optr %x\n",
718 isr, optr, iptr);
719 }
720 #endif
721 }
722
723 while (optr != iptr) {
724 ispstatusreq_t *sp;
725 int buddaboom = 0;
726
727 sp = (ispstatusreq_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
728
729 optr = (optr + 1) & (RESULT_QUEUE_LEN-1);
730 if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
731 printf("%s: not RESPONSE in RESPONSE Queue (0x%x)\n",
732 isp->isp_name, sp->req_header.rqs_entry_type);
733 if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) {
734 ISP_WRITE(isp, INMAILBOX5, optr);
735 continue;
736 }
737 buddaboom = 1;
738 }
739
740 if (sp->req_header.rqs_flags & 0xf) {
741 if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
742 ISP_WRITE(isp, INMAILBOX5, optr);
743 continue;
744 }
745 printf("%s: rqs_flags=%x\n", isp->isp_name,
746 sp->req_header.rqs_flags & 0xf);
747 }
748 if (sp->req_handle >= RQUEST_QUEUE_LEN) {
749 printf("%s: bad request handle %d\n", isp->isp_name,
750 sp->req_handle);
751 ISP_WRITE(isp, INMAILBOX5, optr);
752 continue;
753 }
754 xs = (struct scsi_xfer *) isp->isp_xflist[sp->req_handle];
755 if (xs == NULL) {
756 printf("%s: NULL xs in xflist\n", isp->isp_name);
757 ISP_WRITE(isp, INMAILBOX5, optr);
758 continue;
759 }
760 isp->isp_xflist[sp->req_handle] = NULL;
761 if (sp->req_status_flags & RQSTF_BUS_RESET) {
762 isp->isp_sendmarker = 1;
763 }
764 if (buddaboom) {
765 xs->error = XS_DRIVER_STUFFUP;
766 }
767 if (sp->req_state_flags & RQSF_GOT_SENSE) {
768 bcopy(sp->req_sense_data, &xs->sense,
769 sizeof (xs->sense));
770 xs->error = XS_SENSE;
771 }
772 xs->status = sp->req_scsi_status;
773 if (xs->error == 0 && xs->status == SCSI_BUSY)
774 xs->error = XS_BUSY;
775
776 if (sp->req_header.rqs_entry_type == RQSTYPE_RESPONSE) {
777 if (xs->error == 0)
778 xs->error = isp_parse_status(isp, sp);
779 } else {
780 printf("%s: unknown return %x\n", isp->isp_name,
781 sp->req_header.rqs_entry_type);
782 if (xs->error == 0)
783 xs->error = XS_DRIVER_STUFFUP;
784 }
785 xs->resid = sp->req_resid;
786 xs->flags |= ITSDONE;
787 if (xs->datalen) {
788 ISP_DMAFREE(isp, xs, sp->req_handle);
789 }
790 #if 0
791 printf("%s(%d.%d): FINISH%d cmd 0x%x resid %d STS %x",
792 isp->isp_name, xs->sc_link->target, xs->sc_link->lun,
793 sp->req_header.rqs_seqno, *(u_char *) xs->cmd,
794 xs->resid, xs->status);
795 if (sp->req_state_flags & RQSF_GOT_SENSE) {
796 printf(" Skey: %x", xs->sense.flags);
797 if (xs->error != XS_SENSE) {
798 printf(" BUT NOT SET");
799 }
800 }
801 printf(" xs->error %d\n", xs->error);
802 #endif
803 ISP_WRITE(isp, INMAILBOX5, optr);
804 scsi_done(xs);
805 }
806 isp->isp_residx = optr;
807 return (1);
808 }
809
810 /*
811 * Support routines.
812 */
813
814 static int
815 isp_parse_status(isp, sp)
816 struct ispsoftc *isp;
817 ispstatusreq_t *sp;
818 {
819 switch (sp->req_completion_status) {
820 case RQCS_COMPLETE:
821 return (XS_NOERROR);
822 break;
823 case RQCS_INCOMPLETE:
824 if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
825 return (XS_SELTIMEOUT);
826 }
827 printf("%s: incomplete, state %x\n",
828 isp->isp_name, sp->req_state_flags);
829 break;
830 case RQCS_DATA_UNDERRUN:
831 return (XS_NOERROR);
832 case RQCS_TIMEOUT:
833 return (XS_TIMEOUT);
834 case RQCS_RESET_OCCURRED:
835 printf("%s: reset occurred\n", isp->isp_name);
836 isp->isp_sendmarker = 1;
837 break;
838 case RQCS_ABORTED:
839 printf("%s: command aborted\n", isp->isp_name);
840 isp->isp_sendmarker = 1;
841 break;
842 default:
843 printf("%s: comp status %x\n", isp->isp_name,
844 sp->req_completion_status);
845 break;
846 }
847 return (XS_DRIVER_STUFFUP);
848 }
849
850 #define HINIB(x) ((x) >> 0x4)
851 #define LONIB(x) ((x) & 0xf)
852 #define MAKNIB(a, b) (((a) << 4) | (b))
853 static u_int8_t mbpcnt[] = {
854 MAKNIB(1, 1), /* MBOX_NO_OP */
855 MAKNIB(5, 5), /* MBOX_LOAD_RAM */
856 MAKNIB(2, 0), /* MBOX_EXEC_FIRMWARE */
857 MAKNIB(5, 5), /* MBOX_DUMP_RAM */
858 MAKNIB(3, 3), /* MBOX_WRITE_RAM_WORD */
859 MAKNIB(2, 3), /* MBOX_READ_RAM_WORD */
860 MAKNIB(6, 6), /* MBOX_MAILBOX_REG_TEST */
861 MAKNIB(2, 3), /* MBOX_VERIFY_CHECKSUM */
862 MAKNIB(1, 3), /* MBOX_ABOUT_FIRMWARE */
863 MAKNIB(0, 0), /* 0x0009 */
864 MAKNIB(0, 0), /* 0x000a */
865 MAKNIB(0, 0), /* 0x000b */
866 MAKNIB(0, 0), /* 0x000c */
867 MAKNIB(0, 0), /* 0x000d */
868 MAKNIB(1, 2), /* MBOX_CHECK_FIRMWARE */
869 MAKNIB(0, 0), /* 0x000f */
870 MAKNIB(5, 5), /* MBOX_INIT_REQ_QUEUE */
871 MAKNIB(6, 6), /* MBOX_INIT_RES_QUEUE */
872 MAKNIB(4, 4), /* MBOX_EXECUTE_IOCB */
873 MAKNIB(2, 2), /* MBOX_WAKE_UP */
874 MAKNIB(1, 6), /* MBOX_STOP_FIRMWARE */
875 MAKNIB(4, 4), /* MBOX_ABORT */
876 MAKNIB(2, 2), /* MBOX_ABORT_DEVICE */
877 MAKNIB(3, 3), /* MBOX_ABORT_TARGET */
878 MAKNIB(2, 2), /* MBOX_BUS_RESET */
879 MAKNIB(2, 3), /* MBOX_STOP_QUEUE */
880 MAKNIB(2, 3), /* MBOX_START_QUEUE */
881 MAKNIB(2, 3), /* MBOX_SINGLE_STEP_QUEUE */
882 MAKNIB(2, 3), /* MBOX_ABORT_QUEUE */
883 MAKNIB(2, 4), /* MBOX_GET_DEV_QUEUE_STATUS */
884 MAKNIB(0, 0), /* 0x001e */
885 MAKNIB(1, 3), /* MBOX_GET_FIRMWARE_STATUS */
886 MAKNIB(1, 2), /* MBOX_GET_INIT_SCSI_ID */
887 MAKNIB(1, 2), /* MBOX_GET_SELECT_TIMEOUT */
888 MAKNIB(1, 3), /* MBOX_GET_RETRY_COUNT */
889 MAKNIB(1, 2), /* MBOX_GET_TAG_AGE_LIMIT */
890 MAKNIB(1, 2), /* MBOX_GET_CLOCK_RATE */
891 MAKNIB(1, 2), /* MBOX_GET_ACT_NEG_STATE */
892 MAKNIB(1, 2), /* MBOX_GET_ASYNC_DATA_SETUP_TIME */
893 MAKNIB(1, 3), /* MBOX_GET_PCI_PARAMS */
894 MAKNIB(2, 4), /* MBOX_GET_TARGET_PARAMS */
895 MAKNIB(2, 4), /* MBOX_GET_DEV_QUEUE_PARAMS */
896 MAKNIB(0, 0), /* 0x002a */
897 MAKNIB(0, 0), /* 0x002b */
898 MAKNIB(0, 0), /* 0x002c */
899 MAKNIB(0, 0), /* 0x002d */
900 MAKNIB(0, 0), /* 0x002e */
901 MAKNIB(0, 0), /* 0x002f */
902 MAKNIB(2, 2), /* MBOX_SET_INIT_SCSI_ID */
903 MAKNIB(2, 2), /* MBOX_SET_SELECT_TIMEOUT */
904 MAKNIB(3, 3), /* MBOX_SET_RETRY_COUNT */
905 MAKNIB(2, 2), /* MBOX_SET_TAG_AGE_LIMIT */
906 MAKNIB(2, 2), /* MBOX_SET_CLOCK_RATE */
907 MAKNIB(2, 2), /* MBOX_SET_ACTIVE_NEG_STATE */
908 MAKNIB(2, 2), /* MBOX_SET_ASYNC_DATA_SETUP_TIME */
909 MAKNIB(3, 3), /* MBOX_SET_PCI_CONTROL_PARAMS */
910 MAKNIB(4, 4), /* MBOX_SET_TARGET_PARAMS */
911 MAKNIB(4, 4), /* MBOX_SET_DEV_QUEUE_PARAMS */
912 MAKNIB(0, 0), /* 0x003a */
913 MAKNIB(0, 0), /* 0x003b */
914 MAKNIB(0, 0), /* 0x003c */
915 MAKNIB(0, 0), /* 0x003d */
916 MAKNIB(0, 0), /* 0x003e */
917 MAKNIB(0, 0), /* 0x003f */
918 MAKNIB(1, 2), /* MBOX_RETURN_BIOS_BLOCK_ADDR */
919 MAKNIB(6, 1), /* MBOX_WRITE_FOUR_RAM_WORDS */
920 MAKNIB(2, 3) /* MBOX_EXEC_BIOS_IOCB */
921 };
922 #define NMBCOM (sizeof (mbpcnt) / sizeof (mbpcnt[0]))
923
924 static int
925 isp_mboxcmd(isp, mbp)
926 struct ispsoftc *isp;
927 mbreg_t *mbp;
928 {
929 int outparam, inparam;
930 int loops;
931
932 if (mbp->param[0] > NMBCOM) {
933 printf("%s: bad command %x\n", isp->isp_name, mbp->param[0]);
934 return (-1);
935 }
936
937 inparam = HINIB(mbpcnt[mbp->param[0]]);
938 outparam = LONIB(mbpcnt[mbp->param[0]]);
939 if (inparam == 0 && outparam == 0) {
940 printf("%s: no parameters for %x\n", isp->isp_name,
941 mbp->param[0]);
942 return (-1);
943 }
944
945 /*
946 * Make sure we can send some words..
947 */
948
949 loops = MBOX_DELAY_COUNT;
950 while ((ISP_READ(isp, HCCR) & HCCR_HOST_INT) != 0) {
951 delay(100);
952 if (--loops < 0) {
953 printf("%s: isp_mboxcmd timeout #1\n", isp->isp_name);
954 return (-1);
955 }
956 }
957
958 /*
959 * Write input parameters
960 */
961 switch (inparam) {
962 case 6: ISP_WRITE(isp, INMAILBOX5, mbp->param[5]); mbp->param[5] = 0;
963 case 5: ISP_WRITE(isp, INMAILBOX4, mbp->param[4]); mbp->param[4] = 0;
964 case 4: ISP_WRITE(isp, INMAILBOX3, mbp->param[3]); mbp->param[3] = 0;
965 case 3: ISP_WRITE(isp, INMAILBOX2, mbp->param[2]); mbp->param[2] = 0;
966 case 2: ISP_WRITE(isp, INMAILBOX1, mbp->param[1]); mbp->param[1] = 0;
967 case 1: ISP_WRITE(isp, INMAILBOX0, mbp->param[0]); mbp->param[0] = 0;
968 }
969
970 /*
971 * Clear semaphore on mailbox registers
972 */
973 ISP_WRITE(isp, BIU_SEMA, 0);
974
975 /*
976 * Clear RISC int condition.
977 */
978 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
979
980 /*
981 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
982 */
983 ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
984
985 /*
986 * Wait until RISC int is set
987 */
988 loops = MBOX_DELAY_COUNT;
989 while ((ISP_READ(isp, BIU_ISR) & BIU_ISR_RISC_INT) != 0) {
990 delay(100);
991 if (--loops < 0) {
992 printf("%s: isp_mboxcmd timeout #2\n", isp->isp_name);
993 return (-1);
994 }
995 }
996
997 /*
998 * Check to make sure that the semaphore has been set.
999 */
1000 loops = MBOX_DELAY_COUNT;
1001 while ((ISP_READ(isp, BIU_SEMA) & 1) == 0) {
1002 delay(100);
1003 if (--loops < 0) {
1004 printf("%s: isp_mboxcmd timeout #3\n", isp->isp_name);
1005 return (-1);
1006 }
1007 }
1008
1009 /*
1010 * Make sure that the MBOX_BUSY has gone away
1011 */
1012 loops = MBOX_DELAY_COUNT;
1013 while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
1014 delay(100);
1015 if (--loops < 0) {
1016 printf("%s: isp_mboxcmd timeout #4\n", isp->isp_name);
1017 return (-1);
1018 }
1019 }
1020
1021
1022 /*
1023 * Pick up output parameters.
1024 */
1025 switch (outparam) {
1026 case 6: mbp->param[5] = ISP_READ(isp, OUTMAILBOX5);
1027 case 5: mbp->param[4] = ISP_READ(isp, OUTMAILBOX4);
1028 case 4: mbp->param[3] = ISP_READ(isp, OUTMAILBOX3);
1029 case 3: mbp->param[2] = ISP_READ(isp, OUTMAILBOX2);
1030 case 2: mbp->param[1] = ISP_READ(isp, OUTMAILBOX1);
1031 case 1: mbp->param[0] = ISP_READ(isp, OUTMAILBOX0);
1032 }
1033
1034 /*
1035 * Clear RISC int.
1036 */
1037 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
1038
1039 /*
1040 * Release semaphore on mailbox registers
1041 */
1042 ISP_WRITE(isp, BIU_SEMA, 0);
1043 return (0);
1044 }
1045
1046 static void
1047 isp_lostcmd(struct ispsoftc *isp, struct scsi_xfer *xs)
1048 {
1049 mbreg_t mbs;
1050 mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
1051 (void) isp_mboxcmd(isp, &mbs);
1052
1053 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1054 printf("%s: couldn't GET FIRMWARE STATUS\n", isp->isp_name);
1055 return;
1056 }
1057 printf("%s: lost command, %d commands active of total %d\n",
1058 isp->isp_name, mbs.param[1], mbs.param[2]);
1059 if (xs == NULL || xs->sc_link == NULL)
1060 return;
1061
1062 mbs.param[0] = MBOX_GET_DEV_QUEUE_STATUS;
1063 mbs.param[1] = xs->sc_link->target << 8 | xs->sc_link->lun;
1064 (void) isp_mboxcmd(isp, &mbs);
1065 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1066 printf("%s: couldn't GET DEVICE STATUS\n", isp->isp_name);
1067 return;
1068 }
1069 printf("%s: lost command, target %d lun %d, State: %x\n",
1070 isp->isp_name, mbs.param[1] >> 8, mbs.param[1] & 0x7,
1071 mbs.param[2] & 0xff);
1072 }
1073