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