Home | History | Annotate | Line # | Download | only in ic
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