Home | History | Annotate | Line # | Download | only in ic
isp.c revision 1.6
      1 /*	$NetBSD: isp.c,v 1.6 1997/06/01 23:42:04 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 	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 	queue_addr =
    454 	    ISP_MBOXDMASETUP(isp, isp->isp_rquest, sizeof (isp->isp_rquest));
    455 	if (queue_addr == 0) {
    456 		(void) splx(s);
    457 		return;
    458 	}
    459 	mbs.param[0] = MBOX_INIT_REQ_QUEUE;
    460 	mbs.param[1] = RQUEST_QUEUE_LEN;
    461 	mbs.param[2] = (u_int16_t) (queue_addr >> 16);
    462 	mbs.param[3] = (u_int16_t) (queue_addr & 0xffff);
    463 	mbs.param[4] = 0;
    464 	(void) isp_mboxcmd(isp, &mbs);
    465 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
    466 		(void) splx(s);
    467 		printf("%s: set of request queue failed\n", isp->isp_name);
    468 		return;
    469 	}
    470 	isp->isp_reqidx = 0;
    471 
    472 	/*
    473 	 * Unfortunately, this is the only way right now for
    474 	 * forcing a sync renegotiation. If we boot off of
    475 	 * an Alpha, it's put the chip in SYNC mode, but we
    476 	 * haven't necessarily set up the parameters the
    477 	 * same, so we'll have to yank the reset line to
    478 	 * get everyone to renegotiate.
    479 	 */
    480 
    481 
    482 	mbs.param[0] = MBOX_BUS_RESET;
    483 	mbs.param[1] = 2;
    484 	(void) isp_mboxcmd(isp, &mbs);
    485 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
    486 		(void) splx(s);
    487 		printf("%s: SCSI bus reset failed\n", isp->isp_name);
    488 	}
    489 	isp->isp_sendmarker = 1;
    490 	(void) splx(s);
    491 	isp->isp_state = ISP_INITSTATE;
    492 }
    493 
    494 /*
    495  * Complete attachment of Hardware, include subdevices.
    496  */
    497 void
    498 isp_attach(isp)
    499 	struct ispsoftc *isp;
    500 {
    501 	isp->isp_state = ISP_RUNSTATE;
    502 	isp->isp_link.channel = SCSI_CHANNEL_ONLY_ONE;
    503 	isp->isp_link.adapter_softc = isp;
    504 	isp->isp_link.adapter_target = isp->isp_initiator_id;
    505 	isp->isp_link.adapter = &isp_switch;
    506 	isp->isp_link.device = &isp_dev;
    507 	isp->isp_link.openings = RQUEST_QUEUE_LEN / (MAX_TARGETS - 1);
    508 	isp->isp_link.max_target = MAX_TARGETS-1;
    509 	config_found((void *)isp, &isp->isp_link, scsiprint);
    510 }
    511 
    512 
    513 /*
    514  * Free any associated resources prior to decommissioning.
    515  */
    516 void
    517 isp_uninit(isp)
    518 	struct ispsoftc *isp;
    519 {
    520 }
    521 
    522 /*
    523  * minphys our xfers
    524  */
    525 
    526 static void
    527 ispminphys(bp)
    528 	struct buf *bp;
    529 {
    530 	/*
    531 	 * XX: Only the 1020 has a 24 bit limit.
    532 	 */
    533 	if (bp->b_bcount >= (1 << 24)) {
    534 		bp->b_bcount = (1 << 24) - 1;
    535 	}
    536 	minphys(bp);
    537 }
    538 
    539 /*
    540  * start an xfer
    541  */
    542 static int32_t
    543 ispscsicmd(xs)
    544 	struct scsi_xfer *xs;
    545 {
    546 	struct ispsoftc *isp;
    547 	u_int8_t iptr, optr;
    548 	ispreq_t *req;
    549 	int s, i;
    550 
    551 	isp = xs->sc_link->adapter_softc;
    552 
    553 	optr = ISP_READ(isp, OUTMAILBOX4);
    554 	iptr = isp->isp_reqidx;
    555 
    556 	req = (ispreq_t *) &isp->isp_rquest[iptr][0];
    557 	iptr = (iptr + 1) & (RQUEST_QUEUE_LEN - 1);
    558 	if (iptr == optr) {
    559 		printf("%s: Request Queue Overflow\n", isp->isp_name);
    560 		xs->error = XS_DRIVER_STUFFUP;
    561 		return (TRY_AGAIN_LATER);
    562 	}
    563 
    564 	s = splbio();
    565 	if (isp->isp_sendmarker) {
    566 		ipsmarkreq_t *marker = (ipsmarkreq_t *) req;
    567 
    568 		bzero((void *) marker, sizeof (*marker));
    569 		marker->req_header.rqs_entry_count = 1;
    570 		marker->req_header.rqs_entry_type = RQSTYPE_MARKER;
    571 		marker->req_modifier = SYNC_ALL;
    572 
    573 		isp->isp_sendmarker = 0;
    574 
    575 		if (((iptr + 1) & (RQUEST_QUEUE_LEN - 1)) == optr) {
    576 			ISP_WRITE(isp, INMAILBOX4, iptr);
    577 			isp->isp_reqidx = iptr;
    578 			(void) splx(s);
    579 			printf("%s: Request Queue Overflow+\n", isp->isp_name);
    580 			xs->error = XS_DRIVER_STUFFUP;
    581 			return (TRY_AGAIN_LATER);
    582 		}
    583 		req = (ispreq_t *) &isp->isp_rquest[iptr][0];
    584 		iptr = (iptr + 1) & (RQUEST_QUEUE_LEN - 1);
    585 	}
    586 
    587 
    588 	bzero((void *) req, sizeof (*req));
    589 	req->req_header.rqs_entry_count = 1;
    590 	req->req_header.rqs_entry_type = RQSTYPE_REQUEST;
    591 	req->req_header.rqs_flags = 0;
    592 	req->req_header.rqs_seqno = isp->isp_seqno++;
    593 
    594 	for (i = 0; i < RQUEST_QUEUE_LEN; i++) {
    595 		if (isp->isp_xflist[i] == NULL)
    596 			break;
    597 	}
    598 	if (i == RQUEST_QUEUE_LEN) {
    599 		panic("%s: ran out of xflist pointers\n", isp->isp_name);
    600 		/* NOTREACHED */
    601 	} else {
    602 		isp->isp_xflist[i] = xs;
    603 		req->req_handle = i;
    604 	}
    605 
    606 	req->req_flags = 0;
    607 	req->req_lun_trn = xs->sc_link->lun;
    608 	req->req_target = xs->sc_link->target;
    609 	req->req_cdblen = xs->cmdlen;
    610 	bcopy((void *)xs->cmd, req->req_cdb, xs->cmdlen);
    611 
    612 #if	0
    613 	printf("%s(%d.%d): START%d cmd 0x%x datalen %d\n", isp->isp_name,
    614 		xs->sc_link->target, xs->sc_link->lun,
    615 		req->req_header.rqs_seqno, *(u_char *) xs->cmd, xs->datalen);
    616 #endif
    617 
    618 	req->req_time = xs->timeout / 1000;
    619 	req->req_seg_count = 0;
    620 	if (ISP_DMASETUP(isp, xs, req, &iptr, optr)) {
    621 		(void) splx(s);
    622 		xs->error = XS_DRIVER_STUFFUP;
    623 		return (COMPLETE);
    624 	}
    625 	xs->error = 0;
    626 	ISP_WRITE(isp, INMAILBOX4, iptr);
    627 	isp->isp_reqidx = iptr;
    628 	(void) splx(s);
    629 	if ((xs->flags & SCSI_POLL) == 0) {
    630 		return (SUCCESSFULLY_QUEUED);
    631 	}
    632 
    633 	/*
    634 	 * If we can't use interrupts, poll on completion.
    635 	 */
    636 	if (isp_poll(isp, xs, xs->timeout)) {
    637 #if 0
    638 		/* XXX try to abort it, or whatever */
    639 		if (isp_poll(isp, xs, xs->timeout) {
    640 			/* XXX really nuke it */
    641 		}
    642 #endif
    643 		/*
    644 		 * If no other error occurred but we didn't finish,
    645 		 * something bad happened.
    646 		 */
    647 		if ((xs->flags & ITSDONE) == 0 && xs->error == XS_NOERROR) {
    648 			isp_lostcmd(isp, xs);
    649 			xs->error = XS_DRIVER_STUFFUP;
    650 		}
    651 	}
    652 	return (COMPLETE);
    653 }
    654 
    655 /*
    656  * Interrupt Service Routine(s)
    657  */
    658 
    659 int
    660 isp_poll(isp, xs, mswait)
    661 	struct ispsoftc *isp;
    662 	struct scsi_xfer *xs;
    663 	int mswait;
    664 {
    665 
    666 	while (mswait) {
    667 		/* Try the interrupt handling routine */
    668 		(void)isp_intr((void *)isp);
    669 
    670 		/* See if the xs is now done */
    671 		if (xs->flags & ITSDONE)
    672 			return (0);
    673 		delay(1000);		/* wait one millisecond */
    674 		mswait--;
    675 	}
    676 	return (1);
    677 }
    678 
    679 int
    680 isp_intr(arg)
    681 	void *arg;
    682 {
    683 	struct scsi_xfer *xs;
    684 	struct ispsoftc *isp = arg;
    685 	u_int16_t iptr, optr, isr;
    686 
    687 	isr = ISP_READ(isp, BIU_ISR);
    688 	if (isr == 0 || (isr & BIU_ISR_RISC_INT) == 0) {
    689 #if	0
    690 		if (isr) {
    691 			printf("%s: isp_intr isr=%x\n", isp->isp_name, isr);
    692 		}
    693 #endif
    694 		return (0);
    695 	}
    696 
    697 	optr = isp->isp_residx;
    698 	iptr = ISP_READ(isp, OUTMAILBOX5);
    699 	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
    700 	ISP_WRITE(isp, BIU_ICR,
    701 		  BIU_ICR_ENABLE_RISC_INT | BIU_ICR_ENABLE_ALL_INTS);
    702 
    703 	if (ISP_READ(isp, BIU_SEMA) & 1) {
    704 		u_int16_t mbox0 = ISP_READ(isp, OUTMAILBOX0);
    705 		switch (mbox0) {
    706 		case ASYNC_BUS_RESET:
    707 		case ASYNC_TIMEOUT_RESET:
    708 			printf("%s: bus or timeout reset\n", isp->isp_name);
    709 			isp->isp_sendmarker = 1;
    710 			break;
    711 		default:
    712 			printf("%s: async %x\n", isp->isp_name, mbox0);
    713 			break;
    714 		}
    715 		ISP_WRITE(isp, BIU_SEMA, 0);
    716 #if	0
    717 	} else {
    718 		if (optr == iptr) {
    719 			printf("why'd we interrupt? isr %x iptr %x optr %x\n",
    720 				isr, optr, iptr);
    721 		}
    722 #endif
    723 	}
    724 
    725 	while (optr != iptr) {
    726 		ispstatusreq_t *sp;
    727 		int buddaboom = 0;
    728 
    729 		sp = (ispstatusreq_t *) &isp->isp_result[optr][0];
    730 
    731 		optr = (optr + 1) & (RESULT_QUEUE_LEN-1);
    732 		if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
    733 			printf("%s: not RESPONSE in RESPONSE Queue (0x%x)\n",
    734 				isp->isp_name, sp->req_header.rqs_entry_type);
    735 			if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) {
    736 				ISP_WRITE(isp, INMAILBOX5, optr);
    737 				continue;
    738 			}
    739 			buddaboom = 1;
    740 		}
    741 
    742 		if (sp->req_header.rqs_flags & 0xf) {
    743 			if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
    744 				ISP_WRITE(isp, INMAILBOX5, optr);
    745 				continue;
    746 			}
    747 			printf("%s: rqs_flags=%x\n", isp->isp_name,
    748 				sp->req_header.rqs_flags & 0xf);
    749 		}
    750 		if (sp->req_handle >= RQUEST_QUEUE_LEN) {
    751 			printf("%s: bad request handle %d\n", isp->isp_name,
    752 				sp->req_handle);
    753 			ISP_WRITE(isp, INMAILBOX5, optr);
    754 			continue;
    755 		}
    756 		xs = (struct scsi_xfer *) isp->isp_xflist[sp->req_handle];
    757 		if (xs == NULL) {
    758 			printf("%s: NULL xs in xflist\n", isp->isp_name);
    759 			ISP_WRITE(isp, INMAILBOX5, optr);
    760 			continue;
    761 		}
    762 		isp->isp_xflist[sp->req_handle] = NULL;
    763 		if (sp->req_status_flags & RQSTF_BUS_RESET) {
    764 			isp->isp_sendmarker = 1;
    765 		}
    766 		if (buddaboom) {
    767 			xs->error = XS_DRIVER_STUFFUP;
    768 		}
    769 		if (sp->req_state_flags & RQSF_GOT_SENSE) {
    770 			bcopy(sp->req_sense_data, &xs->sense,
    771 				sizeof (xs->sense));
    772 			xs->error = XS_SENSE;
    773 		}
    774 		xs->status = sp->req_scsi_status;
    775 		if (xs->error == 0 && xs->status == SCSI_BUSY)
    776 			xs->error = XS_BUSY;
    777 
    778 		if (sp->req_header.rqs_entry_type == RQSTYPE_RESPONSE) {
    779 			if (xs->error == 0)
    780 				xs->error = isp_parse_status(isp, sp);
    781 		} else {
    782 			printf("%s: unknown return %x\n", isp->isp_name,
    783 				sp->req_header.rqs_entry_type);
    784 			if (xs->error == 0)
    785 				xs->error = XS_DRIVER_STUFFUP;
    786 		}
    787 		xs->resid = sp->req_resid;
    788 		xs->flags |= ITSDONE;
    789 		if (xs->datalen) {
    790 			ISP_DMAFREE(isp, xs, sp->req_handle);
    791 		}
    792 #if	0
    793 		printf("%s(%d.%d): FINISH%d cmd 0x%x resid %d STS %x",
    794 			isp->isp_name, xs->sc_link->target, xs->sc_link->lun,
    795 			sp->req_header.rqs_seqno, *(u_char *) xs->cmd,
    796 			xs->resid, xs->status);
    797 		if (sp->req_state_flags & RQSF_GOT_SENSE) {
    798 			printf(" Skey: %x", xs->sense.flags);
    799 			if (xs->error != XS_SENSE) {
    800 				printf(" BUT NOT SET");
    801 			}
    802 		}
    803 		printf(" xs->error %d\n", xs->error);
    804 #endif
    805 		ISP_WRITE(isp, INMAILBOX5, optr);
    806 		scsi_done(xs);
    807 	}
    808 	isp->isp_residx = optr;
    809 	return (1);
    810 }
    811 
    812 /*
    813  * Support routines.
    814  */
    815 
    816 static int
    817 isp_parse_status(isp, sp)
    818 	struct ispsoftc *isp;
    819 	ispstatusreq_t *sp;
    820 {
    821 	switch (sp->req_completion_status) {
    822 	case RQCS_COMPLETE:
    823 		return (XS_NOERROR);
    824 		break;
    825 	case RQCS_INCOMPLETE:
    826 		if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
    827 			return (XS_SELTIMEOUT);
    828 		}
    829 		printf("%s: incomplete, state %x\n",
    830 			isp->isp_name, sp->req_state_flags);
    831 		break;
    832 	case RQCS_DATA_UNDERRUN:
    833 		return (XS_NOERROR);
    834 	case RQCS_TIMEOUT:
    835 		return (XS_TIMEOUT);
    836 	case RQCS_RESET_OCCURRED:
    837 		printf("%s: reset occurred\n", isp->isp_name);
    838 		isp->isp_sendmarker = 1;
    839 		break;
    840 	case RQCS_ABORTED:
    841 		printf("%s: command aborted\n", isp->isp_name);
    842 		isp->isp_sendmarker = 1;
    843 		break;
    844 	default:
    845 		printf("%s: comp status %x\n", isp->isp_name,
    846 		       sp->req_completion_status);
    847 		break;
    848 	}
    849 	return (XS_DRIVER_STUFFUP);
    850 }
    851 
    852 #define	HINIB(x)			((x) >> 0x4)
    853 #define	LONIB(x)			((x)  & 0xf)
    854 #define MAKNIB(a, b)			(((a) << 4) | (b))
    855 static u_int8_t mbpcnt[] = {
    856 	MAKNIB(1, 1),	/* MBOX_NO_OP */
    857 	MAKNIB(5, 5),	/* MBOX_LOAD_RAM */
    858 	MAKNIB(2, 0),	/* MBOX_EXEC_FIRMWARE */
    859 	MAKNIB(5, 5),	/* MBOX_DUMP_RAM */
    860 	MAKNIB(3, 3),	/* MBOX_WRITE_RAM_WORD */
    861 	MAKNIB(2, 3),	/* MBOX_READ_RAM_WORD */
    862 	MAKNIB(6, 6),	/* MBOX_MAILBOX_REG_TEST */
    863 	MAKNIB(2, 3),	/* MBOX_VERIFY_CHECKSUM	*/
    864 	MAKNIB(1, 3),	/* MBOX_ABOUT_FIRMWARE */
    865 	MAKNIB(0, 0),	/* 0x0009 */
    866 	MAKNIB(0, 0),	/* 0x000a */
    867 	MAKNIB(0, 0),	/* 0x000b */
    868 	MAKNIB(0, 0),	/* 0x000c */
    869 	MAKNIB(0, 0),	/* 0x000d */
    870 	MAKNIB(1, 2),	/* MBOX_CHECK_FIRMWARE */
    871 	MAKNIB(0, 0),	/* 0x000f */
    872 	MAKNIB(5, 5),	/* MBOX_INIT_REQ_QUEUE */
    873 	MAKNIB(6, 6),	/* MBOX_INIT_RES_QUEUE */
    874 	MAKNIB(4, 4),	/* MBOX_EXECUTE_IOCB */
    875 	MAKNIB(2, 2),	/* MBOX_WAKE_UP	*/
    876 	MAKNIB(1, 6),	/* MBOX_STOP_FIRMWARE */
    877 	MAKNIB(4, 4),	/* MBOX_ABORT */
    878 	MAKNIB(2, 2),	/* MBOX_ABORT_DEVICE */
    879 	MAKNIB(3, 3),	/* MBOX_ABORT_TARGET */
    880 	MAKNIB(2, 2),	/* MBOX_BUS_RESET */
    881 	MAKNIB(2, 3),	/* MBOX_STOP_QUEUE */
    882 	MAKNIB(2, 3),	/* MBOX_START_QUEUE */
    883 	MAKNIB(2, 3),	/* MBOX_SINGLE_STEP_QUEUE */
    884 	MAKNIB(2, 3),	/* MBOX_ABORT_QUEUE */
    885 	MAKNIB(2, 4),	/* MBOX_GET_DEV_QUEUE_STATUS */
    886 	MAKNIB(0, 0),	/* 0x001e */
    887 	MAKNIB(1, 3),	/* MBOX_GET_FIRMWARE_STATUS */
    888 	MAKNIB(1, 2),	/* MBOX_GET_INIT_SCSI_ID */
    889 	MAKNIB(1, 2),	/* MBOX_GET_SELECT_TIMEOUT */
    890 	MAKNIB(1, 3),	/* MBOX_GET_RETRY_COUNT	*/
    891 	MAKNIB(1, 2),	/* MBOX_GET_TAG_AGE_LIMIT */
    892 	MAKNIB(1, 2),	/* MBOX_GET_CLOCK_RATE */
    893 	MAKNIB(1, 2),	/* MBOX_GET_ACT_NEG_STATE */
    894 	MAKNIB(1, 2),	/* MBOX_GET_ASYNC_DATA_SETUP_TIME */
    895 	MAKNIB(1, 3),	/* MBOX_GET_PCI_PARAMS */
    896 	MAKNIB(2, 4),	/* MBOX_GET_TARGET_PARAMS */
    897 	MAKNIB(2, 4),	/* MBOX_GET_DEV_QUEUE_PARAMS */
    898 	MAKNIB(0, 0),	/* 0x002a */
    899 	MAKNIB(0, 0),	/* 0x002b */
    900 	MAKNIB(0, 0),	/* 0x002c */
    901 	MAKNIB(0, 0),	/* 0x002d */
    902 	MAKNIB(0, 0),	/* 0x002e */
    903 	MAKNIB(0, 0),	/* 0x002f */
    904 	MAKNIB(2, 2),	/* MBOX_SET_INIT_SCSI_ID */
    905 	MAKNIB(2, 2),	/* MBOX_SET_SELECT_TIMEOUT */
    906 	MAKNIB(3, 3),	/* MBOX_SET_RETRY_COUNT	*/
    907 	MAKNIB(2, 2),	/* MBOX_SET_TAG_AGE_LIMIT */
    908 	MAKNIB(2, 2),	/* MBOX_SET_CLOCK_RATE */
    909 	MAKNIB(2, 2),	/* MBOX_SET_ACTIVE_NEG_STATE */
    910 	MAKNIB(2, 2),	/* MBOX_SET_ASYNC_DATA_SETUP_TIME */
    911 	MAKNIB(3, 3),	/* MBOX_SET_PCI_CONTROL_PARAMS */
    912 	MAKNIB(4, 4),	/* MBOX_SET_TARGET_PARAMS */
    913 	MAKNIB(4, 4),	/* MBOX_SET_DEV_QUEUE_PARAMS */
    914 	MAKNIB(0, 0),	/* 0x003a */
    915 	MAKNIB(0, 0),	/* 0x003b */
    916 	MAKNIB(0, 0),	/* 0x003c */
    917 	MAKNIB(0, 0),	/* 0x003d */
    918 	MAKNIB(0, 0),	/* 0x003e */
    919 	MAKNIB(0, 0),	/* 0x003f */
    920 	MAKNIB(1, 2),	/* MBOX_RETURN_BIOS_BLOCK_ADDR */
    921 	MAKNIB(6, 1),	/* MBOX_WRITE_FOUR_RAM_WORDS */
    922 	MAKNIB(2, 3)	/* MBOX_EXEC_BIOS_IOCB */
    923 };
    924 #define	NMBCOM	(sizeof (mbpcnt) / sizeof (mbpcnt[0]))
    925 
    926 static int
    927 isp_mboxcmd(isp, mbp)
    928 	struct ispsoftc *isp;
    929 	mbreg_t *mbp;
    930 {
    931 	int outparam, inparam;
    932 	int loops;
    933 
    934 	if (mbp->param[0] > NMBCOM) {
    935 		printf("%s: bad command %x\n", isp->isp_name, mbp->param[0]);
    936 		return (-1);
    937 	}
    938 
    939 	inparam = HINIB(mbpcnt[mbp->param[0]]);
    940 	outparam =  LONIB(mbpcnt[mbp->param[0]]);
    941 	if (inparam == 0 && outparam == 0) {
    942 		printf("%s: no parameters for %x\n", isp->isp_name,
    943 			mbp->param[0]);
    944 		return (-1);
    945 	}
    946 
    947 	/*
    948 	 * Make sure we can send some words..
    949 	 */
    950 
    951 	loops = MBOX_DELAY_COUNT;
    952 	while ((ISP_READ(isp, HCCR) & HCCR_HOST_INT) != 0) {
    953 		delay(100);
    954 		if (--loops < 0) {
    955 			printf("%s: isp_mboxcmd timeout #1\n", isp->isp_name);
    956 			return (-1);
    957 		}
    958 	}
    959 
    960 	/*
    961 	 * Write input parameters
    962 	 */
    963 	switch (inparam) {
    964 	case 6: ISP_WRITE(isp, INMAILBOX5, mbp->param[5]); mbp->param[5] = 0;
    965 	case 5: ISP_WRITE(isp, INMAILBOX4, mbp->param[4]); mbp->param[4] = 0;
    966 	case 4: ISP_WRITE(isp, INMAILBOX3, mbp->param[3]); mbp->param[3] = 0;
    967 	case 3: ISP_WRITE(isp, INMAILBOX2, mbp->param[2]); mbp->param[2] = 0;
    968 	case 2: ISP_WRITE(isp, INMAILBOX1, mbp->param[1]); mbp->param[1] = 0;
    969 	case 1: ISP_WRITE(isp, INMAILBOX0, mbp->param[0]); mbp->param[0] = 0;
    970 	}
    971 
    972 	/*
    973 	 * Clear semaphore on mailbox registers
    974 	 */
    975 	ISP_WRITE(isp, BIU_SEMA, 0);
    976 
    977 	/*
    978 	 * Clear RISC int condition.
    979 	 */
    980 	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
    981 
    982 	/*
    983 	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
    984 	 */
    985 	ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
    986 
    987 	/*
    988 	 * Wait until RISC int is set
    989 	 */
    990 	loops = MBOX_DELAY_COUNT;
    991 	while ((ISP_READ(isp, BIU_ISR) & BIU_ISR_RISC_INT) != 0) {
    992 		delay(100);
    993 		if (--loops < 0) {
    994 			printf("%s: isp_mboxcmd timeout #2\n", isp->isp_name);
    995 			return (-1);
    996 		}
    997 	}
    998 
    999 	/*
   1000 	 * Check to make sure that the semaphore has been set.
   1001 	 */
   1002 	loops = MBOX_DELAY_COUNT;
   1003 	while ((ISP_READ(isp, BIU_SEMA) & 1) == 0) {
   1004 		delay(100);
   1005 		if (--loops < 0) {
   1006 			printf("%s: isp_mboxcmd timeout #3\n", isp->isp_name);
   1007 			return (-1);
   1008 		}
   1009 	}
   1010 
   1011 	/*
   1012 	 * Make sure that the MBOX_BUSY has gone away
   1013 	 */
   1014 	loops = MBOX_DELAY_COUNT;
   1015 	while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
   1016 		delay(100);
   1017 		if (--loops < 0) {
   1018 			printf("%s: isp_mboxcmd timeout #4\n", isp->isp_name);
   1019 			return (-1);
   1020 		}
   1021 	}
   1022 
   1023 
   1024 	/*
   1025 	 * Pick up output parameters.
   1026 	 */
   1027 	switch (outparam) {
   1028 	case 6: mbp->param[5] = ISP_READ(isp, OUTMAILBOX5);
   1029 	case 5: mbp->param[4] = ISP_READ(isp, OUTMAILBOX4);
   1030 	case 4: mbp->param[3] = ISP_READ(isp, OUTMAILBOX3);
   1031 	case 3: mbp->param[2] = ISP_READ(isp, OUTMAILBOX2);
   1032 	case 2: mbp->param[1] = ISP_READ(isp, OUTMAILBOX1);
   1033 	case 1: mbp->param[0] = ISP_READ(isp, OUTMAILBOX0);
   1034 	}
   1035 
   1036 	/*
   1037 	 * Clear RISC int.
   1038 	 */
   1039 	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
   1040 
   1041 	/*
   1042 	 * Release semaphore on mailbox registers
   1043 	 */
   1044 	ISP_WRITE(isp, BIU_SEMA, 0);
   1045 	return (0);
   1046 }
   1047 
   1048 static void
   1049 isp_lostcmd(struct ispsoftc *isp, struct scsi_xfer *xs)
   1050 {
   1051 	mbreg_t mbs;
   1052 	mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
   1053 	(void) isp_mboxcmd(isp, &mbs);
   1054 
   1055 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1056 		printf("%s: couldn't GET FIRMWARE STATUS\n", isp->isp_name);
   1057 		return;
   1058 	}
   1059 	printf("%s: lost command, %d commands active of total %d\n",
   1060 	       isp->isp_name, mbs.param[1], mbs.param[2]);
   1061 	if (xs == NULL || xs->sc_link == NULL)
   1062 		return;
   1063 
   1064 	mbs.param[0] = MBOX_GET_DEV_QUEUE_STATUS;
   1065 	mbs.param[1] = xs->sc_link->target << 8 | xs->sc_link->lun;
   1066 	(void) isp_mboxcmd(isp, &mbs);
   1067 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1068 		printf("%s: couldn't GET DEVICE STATUS\n", isp->isp_name);
   1069 		return;
   1070 	}
   1071 	printf("%s: lost command, target %d lun %d, State: %x\n",
   1072 	       isp->isp_name, mbs.param[1] >> 8, mbs.param[1] & 0x7,
   1073 	       mbs.param[2] & 0xff);
   1074 }
   1075