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