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