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