xref: /openbsd-src/sys/dev/ic/advlib.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /*	$OpenBSD: advlib.c,v 1.14 2013/11/15 16:46:27 brad Exp $	*/
2 /*      $NetBSD: advlib.c,v 1.7 1998/10/28 20:39:46 dante Exp $        */
3 
4 /*
5  * Low level routines for the Advanced Systems Inc. SCSI controllers chips
6  *
7  * Copyright (c) 1998 The NetBSD Foundation, Inc.
8  * All rights reserved.
9  *
10  * Author: Baldassare Dante Profeta <dante@mclink.it>
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 /*
34  * Ported from:
35  */
36 /*
37  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
38  *
39  * Copyright (c) 1995-1998 Advanced System Products, Inc.
40  * All Rights Reserved.
41  *
42  * Redistribution and use in source and binary forms, with or without
43  * modification, are permitted provided that redistributions of source
44  * code retain the above copyright notice and this comment without
45  * modification.
46  *
47  */
48 
49 #include <sys/types.h>
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/malloc.h>
53 #include <sys/kernel.h>
54 #include <sys/queue.h>
55 #include <sys/device.h>
56 
57 #include <machine/bus.h>
58 #include <machine/intr.h>
59 
60 #include <scsi/scsi_all.h>
61 #include <scsi/scsiconf.h>
62 
63 #include <uvm/uvm_extern.h>
64 
65 #include <dev/ic/adv.h>
66 #include <dev/ic/advlib.h>
67 
68 #include <dev/microcode/adw/advmcode.h>
69 
70 
71 /* #define ASC_DEBUG */
72 
73 /******************************************************************************/
74 /*                                Static functions                            */
75 /******************************************************************************/
76 
77 /* Initialization routines */
78 static u_int32_t AscLoadMicroCode(bus_space_tag_t, bus_space_handle_t,
79 					u_int16_t, u_int16_t *, u_int16_t);
80 static void AscInitLram(ASC_SOFTC *);
81 static void AscInitQLinkVar(ASC_SOFTC *);
82 static int AscResetChipAndScsiBus(bus_space_tag_t, bus_space_handle_t);
83 static u_int16_t AscGetChipBusType(bus_space_tag_t, bus_space_handle_t);
84 
85 /* Chip register routines */
86 static void AscSetBank(bus_space_tag_t, bus_space_handle_t, u_int8_t);
87 
88 /* RISC Chip routines */
89 static int AscStartChip(bus_space_tag_t, bus_space_handle_t);
90 static int AscStopChip(bus_space_tag_t, bus_space_handle_t);
91 static u_int8_t AscSetChipScsiID(bus_space_tag_t, bus_space_handle_t,
92 					u_int8_t);
93 static u_int8_t AscGetChipScsiCtrl(bus_space_tag_t, bus_space_handle_t);
94 static u_int8_t AscGetChipVersion(bus_space_tag_t, bus_space_handle_t,
95 					u_int16_t);
96 static int AscSetRunChipSynRegAtID(bus_space_tag_t, bus_space_handle_t,
97 					u_int8_t, u_int8_t);
98 static int AscSetChipSynRegAtID(bus_space_tag_t, bus_space_handle_t,
99 					u_int8_t, u_int8_t);
100 static int AscHostReqRiscHalt(bus_space_tag_t, bus_space_handle_t);
101 static int AscIsChipHalted(bus_space_tag_t, bus_space_handle_t);
102 static void AscSetChipIH(bus_space_tag_t, bus_space_handle_t, u_int16_t);
103 
104 /* Lram routines */
105 static u_int8_t AscReadLramByte(bus_space_tag_t, bus_space_handle_t,
106 					u_int16_t);
107 static void AscWriteLramByte(bus_space_tag_t, bus_space_handle_t,
108 					u_int16_t, u_int8_t);
109 static u_int16_t AscReadLramWord(bus_space_tag_t, bus_space_handle_t,
110 					u_int16_t);
111 static void AscWriteLramWord(bus_space_tag_t, bus_space_handle_t,
112 					u_int16_t, u_int16_t);
113 static u_int32_t AscReadLramDWord(bus_space_tag_t, bus_space_handle_t,
114 					u_int16_t);
115 static void AscWriteLramDWord(bus_space_tag_t, bus_space_handle_t,
116 					u_int16_t, u_int32_t);
117 static void AscMemWordSetLram(bus_space_tag_t, bus_space_handle_t,
118 					u_int16_t, u_int16_t, int);
119 static void AscMemWordCopyToLram(bus_space_tag_t, bus_space_handle_t,
120 					u_int16_t, u_int16_t *, int);
121 static void AscMemWordCopyFromLram(bus_space_tag_t, bus_space_handle_t,
122 					u_int16_t, u_int16_t *, int);
123 static void AscMemDWordCopyToLram(bus_space_tag_t, bus_space_handle_t,
124 					u_int16_t, u_int32_t *, int);
125 static u_int32_t AscMemSumLramWord(bus_space_tag_t, bus_space_handle_t,
126 					u_int16_t, int);
127 static int AscTestExternalLram(bus_space_tag_t, bus_space_handle_t);
128 
129 /* MicroCode routines */
130 static u_int16_t AscInitMicroCodeVar(ASC_SOFTC *);
131 static u_int32_t AscGetOnePhyAddr(ASC_SOFTC *, u_int8_t *, u_int32_t);
132 static u_int32_t AscGetSGList(ASC_SOFTC *, u_int8_t *, u_int32_t,
133 					ASC_SG_HEAD *);
134 
135 /* EEProm routines */
136 static int AscWriteEEPCmdReg(bus_space_tag_t, bus_space_handle_t,
137 					u_int8_t);
138 static int AscWriteEEPDataReg(bus_space_tag_t, bus_space_handle_t,
139 					u_int16_t);
140 static void AscWaitEEPRead(void);
141 static void AscWaitEEPWrite(void);
142 static u_int16_t AscReadEEPWord(bus_space_tag_t, bus_space_handle_t,
143 					u_int8_t);
144 static u_int16_t AscWriteEEPWord(bus_space_tag_t, bus_space_handle_t,
145 					u_int8_t, u_int16_t);
146 static u_int16_t AscGetEEPConfig(bus_space_tag_t, bus_space_handle_t,
147 					ASCEEP_CONFIG *, u_int16_t);
148 static int AscSetEEPConfig(bus_space_tag_t, bus_space_handle_t,
149 					ASCEEP_CONFIG *, u_int16_t);
150 static int AscSetEEPConfigOnce(bus_space_tag_t, bus_space_handle_t,
151 					ASCEEP_CONFIG *, u_int16_t);
152 #ifdef ASC_DEBUG
153 static void AscPrintEEPConfig(ASCEEP_CONFIG *, u_int16_t);
154 #endif
155 
156 /* Interrupt routines */
157 static void AscIsrChipHalted(ASC_SOFTC *);
158 static int AscIsrQDone(ASC_SOFTC *);
159 static int AscWaitTixISRDone(ASC_SOFTC *, u_int8_t);
160 static int AscWaitISRDone(ASC_SOFTC *);
161 static u_int8_t _AscCopyLramScsiDoneQ(bus_space_tag_t, bus_space_handle_t,
162 					u_int16_t, ASC_QDONE_INFO *,
163 					u_int32_t);
164 static void AscGetQDoneInfo(bus_space_tag_t, bus_space_handle_t, u_int16_t,
165 					ASC_QDONE_INFO *);
166 static void AscToggleIRQAct(bus_space_tag_t, bus_space_handle_t);
167 static void AscDisableInterrupt(bus_space_tag_t, bus_space_handle_t);
168 static void AscEnableInterrupt(bus_space_tag_t, bus_space_handle_t);
169 static u_int8_t AscGetChipIRQ(bus_space_tag_t, bus_space_handle_t,
170 					u_int16_t);
171 static u_int8_t AscSetChipIRQ(bus_space_tag_t, bus_space_handle_t,
172 					u_int8_t, u_int16_t);
173 static void AscAckInterrupt(bus_space_tag_t, bus_space_handle_t);
174 static u_int32_t AscGetMaxDmaCount(u_int16_t);
175 static u_int16_t AscGetIsaDmaChannel(bus_space_tag_t, bus_space_handle_t);
176 static u_int16_t AscSetIsaDmaChannel(bus_space_tag_t, bus_space_handle_t,
177 					u_int16_t);
178 static u_int8_t AscGetIsaDmaSpeed(bus_space_tag_t, bus_space_handle_t);
179 static u_int8_t AscSetIsaDmaSpeed(bus_space_tag_t, bus_space_handle_t,
180 					u_int8_t);
181 
182 /* Messages routines */
183 static void AscHandleExtMsgIn(ASC_SOFTC *, u_int16_t, u_int8_t,
184 					ASC_SCSI_BIT_ID_TYPE, int, u_int8_t);
185 static u_int8_t AscMsgOutSDTR(ASC_SOFTC *, u_int8_t, u_int8_t);
186 
187 /* SDTR routines */
188 static void AscSetChipSDTR(bus_space_tag_t, bus_space_handle_t,
189 					u_int8_t, u_int8_t);
190 static u_int8_t AscCalSDTRData(ASC_SOFTC *, u_int8_t, u_int8_t);
191 static u_int8_t AscGetSynPeriodIndex(ASC_SOFTC *, u_int8_t);
192 
193 /* Queue routines */
194 static int AscSendScsiQueue(ASC_SOFTC *, ASC_SCSI_Q *, u_int8_t);
195 static int AscSgListToQueue(int);
196 static u_int AscGetNumOfFreeQueue(ASC_SOFTC *, u_int8_t, u_int8_t);
197 static int AscPutReadyQueue(ASC_SOFTC *, ASC_SCSI_Q *, u_int8_t);
198 static void AscPutSCSIQ(bus_space_tag_t, bus_space_handle_t,
199 					 u_int16_t, ASC_SCSI_Q *);
200 static int AscPutReadySgListQueue(ASC_SOFTC *, ASC_SCSI_Q *, u_int8_t);
201 static u_int8_t AscAllocFreeQueue(bus_space_tag_t, bus_space_handle_t,
202 					u_int8_t);
203 static u_int8_t AscAllocMultipleFreeQueue(bus_space_tag_t,
204 					bus_space_handle_t,
205 					u_int8_t, u_int8_t);
206 static int AscStopQueueExe(bus_space_tag_t, bus_space_handle_t);
207 static void AscStartQueueExe(bus_space_tag_t, bus_space_handle_t);
208 static void AscCleanUpBusyQueue(bus_space_tag_t, bus_space_handle_t);
209 static int _AscWaitQDone(bus_space_tag_t, bus_space_handle_t,
210 					ASC_SCSI_Q *);
211 static int AscCleanUpDiscQueue(bus_space_tag_t, bus_space_handle_t);
212 
213 /* Abort and Reset CCB routines */
214 static int AscRiscHaltedAbortCCB(ASC_SOFTC *, u_int32_t);
215 static int AscRiscHaltedAbortTIX(ASC_SOFTC *, u_int8_t);
216 
217 /* Error Handling routines */
218 static int AscSetLibErrorCode(ASC_SOFTC *, u_int16_t);
219 
220 /* Handle bugged borads routines */
221 static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
222 static void AscAsyncFix(ASC_SOFTC *, u_int8_t, ASC_SCSI_INQUIRY *);
223 
224 /* Miscellaneous routines */
225 static int AscCompareString(u_char *, u_char *, int);
226 
227 /* Device oriented routines */
228 static int DvcEnterCritical(void);
229 static void DvcLeaveCritical(int);
230 static void DvcSleepMilliSecond(u_int32_t);
231 //static void DvcDelayMicroSecond(u_int32_t);
232 static void DvcDelayNanoSecond(u_int32_t);
233 
234 
235 /******************************************************************************/
236 /*                            Initialization routines                         */
237 /******************************************************************************/
238 
239 /*
240  * This function perform the following steps:
241  * - initialize ASC_SOFTC structure with defaults values.
242  * - inquire board registers to know what kind of board it is.
243  * - keep track of bugged borads.
244  */
245 void
246 AscInitASC_SOFTC(ASC_SOFTC *sc)
247 {
248 	bus_space_tag_t iot = sc->sc_iot;
249 	bus_space_handle_t ioh = sc->sc_ioh;
250 	int             i;
251 	u_int8_t        chip_version;
252 
253 	ASC_SET_CHIP_CONTROL(iot, ioh, ASC_CC_HALT);
254 	ASC_SET_CHIP_STATUS(iot, ioh, 0);
255 
256 	sc->bug_fix_cntl = 0;
257 	sc->pci_fix_asyn_xfer = 0;
258 	sc->pci_fix_asyn_xfer_always = 0;
259 	sc->sdtr_done = 0;
260 	sc->cur_total_qng = 0;
261 	sc->last_q_shortage = 0;
262 	sc->use_tagged_qng = 0;
263 	sc->unit_not_ready = 0;
264 	sc->queue_full_or_busy = 0;
265 	sc->host_init_sdtr_index = 0;
266 	sc->can_tagged_qng = 0;
267 	sc->cmd_qng_enabled = 0;
268 	sc->dvc_cntl = ASC_DEF_DVC_CNTL;
269 	sc->init_sdtr = 0;
270 	sc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
271 	sc->scsi_reset_wait = 3;
272 	sc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
273 	sc->max_dma_count = AscGetMaxDmaCount(sc->bus_type);
274 	sc->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
275 	sc->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
276 	sc->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
277 	sc->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
278 	sc->lib_version = (ASC_LIB_VERSION_MAJOR << 8) | ASC_LIB_VERSION_MINOR;
279 	chip_version = AscGetChipVersion(iot, ioh, sc->bus_type);
280 	sc->chip_version = chip_version;
281 	if ((sc->bus_type & ASC_IS_PCI) &&
282 	    (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
283 		sc->bus_type = ASC_IS_PCI_ULTRA;
284 		sc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
285 		sc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
286 		sc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
287 		sc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
288 		sc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
289 		sc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
290 		sc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
291 		sc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
292 		sc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
293 		sc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
294 		sc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
295 		sc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
296 		sc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
297 		sc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
298 		sc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
299 		sc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
300 		sc->max_sdtr_index = 15;
301 		if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
302 			ASC_SET_EXTRA_CONTROL(iot, ioh,
303 				       (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
304 		else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050)
305 			ASC_SET_EXTRA_CONTROL(iot, ioh,
306 				   (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
307 	} else {
308 		sc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
309 		sc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
310 		sc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
311 		sc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
312 		sc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
313 		sc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
314 		sc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
315 		sc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
316 		sc->max_sdtr_index = 7;
317 	}
318 
319 	if (sc->bus_type == ASC_IS_PCI)
320 		ASC_SET_EXTRA_CONTROL(iot, ioh,
321 				      (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
322 
323 	sc->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
324 	if (AscGetChipBusType(iot, ioh) == ASC_IS_ISAPNP) {
325 		ASC_SET_CHIP_IFC(iot, ioh, ASC_IFC_INIT_DEFAULT);
326 		sc->bus_type = ASC_IS_ISAPNP;
327 	}
328 	if ((sc->bus_type & ASC_IS_ISA) != 0)
329 		sc->isa_dma_channel = AscGetIsaDmaChannel(iot, ioh);
330 
331 	for (i = 0; i <= ASC_MAX_TID; i++) {
332 		sc->cur_dvc_qng[i] = 0;
333 		sc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
334 		sc->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
335 	}
336 }
337 
338 
339 /*
340  * This function initialize some ASC_SOFTC fields with values read from
341  * on-board EEProm.
342  */
343 u_int16_t
344 AscInitFromEEP(ASC_SOFTC *sc)
345 {
346 	bus_space_tag_t iot = sc->sc_iot;
347 	bus_space_handle_t ioh = sc->sc_ioh;
348 	ASCEEP_CONFIG   eep_config_buf;
349 	ASCEEP_CONFIG  *eep_config;
350 	u_int16_t       chksum;
351 	u_int16_t       warn_code;
352 	u_int16_t       cfg_msw, cfg_lsw;
353 	int             i;
354 	int             write_eep = 0;
355 
356 	warn_code = 0;
357 	AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0x00FE);
358 	AscStopQueueExe(iot, ioh);
359 	if ((AscStopChip(iot, ioh) == FALSE) ||
360 	    (AscGetChipScsiCtrl(iot, ioh) != 0)) {
361 		AscResetChipAndScsiBus(iot, ioh);
362 		DvcSleepMilliSecond(sc->scsi_reset_wait * 1000);
363 	}
364 	if (AscIsChipHalted(iot, ioh) == FALSE)
365 		return (-1);
366 
367 	ASC_SET_PC_ADDR(iot, ioh, ASC_MCODE_START_ADDR);
368 	if (ASC_GET_PC_ADDR(iot, ioh) != ASC_MCODE_START_ADDR)
369 		return (-2);
370 
371 	eep_config = &eep_config_buf;
372 	cfg_msw = ASC_GET_CHIP_CFG_MSW(iot, ioh);
373 	cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh);
374 	if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
375 		cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
376 		warn_code |= ASC_WARN_CFG_MSW_RECOVER;
377 		ASC_SET_CHIP_CFG_MSW(iot, ioh, cfg_msw);
378 	}
379 	chksum = AscGetEEPConfig(iot, ioh, eep_config, sc->bus_type);
380 #ifdef ASC_DEBUG
381 	AscPrintEEPConfig(eep_config, chksum);
382 #endif
383 	if (chksum == 0)
384 		chksum = 0xAA55;
385 
386 	if (ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_AUTO_CONFIG) {
387 		warn_code |= ASC_WARN_AUTO_CONFIG;
388 		if (sc->chip_version == 3) {
389 			if (eep_config->cfg_lsw != cfg_lsw) {
390 				warn_code |= ASC_WARN_EEPROM_RECOVER;
391 				eep_config->cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh);
392 			}
393 			if (eep_config->cfg_msw != cfg_msw) {
394 				warn_code |= ASC_WARN_EEPROM_RECOVER;
395 				eep_config->cfg_msw = ASC_GET_CHIP_CFG_MSW(iot, ioh);
396 			}
397 		}
398 	}
399 	eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
400 	eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
401 
402 	if (chksum != eep_config->chksum) {
403 		if (AscGetChipVersion(iot, ioh, sc->bus_type) ==
404 		    ASC_CHIP_VER_PCI_ULTRA_3050) {
405 			eep_config->init_sdtr = 0xFF;
406 			eep_config->disc_enable = 0xFF;
407 			eep_config->start_motor = 0xFF;
408 			eep_config->use_cmd_qng = 0;
409 			eep_config->max_total_qng = 0xF0;
410 			eep_config->max_tag_qng = 0x20;
411 			eep_config->cntl = 0xBFFF;
412 			eep_config->chip_scsi_id = 7;
413 			eep_config->no_scam = 0;
414 			eep_config->adapter_info[0] = 0;
415 			eep_config->adapter_info[1] = 0;
416 			eep_config->adapter_info[2] = 0;
417 			eep_config->adapter_info[3] = 0;
418 #if BYTE_ORDER == BIG_ENDIAN
419 			eep_config->adapter_info[5] = 0;
420 			/* Indicate EEPROM-less board. */
421 			eep_config->adapter_info[4] = 0xBB;
422 #else
423 			eep_config->adapter_info[4] = 0;
424 			/* Indicate EEPROM-less board. */
425 			eep_config->adapter_info[5] = 0xBB;
426 #endif
427 		} else {
428 			write_eep = 1;
429 			warn_code |= ASC_WARN_EEPROM_CHKSUM;
430 		}
431 	}
432 	sc->sdtr_enable = eep_config->init_sdtr;
433 	sc->disc_enable = eep_config->disc_enable;
434 	sc->cmd_qng_enabled = eep_config->use_cmd_qng;
435 	sc->isa_dma_speed = eep_config->isa_dma_speed;
436 	sc->start_motor = eep_config->start_motor;
437 	sc->dvc_cntl = eep_config->cntl;
438 #if BYTE_ORDER == BIG_ENDIAN
439 	sc->adapter_info[0] = eep_config->adapter_info[1];
440 	sc->adapter_info[1] = eep_config->adapter_info[0];
441 	sc->adapter_info[2] = eep_config->adapter_info[3];
442 	sc->adapter_info[3] = eep_config->adapter_info[2];
443 	sc->adapter_info[4] = eep_config->adapter_info[5];
444 	sc->adapter_info[5] = eep_config->adapter_info[4];
445 #else
446 	sc->adapter_info[0] = eep_config->adapter_info[0];
447 	sc->adapter_info[1] = eep_config->adapter_info[1];
448 	sc->adapter_info[2] = eep_config->adapter_info[2];
449 	sc->adapter_info[3] = eep_config->adapter_info[3];
450 	sc->adapter_info[4] = eep_config->adapter_info[4];
451 	sc->adapter_info[5] = eep_config->adapter_info[5];
452 #endif
453 
454 	if (!AscTestExternalLram(iot, ioh)) {
455 		if (((sc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
456 			eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
457 			eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
458 		} else {
459 			eep_config->cfg_msw |= 0x0800;
460 			cfg_msw |= 0x0800;
461 			ASC_SET_CHIP_CFG_MSW(iot, ioh, cfg_msw);
462 			eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
463 			eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
464 		}
465 	}
466 	if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG)
467 		eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
468 
469 	if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG)
470 		eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
471 
472 	if (eep_config->max_tag_qng > eep_config->max_total_qng)
473 		eep_config->max_tag_qng = eep_config->max_total_qng;
474 
475 	if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC)
476 		eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
477 
478 	sc->max_total_qng = eep_config->max_total_qng;
479 	if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
480 	    eep_config->use_cmd_qng) {
481 		eep_config->disc_enable = eep_config->use_cmd_qng;
482 		warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
483 	}
484 	if (sc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA))
485 		sc->irq_no = AscGetChipIRQ(iot, ioh, sc->bus_type);
486 
487 	eep_config->chip_scsi_id &= ASC_MAX_TID;
488 	sc->chip_scsi_id = eep_config->chip_scsi_id;
489 	if (((sc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
490 	    !(sc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
491 		sc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
492 	}
493 	for (i = 0; i <= ASC_MAX_TID; i++) {
494 		sc->max_tag_qng[i] = eep_config->max_tag_qng;
495 		sc->sdtr_period_offset[i] = ASC_DEF_SDTR_OFFSET |
496 			(sc->host_init_sdtr_index << 4);
497 	}
498 
499 	eep_config->cfg_msw = ASC_GET_CHIP_CFG_MSW(iot, ioh);
500 	if (write_eep) {
501 		AscSetEEPConfig(iot, ioh, eep_config, sc->bus_type);
502 #ifdef ASC_DEBUG
503 		AscPrintEEPConfig(eep_config, 0);
504 #endif
505 	}
506 
507 	return (warn_code);
508 }
509 
510 
511 u_int16_t
512 AscInitFromASC_SOFTC(ASC_SOFTC *sc)
513 {
514 	bus_space_tag_t iot = sc->sc_iot;
515 	bus_space_handle_t ioh = sc->sc_ioh;
516 	u_int16_t       cfg_msw;
517 	u_int16_t       warn_code;
518 	u_int16_t       pci_device_id = sc->pci_device_id;
519 
520 	warn_code = 0;
521 	cfg_msw = ASC_GET_CHIP_CFG_MSW(iot, ioh);
522 
523 	if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
524 		cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
525 		warn_code |= ASC_WARN_CFG_MSW_RECOVER;
526 		ASC_SET_CHIP_CFG_MSW(iot, ioh, cfg_msw);
527 	}
528 	if ((sc->cmd_qng_enabled & sc->disc_enable) != sc->cmd_qng_enabled) {
529 		sc->disc_enable = sc->cmd_qng_enabled;
530 		warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
531 	}
532 	if (ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_AUTO_CONFIG) {
533 		warn_code |= ASC_WARN_AUTO_CONFIG;
534 	}
535 	if ((sc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
536 		AscSetChipIRQ(iot, ioh, sc->irq_no, sc->bus_type);
537 	}
538 	if (sc->bus_type & ASC_IS_PCI) {
539 		cfg_msw &= 0xFFC0;
540 		ASC_SET_CHIP_CFG_MSW(iot, ioh, cfg_msw);
541 
542 		if ((sc->bus_type & ASC_IS_PCI_ULTRA) != ASC_IS_PCI_ULTRA) {
543 			if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
544 			    (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
545 				sc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
546 				sc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
547 			}
548 		}
549 	} else if (sc->bus_type == ASC_IS_ISAPNP) {
550 		if (AscGetChipVersion(iot, ioh, sc->bus_type) ==
551 		    ASC_CHIP_VER_ASYN_BUG) {
552 			sc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
553 		}
554 	}
555 	AscSetChipScsiID(iot, ioh, sc->chip_scsi_id);
556 
557 	if (sc->bus_type & ASC_IS_ISA) {
558 		AscSetIsaDmaChannel(iot, ioh, sc->isa_dma_channel);
559 		AscSetIsaDmaSpeed(iot, ioh, sc->isa_dma_speed);
560 	}
561 	return (warn_code);
562 }
563 
564 
565 /*
566  * - Initialize RISC chip
567  * - Initialize Lram
568  * - Load uCode into Lram
569  * - Enable Interrupts
570  */
571 int
572 AscInitDriver(ASC_SOFTC *sc)
573 {
574 	bus_space_tag_t iot = sc->sc_iot;
575 	bus_space_handle_t ioh = sc->sc_ioh;
576 	u_int32_t       chksum;
577 
578 	if (!AscFindSignature(iot, ioh))
579 		return (1);
580 
581 	AscDisableInterrupt(iot, ioh);
582 
583 	AscInitLram(sc);
584 	chksum = AscLoadMicroCode(iot, ioh, 0, (u_int16_t *) asc_mcode,
585 				  asc_mcode_size);
586 	if (chksum != asc_mcode_chksum)
587 		return (2);
588 
589 	if (AscInitMicroCodeVar(sc) == 0)
590 		return (3);
591 
592 	AscEnableInterrupt(iot, ioh);
593 
594 	return (0);
595 }
596 
597 
598 int
599 AscFindSignature(bus_space_tag_t iot, bus_space_handle_t ioh)
600 {
601 	u_int16_t       sig_word;
602 
603 	if (ASC_GET_CHIP_SIGNATURE_BYTE(iot, ioh) == ASC_1000_ID1B) {
604 		sig_word = ASC_GET_CHIP_SIGNATURE_WORD(iot, ioh);
605 		if (sig_word == ASC_1000_ID0W ||
606 		    sig_word == ASC_1000_ID0W_FIX)
607 			return (1);
608 	}
609 	return (0);
610 }
611 
612 
613 static void
614 AscInitLram(ASC_SOFTC *sc)
615 {
616 	bus_space_tag_t iot = sc->sc_iot;
617 	bus_space_handle_t ioh = sc->sc_ioh;
618 	u_int8_t        i;
619 	u_int16_t       s_addr;
620 
621 	AscMemWordSetLram(iot, ioh, ASC_QADR_BEG, 0,
622 			  (((sc->max_total_qng + 2 + 1) * 64) >> 1));
623 
624 	i = ASC_MIN_ACTIVE_QNO;
625 	s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
626 	AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_FWD, i + 1);
627 	AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_BWD, sc->max_total_qng);
628 	AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_QNO, i);
629 	i++;
630 	s_addr += ASC_QBLK_SIZE;
631 	for (; i < sc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
632 		AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_FWD, i + 1);
633 		AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_BWD, i - 1);
634 		AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_QNO, i);
635 	}
636 	AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_FWD, ASC_QLINK_END);
637 	AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_BWD, sc->max_total_qng - 1);
638 	AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_QNO, sc->max_total_qng);
639 	i++;
640 	s_addr += ASC_QBLK_SIZE;
641 	for (; i <= (u_int8_t) (sc->max_total_qng + 3); i++, s_addr += ASC_QBLK_SIZE) {
642 		AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_FWD, i);
643 		AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_BWD, i);
644 		AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_QNO, i);
645 	}
646 }
647 
648 
649 void
650 AscReInitLram(ASC_SOFTC *sc)
651 {
652 	AscInitLram(sc);
653 	AscInitQLinkVar(sc);
654 }
655 
656 
657 static void
658 AscInitQLinkVar(ASC_SOFTC *sc)
659 {
660 	bus_space_tag_t iot = sc->sc_iot;
661 	bus_space_handle_t ioh = sc->sc_ioh;
662 	u_int8_t        i;
663 	u_int16_t       lram_addr;
664 
665 	ASC_PUT_RISC_VAR_FREE_QHEAD(iot, ioh, 1);
666 	ASC_PUT_RISC_VAR_DONE_QTAIL(iot, ioh, sc->max_total_qng);
667 	ASC_PUT_VAR_FREE_QHEAD(iot, ioh, 1);
668 	ASC_PUT_VAR_DONE_QTAIL(iot, ioh, sc->max_total_qng);
669 	AscWriteLramByte(iot, ioh, ASCV_BUSY_QHEAD_B, sc->max_total_qng + 1);
670 	AscWriteLramByte(iot, ioh, ASCV_DISC1_QHEAD_B, sc->max_total_qng + 2);
671 	AscWriteLramByte(iot, ioh, ASCV_TOTAL_READY_Q_B, sc->max_total_qng);
672 	AscWriteLramWord(iot, ioh, ASCV_ASCDVC_ERR_CODE_W, 0);
673 	AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0);
674 	AscWriteLramByte(iot, ioh, ASCV_STOP_CODE_B, 0);
675 	AscWriteLramByte(iot, ioh, ASCV_SCSIBUSY_B, 0);
676 	AscWriteLramByte(iot, ioh, ASCV_WTM_FLAG_B, 0);
677 	ASC_PUT_QDONE_IN_PROGRESS(iot, ioh, 0);
678 	lram_addr = ASC_QADR_BEG;
679 	for (i = 0; i < 32; i++, lram_addr += 2)
680 		AscWriteLramWord(iot, ioh, lram_addr, 0);
681 }
682 
683 
684 static int
685 AscResetChipAndScsiBus(bus_space_tag_t iot, bus_space_handle_t ioh)
686 {
687 	while (ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_SCSI_RESET_ACTIVE);
688 
689 	AscStopChip(iot, ioh);
690 	ASC_SET_CHIP_CONTROL(iot, ioh, ASC_CC_CHIP_RESET | ASC_CC_SCSI_RESET | ASC_CC_HALT);
691 
692 	DvcDelayNanoSecond(60000);
693 
694 	AscSetChipIH(iot, ioh, ASC_INS_RFLAG_WTM);
695 	AscSetChipIH(iot, ioh, ASC_INS_HALT);
696 	ASC_SET_CHIP_CONTROL(iot, ioh, ASC_CC_CHIP_RESET | ASC_CC_HALT);
697 	ASC_SET_CHIP_CONTROL(iot, ioh, ASC_CC_HALT);
698 
699 	DvcSleepMilliSecond(200);
700 
701 	ASC_SET_CHIP_STATUS(iot, ioh, ASC_CIW_CLR_SCSI_RESET_INT);
702 	AscStartChip(iot, ioh);
703 
704 	DvcSleepMilliSecond(200);
705 
706 	return (AscIsChipHalted(iot, ioh));
707 }
708 
709 
710 static u_int16_t
711 AscGetChipBusType(bus_space_tag_t iot, bus_space_handle_t ioh)
712 {
713 	u_int16_t       chip_ver;
714 
715 	chip_ver = ASC_GET_CHIP_VER_NO(iot, ioh);
716 	if ((chip_ver >= ASC_CHIP_MIN_VER_VL) &&
717 	    (chip_ver <= ASC_CHIP_MAX_VER_VL)) {
718 		/*
719 		 * if(((iop_base & 0x0C30) == 0x0C30) || ((iop_base & 0x0C50)
720 		 * == 0x0C50)) return (ASC_IS_EISA);
721 		 */
722 		return (ASC_IS_VL);
723 	}
724 	if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
725 	    (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
726 		if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP)
727 			return (ASC_IS_ISAPNP);
728 
729 		return (ASC_IS_ISA);
730 	} else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
731 		   (chip_ver <= ASC_CHIP_MAX_VER_PCI))
732 		return (ASC_IS_PCI);
733 
734 	return (0);
735 }
736 
737 
738 /******************************************************************************/
739 /*                             Chip register routines                         */
740 /******************************************************************************/
741 
742 
743 static void
744 AscSetBank(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t bank)
745 {
746 	u_int8_t        val;
747 
748 	val = ASC_GET_CHIP_CONTROL(iot, ioh) &
749 		(~(ASC_CC_SINGLE_STEP | ASC_CC_TEST |
750 		   ASC_CC_DIAG | ASC_CC_SCSI_RESET |
751 		   ASC_CC_CHIP_RESET));
752 
753 	switch (bank) {
754 	case 1:
755 		val |= ASC_CC_BANK_ONE;
756 		break;
757 
758 	case 2:
759 		val |= ASC_CC_DIAG | ASC_CC_BANK_ONE;
760 		break;
761 
762 	default:
763 		val &= ~ASC_CC_BANK_ONE;
764 	}
765 
766 	ASC_SET_CHIP_CONTROL(iot, ioh, val);
767 	return;
768 }
769 
770 
771 /******************************************************************************/
772 /*                                 Chip routines                              */
773 /******************************************************************************/
774 
775 
776 static int
777 AscStartChip(bus_space_tag_t iot, bus_space_handle_t ioh)
778 {
779 	ASC_SET_CHIP_CONTROL(iot, ioh, 0);
780 	if ((ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_HALTED) != 0)
781 		return (0);
782 
783 	return (1);
784 }
785 
786 
787 static int
788 AscStopChip(bus_space_tag_t iot, bus_space_handle_t ioh)
789 {
790 	u_int8_t        cc_val;
791 
792 	cc_val = ASC_GET_CHIP_CONTROL(iot, ioh) &
793 		(~(ASC_CC_SINGLE_STEP | ASC_CC_TEST | ASC_CC_DIAG));
794 	ASC_SET_CHIP_CONTROL(iot, ioh, cc_val | ASC_CC_HALT);
795 	AscSetChipIH(iot, ioh, ASC_INS_HALT);
796 	AscSetChipIH(iot, ioh, ASC_INS_RFLAG_WTM);
797 	if ((ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_HALTED) == 0)
798 		return (0);
799 
800 	return (1);
801 }
802 
803 
804 static u_int8_t
805 AscGetChipVersion(bus_space_tag_t iot, bus_space_handle_t ioh,
806     u_int16_t bus_type)
807 {
808 	if (bus_type & ASC_IS_EISA) {
809 		/*
810 		 * u_int16_t	eisa_iop; u_int8_t	revision;
811 		 *
812 		 * eisa_iop = ASC_GET_EISA_SLOT(iop_base) |
813 		 * ASC_EISA_REV_IOP_MASK; revision = inp(eisa_iop);
814 		 * return((ASC_CHIP_MIN_VER_EISA - 1) + revision);
815 		 */
816 	}
817 	return (ASC_GET_CHIP_VER_NO(iot, ioh));
818 }
819 
820 
821 static u_int8_t
822 AscSetChipScsiID(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t new_id)
823 {
824 	u_int16_t       cfg_lsw;
825 
826 	if (ASC_GET_CHIP_SCSI_ID(iot, ioh) == new_id)
827 		return (new_id);
828 
829 	cfg_lsw = ASC_GET_CHIP_SCSI_ID(iot, ioh);
830 	cfg_lsw &= 0xF8FF;
831 	cfg_lsw |= (new_id & ASC_MAX_TID) << 8;
832 	ASC_SET_CHIP_CFG_LSW(iot, ioh, cfg_lsw);
833 	return (ASC_GET_CHIP_SCSI_ID(iot, ioh));
834 }
835 
836 
837 static u_int8_t
838 AscGetChipScsiCtrl(bus_space_tag_t iot, bus_space_handle_t ioh)
839 {
840 	u_int8_t        scsi_ctrl;
841 
842 	AscSetBank(iot, ioh, 1);
843 	scsi_ctrl = bus_space_read_1(iot, ioh, ASC_IOP_REG_SC);
844 	AscSetBank(iot, ioh, 0);
845 	return (scsi_ctrl);
846 }
847 
848 
849 static int
850 AscSetRunChipSynRegAtID(bus_space_tag_t iot, bus_space_handle_t ioh,
851     u_int8_t tid_no, u_int8_t sdtr_data)
852 {
853 	int             retval = FALSE;
854 
855 	if (AscHostReqRiscHalt(iot, ioh)) {
856 		retval = AscSetChipSynRegAtID(iot, ioh, tid_no, sdtr_data);
857 		AscStartChip(iot, ioh);
858 	}
859 	return (retval);
860 }
861 
862 
863 static int
864 AscSetChipSynRegAtID(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t id,
865     u_int8_t sdtr_data)
866 {
867 	ASC_SCSI_BIT_ID_TYPE org_id;
868 	int             i;
869 	int             sta = TRUE;
870 
871 	AscSetBank(iot, ioh, 1);
872 	org_id = ASC_READ_CHIP_DVC_ID(iot, ioh);
873 	for (i = 0; i <= ASC_MAX_TID; i++)
874 		if (org_id == (0x01 << i))
875 			break;
876 
877 	org_id = i;
878 	ASC_WRITE_CHIP_DVC_ID(iot, ioh, id);
879 	if (ASC_READ_CHIP_DVC_ID(iot, ioh) == (0x01 << id)) {
880 		AscSetBank(iot, ioh, 0);
881 		ASC_SET_CHIP_SYN(iot, ioh, sdtr_data);
882 		if (ASC_GET_CHIP_SYN(iot, ioh) != sdtr_data)
883 			sta = FALSE;
884 	} else
885 		sta = FALSE;
886 
887 	AscSetBank(iot, ioh, 1);
888 	ASC_WRITE_CHIP_DVC_ID(iot, ioh, org_id);
889 	AscSetBank(iot, ioh, 0);
890 	return (sta);
891 }
892 
893 
894 static int
895 AscHostReqRiscHalt(bus_space_tag_t iot, bus_space_handle_t ioh)
896 {
897 	int             count = 0;
898 	int             retval = 0;
899 	u_int8_t        saved_stop_code;
900 
901 	if (AscIsChipHalted(iot, ioh))
902 		return (1);
903 	saved_stop_code = AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B);
904 	AscWriteLramByte(iot, ioh, ASCV_STOP_CODE_B,
905 		      ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
906 
907 	do {
908 		if (AscIsChipHalted(iot, ioh)) {
909 			retval = 1;
910 			break;
911 		}
912 		DvcSleepMilliSecond(100);
913 	} while (count++ < 20);
914 
915 	AscWriteLramByte(iot, ioh, ASCV_STOP_CODE_B, saved_stop_code);
916 
917 	return (retval);
918 }
919 
920 
921 static int
922 AscIsChipHalted(bus_space_tag_t iot, bus_space_handle_t ioh)
923 {
924 	if ((ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_HALTED) != 0)
925 		if ((ASC_GET_CHIP_CONTROL(iot, ioh) & ASC_CC_HALT) != 0)
926 			return (1);
927 
928 	return (0);
929 }
930 
931 
932 static void
933 AscSetChipIH(bus_space_tag_t iot, bus_space_handle_t ioh, u_int16_t ins_code)
934 {
935 	AscSetBank(iot, ioh, 1);
936 	ASC_WRITE_CHIP_IH(iot, ioh, ins_code);
937 	AscSetBank(iot, ioh, 0);
938 
939 	return;
940 }
941 
942 
943 /******************************************************************************/
944 /*                                 Lram routines                              */
945 /******************************************************************************/
946 
947 
948 static u_int8_t
949 AscReadLramByte(bus_space_tag_t iot, bus_space_handle_t ioh, u_int16_t addr)
950 {
951 	u_int8_t        byte_data;
952 	u_int16_t       word_data;
953 
954 	ASC_SET_CHIP_LRAM_ADDR(iot, ioh, addr & 0xFFFE);
955 	word_data = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
956 
957 	if (addr & 1) {
958 		/* odd address */
959 		byte_data = (u_int8_t) ((word_data >> 8) & 0xFF);
960 	} else {
961 		/* even address */
962 		byte_data = (u_int8_t) (word_data & 0xFF);
963 	}
964 
965 	return (byte_data);
966 }
967 
968 
969 static void
970 AscWriteLramByte(bus_space_tag_t iot, bus_space_handle_t ioh, u_int16_t addr,
971     u_int8_t data)
972 {
973 	u_int16_t       word_data;
974 
975 	word_data = AscReadLramWord(iot, ioh, addr & 0xFFFE);
976 
977 	if (addr & 1) {
978 		/* odd address */
979 		word_data &= 0x00FF;
980 		word_data |= (((u_int16_t) data) << 8) & 0xFF00;
981 	} else {
982 		/* even address */
983 		word_data &= 0xFF00;
984 		word_data |= ((u_int16_t) data) & 0x00FF;
985 	}
986 
987 	AscWriteLramWord(iot, ioh, addr, word_data);
988 }
989 
990 
991 static u_int16_t
992 AscReadLramWord(bus_space_tag_t iot, bus_space_handle_t ioh, u_int16_t addr)
993 {
994 	ASC_SET_CHIP_LRAM_ADDR(iot, ioh, addr);
995 	return (ASC_GET_CHIP_LRAM_DATA(iot, ioh));
996 }
997 
998 
999 static void
1000 AscWriteLramWord(bus_space_tag_t iot, bus_space_handle_t ioh, u_int16_t addr,
1001     u_int16_t data)
1002 {
1003 	ASC_SET_CHIP_LRAM_ADDR(iot, ioh, addr);
1004 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, data);
1005 }
1006 
1007 
1008 static u_int32_t
1009 AscReadLramDWord(bus_space_tag_t iot, bus_space_handle_t ioh, u_int16_t addr)
1010 {
1011 	u_int16_t       low_word, hi_word;
1012 
1013 	ASC_SET_CHIP_LRAM_ADDR(iot, ioh, addr);
1014 	low_word = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
1015 	hi_word = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
1016 
1017 	return ((((u_int32_t) hi_word) << 16) | (u_int32_t) low_word);
1018 }
1019 
1020 
1021 static void
1022 AscWriteLramDWord(bus_space_tag_t iot, bus_space_handle_t ioh, u_int16_t addr,
1023     u_int32_t data)
1024 {
1025 	ASC_SET_CHIP_LRAM_ADDR(iot, ioh, addr);
1026 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, (u_int16_t) (data & 0x0000FFFF));
1027 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, (u_int16_t) (data >> 16));
1028 }
1029 
1030 
1031 static void
1032 AscMemWordSetLram(bus_space_tag_t iot, bus_space_handle_t ioh, u_int16_t s_addr,
1033     u_int16_t s_words, int count)
1034 {
1035 	int             i;
1036 
1037 	ASC_SET_CHIP_LRAM_ADDR(iot, ioh, s_addr);
1038 	for (i = 0; i < count; i++)
1039 		ASC_SET_CHIP_LRAM_DATA(iot, ioh, s_words);
1040 }
1041 
1042 
1043 static void
1044 AscMemWordCopyToLram(bus_space_tag_t iot, bus_space_handle_t ioh,
1045     u_int16_t s_addr, u_int16_t *s_buffer, int words)
1046 {
1047 	int             i;
1048 
1049 	ASC_SET_CHIP_LRAM_ADDR(iot, ioh, s_addr);
1050 	for (i = 0; i < words; i++, s_buffer++)
1051 		ASC_SET_CHIP_LRAM_DATA_NO_SWAP(iot, ioh, *s_buffer);
1052 }
1053 
1054 
1055 static void
1056 AscMemWordCopyFromLram(bus_space_tag_t iot, bus_space_handle_t ioh,
1057     u_int16_t s_addr, u_int16_t *s_buffer, int words)
1058 {
1059 	int             i;
1060 
1061 	ASC_SET_CHIP_LRAM_ADDR(iot, ioh, s_addr);
1062 	for (i = 0; i < words; i++, s_buffer++)
1063 		*s_buffer = ASC_GET_CHIP_LRAM_DATA_NO_SWAP(iot, ioh);
1064 }
1065 
1066 
1067 static void
1068 AscMemDWordCopyToLram(bus_space_tag_t iot, bus_space_handle_t ioh,
1069     u_int16_t s_addr, u_int32_t *s_buffer, int dwords)
1070 {
1071 	int             i;
1072 	u_int32_t      *pw;
1073 
1074 	ASC_SET_CHIP_LRAM_ADDR(iot, ioh, s_addr);
1075 
1076 	pw = s_buffer;
1077 	for (i = 0; i < dwords; i++, pw++) {
1078 		ASC_SET_CHIP_LRAM_DATA(iot, ioh, LO_WORD(*pw));
1079 		DELAY(1);
1080 		ASC_SET_CHIP_LRAM_DATA(iot, ioh, HI_WORD(*pw));
1081 	}
1082 }
1083 
1084 
1085 static u_int32_t
1086 AscMemSumLramWord(bus_space_tag_t iot, bus_space_handle_t ioh, u_int16_t s_addr,
1087     int words)
1088 {
1089 	u_int32_t       sum = 0L;
1090 	u_int16_t       i;
1091 
1092 	for (i = 0; i < words; i++, s_addr += 2)
1093 		sum += AscReadLramWord(iot, ioh, s_addr);
1094 
1095 	return (sum);
1096 }
1097 
1098 
1099 static int
1100 AscTestExternalLram(bus_space_tag_t iot, bus_space_handle_t ioh)
1101 {
1102 	u_int16_t       q_addr;
1103 	u_int16_t       saved_word;
1104 	int             retval;
1105 
1106 	retval = 0;
1107 	q_addr = ASC_QNO_TO_QADDR(241);
1108 	saved_word = AscReadLramWord(iot, ioh, q_addr);
1109 	ASC_SET_CHIP_LRAM_ADDR(iot, ioh, q_addr);
1110 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, 0x55AA);
1111 	DvcSleepMilliSecond(10);
1112 	ASC_SET_CHIP_LRAM_ADDR(iot, ioh, q_addr);
1113 
1114 	if (ASC_GET_CHIP_LRAM_DATA(iot, ioh) == 0x55AA) {
1115 		retval = 1;
1116 		AscWriteLramWord(iot, ioh, q_addr, saved_word);
1117 	}
1118 	return (retval);
1119 }
1120 
1121 
1122 /******************************************************************************/
1123 /*                               MicroCode routines                           */
1124 /******************************************************************************/
1125 
1126 
1127 static u_int16_t
1128 AscInitMicroCodeVar(ASC_SOFTC *sc)
1129 {
1130 	bus_space_tag_t iot = sc->sc_iot;
1131 	bus_space_handle_t ioh = sc->sc_ioh;
1132 	u_int32_t       phy_addr;
1133 	int             i;
1134 
1135 	for (i = 0; i <= ASC_MAX_TID; i++)
1136 		ASC_PUT_MCODE_INIT_SDTR_AT_ID(iot, ioh, i,
1137 					      sc->sdtr_period_offset[i]);
1138 
1139 	AscInitQLinkVar(sc);
1140 	AscWriteLramByte(iot, ioh, ASCV_DISC_ENABLE_B, sc->disc_enable);
1141 	AscWriteLramByte(iot, ioh, ASCV_HOSTSCSI_ID_B,
1142 			 ASC_TID_TO_TARGET_ID(sc->chip_scsi_id));
1143 
1144 	if ((phy_addr = AscGetOnePhyAddr(sc, sc->overrun_buf,
1145 					 ASC_OVERRUN_BSIZE)) == 0L) {
1146 		return (0);
1147 	} else {
1148 		phy_addr = (phy_addr & 0xFFFFFFF8ul) + 8;
1149 		AscWriteLramDWord(iot, ioh, ASCV_OVERRUN_PADDR_D, phy_addr);
1150 		AscWriteLramDWord(iot, ioh, ASCV_OVERRUN_BSIZE_D,
1151 				  ASC_OVERRUN_BSIZE - 8);
1152 	}
1153 
1154 	sc->mcode_date = AscReadLramWord(iot, ioh, ASCV_MC_DATE_W);
1155 	sc->mcode_version = AscReadLramWord(iot, ioh, ASCV_MC_VER_W);
1156 	ASC_SET_PC_ADDR(iot, ioh, ASC_MCODE_START_ADDR);
1157 
1158 	if (ASC_GET_PC_ADDR(iot, ioh) != ASC_MCODE_START_ADDR) {
1159 		return (0);
1160 	}
1161 	if (AscStartChip(iot, ioh) != 1) {
1162 		return (0);
1163 	}
1164 	return (1);
1165 }
1166 
1167 
1168 static u_int32_t
1169 AscLoadMicroCode(bus_space_tag_t iot, bus_space_handle_t ioh, u_int16_t s_addr,
1170     u_int16_t *mcode_buf, u_int16_t mcode_size)
1171 {
1172 	u_int32_t       chksum;
1173 	u_int16_t       mcode_word_size;
1174 	u_int16_t       mcode_chksum;
1175 
1176 	mcode_word_size = mcode_size >> 1;
1177 	/* clear board memory */
1178 	AscMemWordSetLram(iot, ioh, s_addr, 0, mcode_word_size);
1179 	/* copy uCode to board memory */
1180 	AscMemWordCopyToLram(iot, ioh, s_addr, mcode_buf, mcode_word_size);
1181 	chksum = AscMemSumLramWord(iot, ioh, s_addr, mcode_word_size);
1182 	mcode_chksum = AscMemSumLramWord(iot, ioh, ASC_CODE_SEC_BEG,
1183 			   ((mcode_size - s_addr - ASC_CODE_SEC_BEG) >> 1));
1184 	AscWriteLramWord(iot, ioh, ASCV_MCODE_CHKSUM_W, mcode_chksum);
1185 	AscWriteLramWord(iot, ioh, ASCV_MCODE_SIZE_W, mcode_size);
1186 
1187 	return (chksum);
1188 }
1189 
1190 
1191 static u_int32_t
1192 AscGetOnePhyAddr(ASC_SOFTC *sc, u_int8_t *buf_addr, u_int32_t buf_size)
1193 {
1194 	ASC_MIN_SG_HEAD sg_head;
1195 
1196 	sg_head.entry_cnt = ASC_MIN_SG_LIST;
1197 	if (AscGetSGList(sc, buf_addr, buf_size, (ASC_SG_HEAD *) & sg_head) !=
1198 	    buf_size) {
1199 		return (0L);
1200 	}
1201 	if (sg_head.entry_cnt > 1) {
1202 		return (0L);
1203 	}
1204 	return (sg_head.sg_list[0].addr);
1205 }
1206 
1207 
1208 static u_int32_t
1209 AscGetSGList(ASC_SOFTC *sc, u_int8_t *buf_addr, u_int32_t buf_len,
1210     ASC_SG_HEAD *asc_sg_head_ptr)
1211 {
1212 	u_int32_t       buf_size;
1213 
1214 	buf_size = buf_len;
1215 	asc_sg_head_ptr->entry_cnt = 1;
1216 	asc_sg_head_ptr->sg_list[0].addr = (u_int32_t) buf_addr;
1217 	asc_sg_head_ptr->sg_list[0].bytes = buf_size;
1218 
1219 	return (buf_size);
1220 }
1221 
1222 
1223 /******************************************************************************/
1224 /*                                 EEProm routines                            */
1225 /******************************************************************************/
1226 
1227 
1228 static int
1229 AscWriteEEPCmdReg(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t cmd_reg)
1230 {
1231 	u_int8_t        read_back;
1232 	int             retry;
1233 
1234 	retry = 0;
1235 
1236 	while (TRUE) {
1237 		ASC_SET_CHIP_EEP_CMD(iot, ioh, cmd_reg);
1238 		DvcSleepMilliSecond(1);
1239 		read_back = ASC_GET_CHIP_EEP_CMD(iot, ioh);
1240 		if (read_back == cmd_reg)
1241 			return (1);
1242 
1243 		if (retry++ > ASC_EEP_MAX_RETRY)
1244 			return (0);
1245 	}
1246 }
1247 
1248 
1249 static int
1250 AscWriteEEPDataReg(bus_space_tag_t iot, bus_space_handle_t ioh,
1251     u_int16_t data_reg)
1252 {
1253 	u_int16_t       read_back;
1254 	int             retry;
1255 
1256 	retry = 0;
1257 	while (TRUE) {
1258 		ASC_SET_CHIP_EEP_DATA(iot, ioh, data_reg);
1259 		DvcSleepMilliSecond(1);
1260 		read_back = ASC_GET_CHIP_EEP_DATA(iot, ioh);
1261 		if (read_back == data_reg)
1262 			return (1);
1263 
1264 		if (retry++ > ASC_EEP_MAX_RETRY)
1265 			return (0);
1266 	}
1267 }
1268 
1269 
1270 static void
1271 AscWaitEEPRead(void)
1272 {
1273 	DvcSleepMilliSecond(1);
1274 }
1275 
1276 
1277 static void
1278 AscWaitEEPWrite(void)
1279 {
1280 	DvcSleepMilliSecond(1);
1281 }
1282 
1283 
1284 static u_int16_t
1285 AscReadEEPWord(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t addr)
1286 {
1287 	u_int16_t       read_wval;
1288 	u_int8_t        cmd_reg;
1289 
1290 	AscWriteEEPCmdReg(iot, ioh, ASC_EEP_CMD_WRITE_DISABLE);
1291 	AscWaitEEPRead();
1292 	cmd_reg = addr | ASC_EEP_CMD_READ;
1293 	AscWriteEEPCmdReg(iot, ioh, cmd_reg);
1294 	AscWaitEEPRead();
1295 	read_wval = ASC_GET_CHIP_EEP_DATA(iot, ioh);
1296 	AscWaitEEPRead();
1297 
1298 	return (read_wval);
1299 }
1300 
1301 
1302 static u_int16_t
1303 AscWriteEEPWord(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t addr,
1304     u_int16_t word_val)
1305 {
1306 	u_int16_t       read_wval;
1307 
1308 	read_wval = AscReadEEPWord(iot, ioh, addr);
1309 	if (read_wval != word_val) {
1310 		AscWriteEEPCmdReg(iot, ioh, ASC_EEP_CMD_WRITE_ABLE);
1311 		AscWaitEEPRead();
1312 		AscWriteEEPDataReg(iot, ioh, word_val);
1313 		AscWaitEEPRead();
1314 		AscWriteEEPCmdReg(iot, ioh, ASC_EEP_CMD_WRITE | addr);
1315 		AscWaitEEPWrite();
1316 		AscWriteEEPCmdReg(iot, ioh, ASC_EEP_CMD_WRITE_DISABLE);
1317 		AscWaitEEPRead();
1318 		return (AscReadEEPWord(iot, ioh, addr));
1319 	}
1320 	return (read_wval);
1321 }
1322 
1323 
1324 static u_int16_t
1325 AscGetEEPConfig(bus_space_tag_t iot, bus_space_handle_t ioh,
1326     ASCEEP_CONFIG *cfg_buf, u_int16_t bus_type)
1327 {
1328 	u_int16_t       wval;
1329 	u_int16_t       sum;
1330 	u_int16_t      *wbuf;
1331 	int             cfg_beg;
1332 	int             cfg_end;
1333 	int             s_addr;
1334 	int             isa_pnp_wsize;
1335 
1336 	wbuf = (u_int16_t *) cfg_buf;
1337 	sum = 0;
1338 	isa_pnp_wsize = 0;
1339 
1340 	for (s_addr = 0; s_addr < (2 + isa_pnp_wsize); s_addr++, wbuf++) {
1341 		wval = AscReadEEPWord(iot, ioh, s_addr);
1342 		sum += wval;
1343 		*wbuf = wval;
1344 	}
1345 
1346 	if (bus_type & ASC_IS_VL) {
1347 		cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
1348 		cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
1349 	} else {
1350 		cfg_beg = ASC_EEP_DVC_CFG_BEG;
1351 		cfg_end = ASC_EEP_MAX_DVC_ADDR;
1352 	}
1353 
1354 	for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
1355 		wval = AscReadEEPWord(iot, ioh, s_addr);
1356 		sum += wval;
1357 		*wbuf = wval;
1358 	}
1359 
1360 	*wbuf = AscReadEEPWord(iot, ioh, s_addr);
1361 
1362 	return (sum);
1363 }
1364 
1365 
1366 static int
1367 AscSetEEPConfig(bus_space_tag_t iot, bus_space_handle_t ioh,
1368     ASCEEP_CONFIG *cfg_buf, u_int16_t bus_type)
1369 {
1370 	int             retry;
1371 	int             n_error;
1372 
1373 	retry = 0;
1374 	while (TRUE) {
1375 		if ((n_error = AscSetEEPConfigOnce(iot, ioh, cfg_buf, bus_type)) == 0)
1376 			break;
1377 
1378 		if (++retry > ASC_EEP_MAX_RETRY)
1379 			break;
1380 	}
1381 
1382 	return (n_error);
1383 }
1384 
1385 
1386 static int
1387 AscSetEEPConfigOnce(bus_space_tag_t iot, bus_space_handle_t ioh,
1388     ASCEEP_CONFIG *cfg_buf, u_int16_t bus_type)
1389 {
1390 	int             n_error;
1391 	u_int16_t      *wbuf;
1392 	u_int16_t       sum;
1393 	int             s_addr;
1394 	int             cfg_beg;
1395 	int             cfg_end;
1396 
1397 	wbuf = (u_int16_t *) cfg_buf;
1398 	n_error = 0;
1399 	sum = 0;
1400 
1401 	for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
1402 		sum += *wbuf;
1403 		if (*wbuf != AscWriteEEPWord(iot, ioh, s_addr, *wbuf))
1404 			n_error++;
1405 	}
1406 
1407 	if (bus_type & ASC_IS_VL) {
1408 		cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
1409 		cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
1410 	} else {
1411 		cfg_beg = ASC_EEP_DVC_CFG_BEG;
1412 		cfg_end = ASC_EEP_MAX_DVC_ADDR;
1413 	}
1414 
1415 	for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
1416 		sum += *wbuf;
1417 		if (*wbuf != AscWriteEEPWord(iot, ioh, s_addr, *wbuf))
1418 			n_error++;
1419 	}
1420 
1421 	*wbuf = sum;
1422 	if (sum != AscWriteEEPWord(iot, ioh, s_addr, sum))
1423 		n_error++;
1424 
1425 	wbuf = (u_int16_t *) cfg_buf;
1426 	for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
1427 		if (*wbuf != AscReadEEPWord(iot, ioh, s_addr))
1428 			n_error++;
1429 	}
1430 
1431 	for (s_addr = cfg_beg; s_addr <= cfg_end; s_addr++, wbuf++) {
1432 		if (*wbuf != AscReadEEPWord(iot, ioh, s_addr))
1433 			n_error++;
1434 	}
1435 
1436 	return (n_error);
1437 }
1438 
1439 
1440 #ifdef ASC_DEBUG
1441 static void
1442 AscPrintEEPConfig(ASCEEP_CONFIG *eep_config, u_int16_t chksum)
1443 {
1444 	printf("---- ASC EEprom settings ----\n");
1445 	printf("cfg_lsw = 0x%x\n", eep_config->cfg_lsw);
1446 	printf("cfg_msw = 0x%x\n", eep_config->cfg_msw);
1447 	printf("init_sdtr = 0x%x\n", eep_config->init_sdtr);
1448 	printf("disc_enable = 0x%x\n", eep_config->disc_enable);
1449 	printf("use_cmd_qng = %d\n", eep_config->use_cmd_qng);
1450 	printf("start_motor = 0x%x\n", eep_config->start_motor);
1451 	printf("max_total_qng = 0x%x\n", eep_config->max_total_qng);
1452 	printf("max_tag_qng = 0x%x\n", eep_config->max_tag_qng);
1453 	printf("bios_scan = 0x%x\n", eep_config->bios_scan);
1454 	printf("power_up_wait = 0x%x\n", eep_config->power_up_wait);
1455 	printf("no_scam = %d\n", eep_config->no_scam);
1456 	printf("chip_scsi_id = %d\n", eep_config->chip_scsi_id);
1457 	printf("isa_dma_speed = %d\n", eep_config->isa_dma_speed);
1458 	printf("cntl = 0x%x\n", eep_config->cntl);
1459 #if BYTE_ORDER == BIG_ENDIAN
1460 	printf("adapter_info[0] = 0x%x\n", eep_config->adapter_info[1]);
1461 	printf("adapter_info[1] = 0x%x\n", eep_config->adapter_info[0]);
1462 	printf("adapter_info[2] = 0x%x\n", eep_config->adapter_info[3]);
1463 	printf("adapter_info[3] = 0x%x\n", eep_config->adapter_info[2]);
1464 	printf("adapter_info[4] = 0x%x\n", eep_config->adapter_info[5]);
1465 	printf("adapter_info[5] = 0x%x\n", eep_config->adapter_info[4]);
1466 #else
1467 	printf("adapter_info[0] = 0x%x\n", eep_config->adapter_info[0]);
1468 	printf("adapter_info[1] = 0x%x\n", eep_config->adapter_info[1]);
1469 	printf("adapter_info[2] = 0x%x\n", eep_config->adapter_info[2]);
1470 	printf("adapter_info[3] = 0x%x\n", eep_config->adapter_info[3]);
1471 	printf("adapter_info[4] = 0x%x\n", eep_config->adapter_info[4]);
1472 	printf("adapter_info[5] = 0x%x\n", eep_config->adapter_info[5]);
1473 #endif
1474 	printf("checksum = 0x%x\n", eep_config->chksum);
1475 	printf("calculated checksum = 0x%x\n", chksum);
1476 	printf("-----------------------------\n");
1477 }
1478 #endif
1479 
1480 
1481 /******************************************************************************/
1482 /*                               Interrupt routines                           */
1483 /******************************************************************************/
1484 
1485 
1486 int
1487 AscISR(ASC_SOFTC *sc)
1488 {
1489 	bus_space_tag_t iot = sc->sc_iot;
1490 	bus_space_handle_t ioh = sc->sc_ioh;
1491 	u_int16_t       chipstat;
1492 	u_int16_t       saved_ram_addr;
1493 	u_int8_t        ctrl_reg;
1494 	u_int8_t        saved_ctrl_reg;
1495 	int             int_pending;
1496 	int             status;
1497 	u_int8_t        host_flag;
1498 
1499 	int_pending = FALSE;
1500 
1501 	ctrl_reg = ASC_GET_CHIP_CONTROL(iot, ioh);
1502 	saved_ctrl_reg = ctrl_reg & (~(ASC_CC_SCSI_RESET | ASC_CC_CHIP_RESET |
1503 			   ASC_CC_SINGLE_STEP | ASC_CC_DIAG | ASC_CC_TEST));
1504 	chipstat = ASC_GET_CHIP_STATUS(iot, ioh);
1505 	if (chipstat & ASC_CSW_SCSI_RESET_LATCH) {
1506 		if (!(sc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
1507 			int_pending = TRUE;
1508 			sc->sdtr_done = 0;
1509 			saved_ctrl_reg &= (u_int8_t) (~ASC_CC_HALT);
1510 
1511 			while (ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_SCSI_RESET_ACTIVE);
1512 
1513 			ASC_SET_CHIP_CONTROL(iot, ioh, (ASC_CC_CHIP_RESET | ASC_CC_HALT));
1514 			ASC_SET_CHIP_CONTROL(iot, ioh, ASC_CC_HALT);
1515 			ASC_SET_CHIP_STATUS(iot, ioh, ASC_CIW_CLR_SCSI_RESET_INT);
1516 			ASC_SET_CHIP_STATUS(iot, ioh, 0);
1517 			chipstat = ASC_GET_CHIP_STATUS(iot, ioh);
1518 		}
1519 	}
1520 	saved_ram_addr = ASC_GET_CHIP_LRAM_ADDR(iot, ioh);
1521 	host_flag = AscReadLramByte(iot, ioh, ASCV_HOST_FLAG_B) &
1522 		(u_int8_t) (~ASC_HOST_FLAG_IN_ISR);
1523 	AscWriteLramByte(iot, ioh, ASCV_HOST_FLAG_B,
1524 			 (host_flag | ASC_HOST_FLAG_IN_ISR));
1525 
1526 	if ((chipstat & ASC_CSW_INT_PENDING) || (int_pending)) {
1527 		AscAckInterrupt(iot, ioh);
1528 		int_pending = TRUE;
1529 
1530 		if ((chipstat & ASC_CSW_HALTED) &&
1531 		    (ctrl_reg & ASC_CC_SINGLE_STEP)) {
1532 			AscIsrChipHalted(sc);
1533 			saved_ctrl_reg &= ~ASC_CC_HALT;
1534 		} else {
1535 			if (sc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) {
1536 				while (((status = AscIsrQDone(sc)) & 0x01) != 0);
1537 			} else {
1538 				do {
1539 					if ((status = AscIsrQDone(sc)) == 1)
1540 						break;
1541 				} while (status == 0x11);
1542 			}
1543 
1544 			if (status & 0x80)
1545 				int_pending = -1;
1546 		}
1547 	}
1548 	AscWriteLramByte(iot, ioh, ASCV_HOST_FLAG_B, host_flag);
1549 	ASC_SET_CHIP_LRAM_ADDR(iot, ioh, saved_ram_addr);
1550 	ASC_SET_CHIP_CONTROL(iot, ioh, saved_ctrl_reg);
1551 
1552 	return (1);
1553 	/* return(int_pending); */
1554 }
1555 
1556 
1557 static int
1558 AscIsrQDone(ASC_SOFTC *sc)
1559 {
1560 	u_int8_t        next_qp;
1561 	u_int8_t        n_q_used;
1562 	u_int8_t        sg_list_qp;
1563 	u_int8_t        sg_queue_cnt;
1564 	u_int8_t        q_cnt;
1565 	u_int8_t        done_q_tail;
1566 	u_int8_t        tid_no;
1567 	ASC_SCSI_BIT_ID_TYPE scsi_busy;
1568 	ASC_SCSI_BIT_ID_TYPE target_id;
1569 	bus_space_tag_t iot = sc->sc_iot;
1570 	bus_space_handle_t ioh = sc->sc_ioh;
1571 	u_int16_t       q_addr;
1572 	u_int16_t       sg_q_addr;
1573 	u_int8_t        cur_target_qng;
1574 	ASC_QDONE_INFO  scsiq_buf;
1575 	ASC_QDONE_INFO *scsiq;
1576 	ASC_ISR_CALLBACK asc_isr_callback;
1577 
1578 	asc_isr_callback = (ASC_ISR_CALLBACK) sc->isr_callback;
1579 	n_q_used = 1;
1580 	scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
1581 	done_q_tail = ASC_GET_VAR_DONE_QTAIL(iot, ioh);
1582 	q_addr = ASC_QNO_TO_QADDR(done_q_tail);
1583 	next_qp = AscReadLramByte(iot, ioh, (q_addr + ASC_SCSIQ_B_FWD));
1584 
1585 	if (next_qp != ASC_QLINK_END) {
1586 		ASC_PUT_VAR_DONE_QTAIL(iot, ioh, next_qp);
1587 		q_addr = ASC_QNO_TO_QADDR(next_qp);
1588 		sg_queue_cnt = _AscCopyLramScsiDoneQ(iot, ioh, q_addr, scsiq,
1589 						     sc->max_dma_count);
1590 		AscWriteLramByte(iot, ioh, (q_addr + ASC_SCSIQ_B_STATUS),
1591 		      (scsiq->q_status & ~(ASC_QS_READY | ASC_QS_ABORTED)));
1592 		tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
1593 		target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
1594 		if ((scsiq->cntl & ASC_QC_SG_HEAD) != 0) {
1595 			sg_q_addr = q_addr;
1596 			sg_list_qp = next_qp;
1597 			for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
1598 				sg_list_qp = AscReadLramByte(iot, ioh,
1599 					       sg_q_addr + ASC_SCSIQ_B_FWD);
1600 				sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
1601 				if (sg_list_qp == ASC_QLINK_END) {
1602 					AscSetLibErrorCode(sc, ASCQ_ERR_SG_Q_LINKS);
1603 					scsiq->d3.done_stat = ASC_QD_WITH_ERROR;
1604 					scsiq->d3.host_stat = ASC_QHSTA_D_QDONE_SG_LIST_CORRUPTED;
1605 					panic("AscIsrQDone: Corrupted SG list encountered");
1606 				}
1607 				AscWriteLramByte(iot, ioh,
1608 				sg_q_addr + ASC_SCSIQ_B_STATUS, ASC_QS_FREE);
1609 			}
1610 			n_q_used = sg_queue_cnt + 1;
1611 			ASC_PUT_VAR_DONE_QTAIL(iot, ioh, sg_list_qp);
1612 		}
1613 		if (sc->queue_full_or_busy & target_id) {
1614 			cur_target_qng = AscReadLramByte(iot, ioh,
1615 					ASC_QADR_BEG + scsiq->d2.target_ix);
1616 
1617 			if (cur_target_qng < sc->max_dvc_qng[tid_no]) {
1618 				scsi_busy = AscReadLramByte(iot, ioh, ASCV_SCSIBUSY_B);
1619 				scsi_busy &= ~target_id;
1620 				AscWriteLramByte(iot, ioh, ASCV_SCSIBUSY_B, scsi_busy);
1621 				sc->queue_full_or_busy &= ~target_id;
1622 			}
1623 		}
1624 		if (sc->cur_total_qng >= n_q_used) {
1625 			sc->cur_total_qng -= n_q_used;
1626 			if (sc->cur_dvc_qng[tid_no] != 0) {
1627 				sc->cur_dvc_qng[tid_no]--;
1628 			}
1629 		} else {
1630 			AscSetLibErrorCode(sc, ASCQ_ERR_CUR_QNG);
1631 			scsiq->d3.done_stat = ASC_QD_WITH_ERROR;
1632 			panic("AscIsrQDone: Attempting to free more queues than are active");
1633 		}
1634 
1635 		if ((scsiq->d2.ccb_ptr == 0UL) || ((scsiq->q_status & ASC_QS_ABORTED) != 0)) {
1636 			return (0x11);
1637 		} else if (scsiq->q_status == ASC_QS_DONE) {
1638 			scsiq->remain_bytes += scsiq->extra_bytes;
1639 
1640 			if (scsiq->d3.done_stat == ASC_QD_WITH_ERROR) {
1641 				if (scsiq->d3.host_stat == ASC_QHSTA_M_DATA_OVER_RUN) {
1642 					if ((scsiq->cntl & (ASC_QC_DATA_IN | ASC_QC_DATA_OUT)) == 0) {
1643 						scsiq->d3.done_stat = ASC_QD_NO_ERROR;
1644 						scsiq->d3.host_stat = ASC_QHSTA_NO_ERROR;
1645 					}
1646 				} else if (scsiq->d3.host_stat == ASC_QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
1647 					AscStopChip(iot, ioh);
1648 					ASC_SET_CHIP_CONTROL(iot, ioh, (ASC_CC_SCSI_RESET | ASC_CC_HALT));
1649 					DvcDelayNanoSecond(60000);
1650 					ASC_SET_CHIP_CONTROL(iot, ioh, ASC_CC_HALT);
1651 					ASC_SET_CHIP_STATUS(iot, ioh, ASC_CIW_CLR_SCSI_RESET_INT);
1652 					ASC_SET_CHIP_STATUS(iot, ioh, 0);
1653 					ASC_SET_CHIP_CONTROL(iot, ioh, 0);
1654 				}
1655 			}
1656 			(*asc_isr_callback) (sc, scsiq);
1657 
1658 			return (1);
1659 		} else {
1660 			AscSetLibErrorCode(sc, ASCQ_ERR_Q_STATUS);
1661 			panic("AscIsrQDone: completed scsiq with unknown status");
1662 
1663 			return (0x80);
1664 		}
1665 	}
1666 	return (0);
1667 }
1668 
1669 
1670 /*
1671  * handle all the conditions that may halt the board
1672  * waiting us to intervene
1673  */
1674 static void
1675 AscIsrChipHalted(ASC_SOFTC *sc)
1676 {
1677 	bus_space_tag_t iot = sc->sc_iot;
1678 	bus_space_handle_t ioh = sc->sc_ioh;
1679 	EXT_MSG         out_msg;
1680 	u_int16_t       int_halt_code;
1681 	u_int16_t       halt_q_addr;
1682 	u_int8_t        halt_qp;
1683 	u_int8_t        target_ix;
1684 	u_int8_t        tag_code;
1685 	u_int8_t        q_status;
1686 	u_int8_t        q_cntl;
1687 	u_int8_t        tid_no;
1688 	u_int8_t        cur_dvc_qng;
1689 	u_int8_t        asyn_sdtr;
1690 	u_int8_t        scsi_status;
1691 	u_int8_t        sdtr_data;
1692 	ASC_SCSI_BIT_ID_TYPE scsi_busy;
1693 	ASC_SCSI_BIT_ID_TYPE target_id;
1694 
1695 	int_halt_code = AscReadLramWord(iot, ioh, ASCV_HALTCODE_W);
1696 
1697 	halt_qp = AscReadLramByte(iot, ioh, ASCV_CURCDB_B);
1698 	halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
1699 	target_ix = AscReadLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_TARGET_IX);
1700 	q_cntl = AscReadLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_CNTL);
1701 	tid_no = ASC_TIX_TO_TID(target_ix);
1702 	target_id = ASC_TID_TO_TARGET_ID(tid_no);
1703 
1704 	if (sc->pci_fix_asyn_xfer & target_id) {
1705 		asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
1706 	} else {
1707 		asyn_sdtr = 0;
1708 	}
1709 
1710 	if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
1711 		if (sc->pci_fix_asyn_xfer & target_id) {
1712 			AscSetChipSDTR(iot, ioh, 0, tid_no);
1713 			sc->sdtr_data[tid_no] = 0;
1714 		}
1715 		AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0);
1716 	} else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
1717 		if (sc->pci_fix_asyn_xfer & target_id) {
1718 			AscSetChipSDTR(iot, ioh, asyn_sdtr, tid_no);
1719 			sc->sdtr_data[tid_no] = asyn_sdtr;
1720 		}
1721 		AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0);
1722 	} else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
1723 		AscHandleExtMsgIn(sc, halt_q_addr, q_cntl, target_id,
1724 				  tid_no, asyn_sdtr);
1725 		AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0);
1726 	} else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
1727 		q_cntl |= ASC_QC_REQ_SENSE;
1728 
1729 		if (sc->init_sdtr & target_id) {
1730 			sc->sdtr_done &= ~target_id;
1731 
1732 			sdtr_data = ASC_GET_MCODE_INIT_SDTR_AT_ID(iot, ioh, tid_no);
1733 			q_cntl |= ASC_QC_MSG_OUT;
1734 			AscMsgOutSDTR(sc, sc->sdtr_period_tbl[(sdtr_data >> 4) &
1735 						  (sc->max_sdtr_index - 1)],
1736 				      (sdtr_data & ASC_SYN_MAX_OFFSET));
1737 		}
1738 		AscWriteLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_CNTL, q_cntl);
1739 
1740 		tag_code = AscReadLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_TAG_CODE);
1741 		tag_code &= 0xDC;
1742 
1743 		if ((sc->pci_fix_asyn_xfer & target_id) &&
1744 		    !(sc->pci_fix_asyn_xfer_always & target_id)) {
1745 			tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT |
1746 				     ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
1747 		}
1748 		AscWriteLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_TAG_CODE, tag_code);
1749 
1750 		q_status = AscReadLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_STATUS);
1751 		q_status |= ASC_QS_READY | ASC_QS_BUSY;
1752 
1753 		AscWriteLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_STATUS, q_status);
1754 
1755 		scsi_busy = AscReadLramByte(iot, ioh, ASCV_SCSIBUSY_B);
1756 		scsi_busy &= ~target_id;
1757 		AscWriteLramByte(iot, ioh, ASCV_SCSIBUSY_B, scsi_busy);
1758 
1759 		AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0);
1760 	} else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
1761 		AscMemWordCopyFromLram(iot, ioh, ASCV_MSGOUT_BEG,
1762 			     (u_int16_t *) & out_msg, sizeof(EXT_MSG) >> 1);
1763 
1764 		if ((out_msg.msg_type == MS_EXTEND) &&
1765 		    (out_msg.msg_len == MS_SDTR_LEN) &&
1766 		    (out_msg.msg_req == MS_SDTR_CODE)) {
1767 			sc->init_sdtr &= ~target_id;
1768 			sc->sdtr_done &= ~target_id;
1769 			AscSetChipSDTR(iot, ioh, asyn_sdtr, tid_no);
1770 			sc->sdtr_data[tid_no] = asyn_sdtr;
1771 		}
1772 		q_cntl &= ~ASC_QC_MSG_OUT;
1773 		AscWriteLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_CNTL, q_cntl);
1774 		AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0);
1775 	} else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
1776 		scsi_status = AscReadLramByte(iot, ioh,
1777 				       halt_q_addr + ASC_SCSIQ_SCSI_STATUS);
1778 		cur_dvc_qng = AscReadLramByte(iot, ioh, target_ix + ASC_QADR_BEG);
1779 
1780 		if ((cur_dvc_qng > 0) && (sc->cur_dvc_qng[tid_no] > 0)) {
1781 			scsi_busy = AscReadLramByte(iot, ioh, ASCV_SCSIBUSY_B);
1782 			scsi_busy |= target_id;
1783 			AscWriteLramByte(iot, ioh, ASCV_SCSIBUSY_B, scsi_busy);
1784 			sc->queue_full_or_busy |= target_id;
1785 
1786 			if (scsi_status == SS_QUEUE_FULL) {
1787 				if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
1788 					cur_dvc_qng -= 1;
1789 					sc->max_dvc_qng[tid_no] = cur_dvc_qng;
1790 
1791 					AscWriteLramByte(iot, ioh,
1792 							 tid_no + ASCV_MAX_DVC_QNG_BEG, cur_dvc_qng);
1793 
1794 #if ASC_QUEUE_FLOW_CONTROL
1795 					if ((sc->device[tid_no] != NULL) &&
1796 					    (sc->device[tid_no]->queue_curr_depth > cur_dvc_qng)) {
1797 						sc->device[tid_no]->queue_curr_depth = cur_dvc_qng;
1798 					}
1799 #endif				/* ASC_QUEUE_FLOW_CONTROL */
1800 				}
1801 			}
1802 		}
1803 		AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0);
1804 	}
1805 	return;
1806 }
1807 
1808 
1809 static int
1810 AscWaitTixISRDone(ASC_SOFTC *sc, u_int8_t target_ix)
1811 {
1812 	u_int8_t        cur_req;
1813 	u_int8_t        tid_no;
1814 	int             i = 0;
1815 
1816 	tid_no = ASC_TIX_TO_TID(target_ix);
1817 	while (i++ < 10) {
1818 		if ((cur_req = sc->cur_dvc_qng[tid_no]) == 0)
1819 			break;
1820 
1821 		DvcSleepMilliSecond(1000L);
1822 		if (sc->cur_dvc_qng[tid_no] == cur_req)
1823 			break;
1824 	}
1825 	return (1);
1826 }
1827 
1828 static int
1829 AscWaitISRDone(ASC_SOFTC *sc)
1830 {
1831 	int             tid;
1832 
1833 	for (tid = 0; tid <= ASC_MAX_TID; tid++)
1834 		AscWaitTixISRDone(sc, ASC_TID_TO_TIX(tid));
1835 
1836 	return (1);
1837 }
1838 
1839 
1840 static u_int8_t
1841 _AscCopyLramScsiDoneQ(bus_space_tag_t iot, bus_space_handle_t ioh,
1842     u_int16_t q_addr, ASC_QDONE_INFO *scsiq, u_int32_t max_dma_count)
1843 {
1844 	u_int16_t       _val;
1845 	u_int8_t        sg_queue_cnt;
1846 
1847 	AscGetQDoneInfo(iot, ioh, q_addr + ASC_SCSIQ_DONE_INFO_BEG, scsiq);
1848 
1849 	_val = AscReadLramWord(iot, ioh, q_addr + ASC_SCSIQ_B_STATUS);
1850 	scsiq->q_status = LO_BYTE(_val);
1851 	scsiq->q_no = HI_BYTE(_val);
1852 	_val = AscReadLramWord(iot, ioh, q_addr + ASC_SCSIQ_B_CNTL);
1853 	scsiq->cntl = LO_BYTE(_val);
1854 	sg_queue_cnt = HI_BYTE(_val);
1855 	_val = AscReadLramWord(iot, ioh, q_addr + ASC_SCSIQ_B_SENSE_LEN);
1856 	scsiq->sense_len = LO_BYTE(_val);
1857 	scsiq->extra_bytes = HI_BYTE(_val);
1858 	scsiq->remain_bytes = AscReadLramWord(iot, ioh,
1859 				     q_addr + ASC_SCSIQ_DW_REMAIN_XFER_CNT);
1860 	scsiq->remain_bytes &= max_dma_count;
1861 
1862 	return (sg_queue_cnt);
1863 }
1864 
1865 
1866 static void
1867 AscGetQDoneInfo(bus_space_tag_t iot, bus_space_handle_t ioh, u_int16_t addr,
1868     ASC_QDONE_INFO *scsiq)
1869 {
1870 	u_int16_t	val;
1871 
1872 	ASC_SET_CHIP_LRAM_ADDR(iot, ioh, addr);
1873 
1874 	val = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
1875 	scsiq->d2.ccb_ptr = MAKELONG(val, ASC_GET_CHIP_LRAM_DATA(iot, ioh));
1876 	val = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
1877 	scsiq->d2.target_ix = LO_BYTE(val);
1878 	scsiq->d2.flag = HI_BYTE(val);
1879 	val = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
1880 	scsiq->d2.cdb_len = LO_BYTE(val);
1881 	scsiq->d2.tag_code = HI_BYTE(val);
1882 	scsiq->d2.vm_id = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
1883 
1884 	val = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
1885 	scsiq->d3.done_stat = LO_BYTE(val);
1886 	scsiq->d3.host_stat = HI_BYTE(val);
1887 	val = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
1888 	scsiq->d3.scsi_stat = LO_BYTE(val);
1889 	scsiq->d3.scsi_msg = HI_BYTE(val);
1890 }
1891 
1892 
1893 static void
1894 AscToggleIRQAct(bus_space_tag_t iot, bus_space_handle_t ioh)
1895 {
1896 	ASC_SET_CHIP_STATUS(iot, ioh, ASC_CIW_IRQ_ACT);
1897 	ASC_SET_CHIP_STATUS(iot, ioh, 0);
1898 }
1899 
1900 
1901 static void
1902 AscDisableInterrupt(bus_space_tag_t iot, bus_space_handle_t ioh)
1903 {
1904 	u_int16_t       cfg;
1905 
1906 	cfg = ASC_GET_CHIP_CFG_LSW(iot, ioh);
1907 	ASC_SET_CHIP_CFG_LSW(iot, ioh, cfg & (~ASC_CFG0_HOST_INT_ON));
1908 }
1909 
1910 
1911 static void
1912 AscEnableInterrupt(bus_space_tag_t iot, bus_space_handle_t ioh)
1913 {
1914 	u_int16_t       cfg;
1915 
1916 	cfg = ASC_GET_CHIP_CFG_LSW(iot, ioh);
1917 	ASC_SET_CHIP_CFG_LSW(iot, ioh, cfg | ASC_CFG0_HOST_INT_ON);
1918 }
1919 
1920 
1921 static u_int8_t
1922 AscGetChipIRQ(bus_space_tag_t iot, bus_space_handle_t ioh, u_int16_t bus_type)
1923 {
1924 	u_int16_t       cfg_lsw;
1925 	u_int8_t        chip_irq;
1926 
1927 	if (bus_type & ASC_IS_EISA) {
1928 		/*
1929 		 * cfg_lsw = AscGetEisaChipCfg(iot, ioh); chip_irq =
1930 		 * ((cfg_lsw >> 8) & 0x07) + 10; if((chip_irq == 13) ||
1931 		 * (chip_irq > 15)) return (0); return(chip_irq);
1932 		 */
1933 	}
1934 	if ((bus_type & ASC_IS_VL) != 0) {
1935 		cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh);
1936 		chip_irq = (cfg_lsw >> 2) & 0x07;
1937 		if ((chip_irq == 0) ||
1938 		    (chip_irq == 4) ||
1939 		    (chip_irq == 7)) {
1940 			return (0);
1941 		}
1942 		return (chip_irq + (ASC_MIN_IRQ_NO - 1));
1943 	}
1944 	cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh);
1945 	chip_irq = (cfg_lsw >> 2) & 0x03;
1946 	if (chip_irq == 3)
1947 		chip_irq += 2;
1948 	return (chip_irq + ASC_MIN_IRQ_NO);
1949 }
1950 
1951 
1952 static u_int8_t
1953 AscSetChipIRQ(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t irq_no,
1954     u_int16_t bus_type)
1955 {
1956 	u_int16_t       cfg_lsw;
1957 
1958 	if (bus_type & ASC_IS_VL) {
1959 		if (irq_no) {
1960 			if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO))
1961 				irq_no = 0;
1962 			else
1963 				irq_no -= ASC_MIN_IRQ_NO - 1;
1964 		}
1965 
1966 		cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh) & 0xFFE3;
1967 		cfg_lsw |= 0x0010;
1968 		ASC_SET_CHIP_CFG_LSW(iot, ioh, cfg_lsw);
1969 		AscToggleIRQAct(iot, ioh);
1970 		cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh) & 0xFFE0;
1971 		cfg_lsw |= (irq_no & 0x07) << 2;
1972 		ASC_SET_CHIP_CFG_LSW(iot, ioh, cfg_lsw);
1973 		AscToggleIRQAct(iot, ioh);
1974 
1975 		return (AscGetChipIRQ(iot, ioh, bus_type));
1976 	}
1977 	if (bus_type & ASC_IS_ISA) {
1978 		if (irq_no == 15)
1979 			irq_no -= 2;
1980 		irq_no -= ASC_MIN_IRQ_NO;
1981 		cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh) & 0xFFF3;
1982 		cfg_lsw |= (irq_no & 0x03) << 2;
1983 		ASC_SET_CHIP_CFG_LSW(iot, ioh, cfg_lsw);
1984 
1985 		return (AscGetChipIRQ(iot, ioh, bus_type));
1986 	}
1987 	return (0);
1988 }
1989 
1990 
1991 static void
1992 AscAckInterrupt(bus_space_tag_t iot, bus_space_handle_t ioh)
1993 {
1994 	u_int8_t        host_flag;
1995 	u_int8_t        risc_flag;
1996 	u_int16_t       loop;
1997 
1998 	loop = 0;
1999 	do {
2000 		risc_flag = AscReadLramByte(iot, ioh, ASCV_RISC_FLAG_B);
2001 		if (loop++ > 0x7FFF)
2002 			break;
2003 	} while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
2004 
2005 	host_flag = AscReadLramByte(iot, ioh, ASCV_HOST_FLAG_B) &
2006 		(~ASC_HOST_FLAG_ACK_INT);
2007 	AscWriteLramByte(iot, ioh, ASCV_HOST_FLAG_B,
2008 			 host_flag | ASC_HOST_FLAG_ACK_INT);
2009 	ASC_SET_CHIP_STATUS(iot, ioh, ASC_CIW_INT_ACK);
2010 
2011 	loop = 0;
2012 	while (ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_INT_PENDING) {
2013 		ASC_SET_CHIP_STATUS(iot, ioh, ASC_CIW_INT_ACK);
2014 		if (loop++ > 3)
2015 			break;
2016 	}
2017 
2018 	AscWriteLramByte(iot, ioh, ASCV_HOST_FLAG_B, host_flag);
2019 }
2020 
2021 
2022 static u_int32_t
2023 AscGetMaxDmaCount(u_int16_t bus_type)
2024 {
2025 	if (bus_type & ASC_IS_ISA)
2026 		return (ASC_MAX_ISA_DMA_COUNT);
2027 	else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
2028 		return (ASC_MAX_VL_DMA_COUNT);
2029 	return (ASC_MAX_PCI_DMA_COUNT);
2030 }
2031 
2032 
2033 static u_int16_t
2034 AscGetIsaDmaChannel(bus_space_tag_t iot, bus_space_handle_t ioh)
2035 {
2036 	u_int16_t       channel;
2037 
2038 	channel = ASC_GET_CHIP_CFG_LSW(iot, ioh) & 0x0003;
2039 	if (channel == 0x03)
2040 		return (0);
2041 	else if (channel == 0x00)
2042 		return (7);
2043 	return (channel + 4);
2044 }
2045 
2046 
2047 static u_int16_t
2048 AscSetIsaDmaChannel(bus_space_tag_t iot, bus_space_handle_t ioh,
2049     u_int16_t dma_channel)
2050 {
2051 	u_int16_t       cfg_lsw;
2052 	u_int8_t        value;
2053 
2054 	if ((dma_channel >= 5) && (dma_channel <= 7)) {
2055 		if (dma_channel == 7)
2056 			value = 0x00;
2057 		else
2058 			value = dma_channel - 4;
2059 		cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh) & 0xFFFC;
2060 		cfg_lsw |= value;
2061 		ASC_SET_CHIP_CFG_LSW(iot, ioh, cfg_lsw);
2062 		return (AscGetIsaDmaChannel(iot, ioh));
2063 	}
2064 	return (0);
2065 }
2066 
2067 
2068 static u_int8_t
2069 AscGetIsaDmaSpeed(bus_space_tag_t iot, bus_space_handle_t ioh)
2070 {
2071 	u_int8_t        speed_value;
2072 
2073 	AscSetBank(iot, ioh, 1);
2074 	speed_value = ASC_READ_CHIP_DMA_SPEED(iot, ioh);
2075 	speed_value &= 0x07;
2076 	AscSetBank(iot, ioh, 0);
2077 	return (speed_value);
2078 }
2079 
2080 
2081 static u_int8_t
2082 AscSetIsaDmaSpeed(bus_space_tag_t iot, bus_space_handle_t ioh,
2083     u_int8_t speed_value)
2084 {
2085 	speed_value &= 0x07;
2086 	AscSetBank(iot, ioh, 1);
2087 	ASC_WRITE_CHIP_DMA_SPEED(iot, ioh, speed_value);
2088 	AscSetBank(iot, ioh, 0);
2089 	return (AscGetIsaDmaSpeed(iot, ioh));
2090 }
2091 
2092 
2093 /******************************************************************************/
2094 /*                              Messages routines                             */
2095 /******************************************************************************/
2096 
2097 
2098 static void
2099 AscHandleExtMsgIn(ASC_SOFTC *sc, u_int16_t halt_q_addr, u_int8_t q_cntl,
2100     ASC_SCSI_BIT_ID_TYPE target_id, int tid_no, u_int8_t asyn_sdtr)
2101 {
2102 	bus_space_tag_t iot = sc->sc_iot;
2103 	bus_space_handle_t ioh = sc->sc_ioh;
2104 	EXT_MSG         ext_msg;
2105 	u_int8_t        sdtr_data;
2106 	int             sdtr_accept;
2107 
2108 	AscMemWordCopyFromLram(iot, ioh, ASCV_MSGIN_BEG,
2109 			     (u_int16_t *) & ext_msg, sizeof(EXT_MSG) >> 1);
2110 
2111 	if (ext_msg.msg_type == MS_EXTEND &&
2112 	    ext_msg.msg_req == MS_SDTR_CODE &&
2113 	    ext_msg.msg_len == MS_SDTR_LEN) {
2114 		sdtr_accept = TRUE;
2115 
2116 		if (ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET) {
2117 			sdtr_accept = FALSE;
2118 			ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
2119 		}
2120 		if ((ext_msg.xfer_period <
2121 		     sc->sdtr_period_tbl[sc->host_init_sdtr_index]) ||
2122 		    (ext_msg.xfer_period >
2123 		     sc->sdtr_period_tbl[sc->max_sdtr_index])) {
2124 			sdtr_accept = FALSE;
2125 			ext_msg.xfer_period = sc->sdtr_period_tbl[sc->host_init_sdtr_index];
2126 		}
2127 		if (sdtr_accept) {
2128 			sdtr_data = AscCalSDTRData(sc, ext_msg.xfer_period,
2129 						   ext_msg.req_ack_offset);
2130 			if (sdtr_data == 0xFF) {
2131 				q_cntl |= ASC_QC_MSG_OUT;
2132 				sc->init_sdtr &= ~target_id;
2133 				sc->sdtr_done &= ~target_id;
2134 				AscSetChipSDTR(iot, ioh, asyn_sdtr, tid_no);
2135 				sc->sdtr_data[tid_no] = asyn_sdtr;
2136 			}
2137 		}
2138 		if (ext_msg.req_ack_offset == 0) {
2139 			q_cntl &= ~ASC_QC_MSG_OUT;
2140 			sc->init_sdtr &= ~target_id;
2141 			sc->sdtr_done &= ~target_id;
2142 			AscSetChipSDTR(iot, ioh, asyn_sdtr, tid_no);
2143 		} else {
2144 			if (sdtr_accept && (q_cntl & ASC_QC_MSG_OUT)) {
2145 				q_cntl &= ~ASC_QC_MSG_OUT;
2146 				sc->sdtr_done |= target_id;
2147 				sc->init_sdtr |= target_id;
2148 				sc->pci_fix_asyn_xfer &= ~target_id;
2149 				sdtr_data = AscCalSDTRData(sc, ext_msg.xfer_period,
2150 						    ext_msg.req_ack_offset);
2151 				AscSetChipSDTR(iot, ioh, sdtr_data, tid_no);
2152 				sc->sdtr_data[tid_no] = sdtr_data;
2153 			} else {
2154 				q_cntl |= ASC_QC_MSG_OUT;
2155 				AscMsgOutSDTR(sc, ext_msg.xfer_period,
2156 					      ext_msg.req_ack_offset);
2157 				sc->pci_fix_asyn_xfer &= ~target_id;
2158 				sdtr_data = AscCalSDTRData(sc, ext_msg.xfer_period,
2159 						    ext_msg.req_ack_offset);
2160 				AscSetChipSDTR(iot, ioh, sdtr_data, tid_no);
2161 				sc->sdtr_data[tid_no] = sdtr_data;
2162 				sc->sdtr_done |= target_id;
2163 				sc->init_sdtr |= target_id;
2164 			}
2165 		}
2166 	} else if (ext_msg.msg_type == MS_EXTEND &&
2167 		   ext_msg.msg_req == MS_WDTR_CODE &&
2168 		   ext_msg.msg_len == MS_WDTR_LEN) {
2169 		ext_msg.wdtr_width = 0;
2170 		AscMemWordCopyToLram(iot, ioh, ASCV_MSGOUT_BEG,
2171 			     (u_int16_t *) & ext_msg, sizeof(EXT_MSG) >> 1);
2172 		q_cntl |= ASC_QC_MSG_OUT;
2173 	} else {
2174 		ext_msg.msg_type = M1_MSG_REJECT;
2175 		AscMemWordCopyToLram(iot, ioh, ASCV_MSGOUT_BEG,
2176 			     (u_int16_t *) & ext_msg, sizeof(EXT_MSG) >> 1);
2177 		q_cntl |= ASC_QC_MSG_OUT;
2178 	}
2179 
2180 	AscWriteLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_CNTL, q_cntl);
2181 }
2182 
2183 
2184 static u_int8_t
2185 AscMsgOutSDTR(ASC_SOFTC *sc, u_int8_t sdtr_period, u_int8_t sdtr_offset)
2186 {
2187 	bus_space_tag_t iot = sc->sc_iot;
2188 	bus_space_handle_t ioh = sc->sc_ioh;
2189 	EXT_MSG         sdtr_buf;
2190 	u_int8_t        sdtr_period_index;
2191 
2192 	sdtr_buf.msg_type = MS_EXTEND;
2193 	sdtr_buf.msg_len = MS_SDTR_LEN;
2194 	sdtr_buf.msg_req = MS_SDTR_CODE;
2195 	sdtr_buf.xfer_period = sdtr_period;
2196 	sdtr_offset &= ASC_SYN_MAX_OFFSET;
2197 	sdtr_buf.req_ack_offset = sdtr_offset;
2198 	if ((sdtr_period_index = AscGetSynPeriodIndex(sc, sdtr_period)) <=
2199 	    sc->max_sdtr_index) {
2200 		AscMemWordCopyToLram(iot, ioh, ASCV_MSGOUT_BEG,
2201 			    (u_int16_t *) & sdtr_buf, sizeof(EXT_MSG) >> 1);
2202 		return ((sdtr_period_index << 4) | sdtr_offset);
2203 	} else {
2204 		sdtr_buf.req_ack_offset = 0;
2205 		AscMemWordCopyToLram(iot, ioh, ASCV_MSGOUT_BEG,
2206 			    (u_int16_t *) & sdtr_buf, sizeof(EXT_MSG) >> 1);
2207 		return (0);
2208 	}
2209 }
2210 
2211 
2212 /******************************************************************************/
2213 /*                                  SDTR routines                             */
2214 /******************************************************************************/
2215 
2216 
2217 static void
2218 AscSetChipSDTR(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t sdtr_data,
2219     u_int8_t tid_no)
2220 {
2221 	AscSetChipSynRegAtID(iot, ioh, tid_no, sdtr_data);
2222 	AscWriteLramByte(iot, ioh, tid_no + ASCV_SDTR_DONE_BEG, sdtr_data);
2223 }
2224 
2225 
2226 static u_int8_t
2227 AscCalSDTRData(ASC_SOFTC *sc, u_int8_t sdtr_period, u_int8_t syn_offset)
2228 {
2229 	u_int8_t        byte;
2230 	u_int8_t        sdtr_period_ix;
2231 
2232 	sdtr_period_ix = AscGetSynPeriodIndex(sc, sdtr_period);
2233 	if (sdtr_period_ix > sc->max_sdtr_index)
2234 		return (0xFF);
2235 
2236 	byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
2237 	return (byte);
2238 }
2239 
2240 
2241 static u_int8_t
2242 AscGetSynPeriodIndex(ASC_SOFTC *sc, u_int8_t syn_time)
2243 {
2244 	u_int8_t       *period_table;
2245 	int             max_index;
2246 	int             min_index;
2247 	int             i;
2248 
2249 	period_table = sc->sdtr_period_tbl;
2250 	max_index = sc->max_sdtr_index;
2251 	min_index = sc->host_init_sdtr_index;
2252 	if ((syn_time <= period_table[max_index])) {
2253 		for (i = min_index; i < (max_index - 1); i++) {
2254 			if (syn_time <= period_table[i])
2255 				return (i);
2256 		}
2257 
2258 		return (max_index);
2259 	} else
2260 		return (max_index + 1);
2261 }
2262 
2263 
2264 /******************************************************************************/
2265 /*                                 Queue routines                             */
2266 /******************************************************************************/
2267 
2268 /*
2269  * Send a command to the board
2270  */
2271 int
2272 AscExeScsiQueue(ASC_SOFTC *sc, ASC_SCSI_Q *scsiq)
2273 {
2274 	bus_space_tag_t iot = sc->sc_iot;
2275 	bus_space_handle_t ioh = sc->sc_ioh;
2276 	ASC_SG_HEAD    *sg_head = scsiq->sg_head;
2277 	int             retval;
2278 	int             n_q_required;
2279 	int             disable_syn_offset_one_fix;
2280 	int             i;
2281 	u_int32_t       addr;
2282 	u_int16_t       sg_entry_cnt = 0;
2283 	u_int16_t       sg_entry_cnt_minus_one = 0;
2284 	u_int8_t        target_ix;
2285 	u_int8_t        tid_no;
2286 	u_int8_t        sdtr_data;
2287 	u_int8_t        extra_bytes;
2288 	u_int8_t        scsi_cmd;
2289 	u_int32_t       data_cnt;
2290 
2291 	scsiq->q1.q_no = 0;
2292 	if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0)
2293 		scsiq->q1.extra_bytes = 0;
2294 
2295 	retval = ASC_BUSY;
2296 	target_ix = scsiq->q2.target_ix;
2297 	tid_no = ASC_TIX_TO_TID(target_ix);
2298 	n_q_required = 1;
2299 
2300 	if (scsiq->cdbptr[0] == SCSICMD_RequestSense)
2301 		if ((sc->init_sdtr & scsiq->q1.target_id) != 0) {
2302 			sc->sdtr_done &= ~scsiq->q1.target_id;
2303 			sdtr_data = ASC_GET_MCODE_INIT_SDTR_AT_ID(iot, ioh, tid_no);
2304 			AscMsgOutSDTR(sc, sc->sdtr_period_tbl[(sdtr_data >> 4) &
2305 						  (sc->max_sdtr_index - 1)],
2306 				      sdtr_data & ASC_SYN_MAX_OFFSET);
2307 			scsiq->q1.cntl |= (ASC_QC_MSG_OUT | ASC_QC_URGENT);
2308 		}
2309 	/*
2310 	 * if there is just one segment into S/G list then
2311 	 * map it as it was a single request, filling
2312 	 * data_addr and data_cnt of ASC_SCSIQ structure.
2313 	 */
2314 	if ((scsiq->q1.cntl & ASC_QC_SG_HEAD) != 0) {
2315 		sg_entry_cnt = sg_head->entry_cnt;
2316 
2317 		if (sg_entry_cnt < 1)
2318 			panic("AscExeScsiQueue: Queue with QC_SG_HEAD set but %d segs.",
2319 			      sg_entry_cnt);
2320 
2321 		if (sg_entry_cnt > ASC_MAX_SG_LIST)
2322 			panic("AscExeScsiQueue: Queue with too many segs.");
2323 
2324 		if (sg_entry_cnt == 1) {
2325 			scsiq->q1.data_addr = sg_head->sg_list[0].addr;
2326 			scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
2327 			scsiq->q1.cntl &= ~(ASC_QC_SG_HEAD | ASC_QC_SG_SWAP_QUEUE);
2328 		}
2329 		sg_entry_cnt_minus_one = sg_entry_cnt - 1;
2330 	}
2331 	scsi_cmd = scsiq->cdbptr[0];
2332 	disable_syn_offset_one_fix = FALSE;
2333 	if ((sc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
2334 	    !(sc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
2335 		if (scsiq->q1.cntl & ASC_QC_SG_HEAD) {
2336 			data_cnt = 0;
2337 			for (i = 0; i < sg_entry_cnt; i++)
2338 				data_cnt += sg_head->sg_list[i].bytes;
2339 		} else {
2340 			data_cnt = scsiq->q1.data_cnt;
2341 		}
2342 
2343 		if (data_cnt != 0ul) {
2344 			if (data_cnt < 512ul) {
2345 				disable_syn_offset_one_fix = TRUE;
2346 			} else {
2347 				if (scsi_cmd == SCSICMD_Inquiry ||
2348 				    scsi_cmd == SCSICMD_RequestSense ||
2349 				    scsi_cmd == SCSICMD_ReadCapacity ||
2350 				    scsi_cmd == SCSICMD_ReadTOC ||
2351 				    scsi_cmd == SCSICMD_ModeSelect6 ||
2352 				    scsi_cmd == SCSICMD_ModeSense6 ||
2353 				    scsi_cmd == SCSICMD_ModeSelect10 ||
2354 				    scsi_cmd == SCSICMD_ModeSense10) {
2355 					disable_syn_offset_one_fix = TRUE;
2356 				}
2357 			}
2358 		}
2359 	}
2360 	if (disable_syn_offset_one_fix) {
2361 		scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
2362 		scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
2363 				       ASC_TAG_FLAG_DISABLE_DISCONNECT);
2364 	} else {
2365 		scsiq->q2.tag_code &= 0x23;
2366 	}
2367 
2368 	if ((scsiq->q1.cntl & ASC_QC_SG_HEAD) != 0) {
2369 		if (sc->bug_fix_cntl) {
2370 			if (sc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
2371 				if ((scsi_cmd == SCSICMD_Read6) || (scsi_cmd == SCSICMD_Read10)) {
2372 					addr = sg_head->sg_list[sg_entry_cnt_minus_one].addr +
2373 						sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
2374 					extra_bytes = addr & 0x0003;
2375 					if ((extra_bytes != 0) &&
2376 					    ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0)) {
2377 						scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
2378 						scsiq->q1.extra_bytes = extra_bytes;
2379 						sg_head->sg_list[sg_entry_cnt_minus_one].bytes -=
2380 							extra_bytes;
2381 					}
2382 				}
2383 			}
2384 		}
2385 		sg_head->entry_to_copy = sg_head->entry_cnt;
2386 		n_q_required = AscSgListToQueue(sg_entry_cnt);
2387 		if ((AscGetNumOfFreeQueue(sc, target_ix, n_q_required) >= n_q_required)
2388 		    || ((scsiq->q1.cntl & ASC_QC_URGENT) != 0)) {
2389 			retval = AscSendScsiQueue(sc, scsiq, n_q_required);
2390 		}
2391 	} else {
2392 		if (sc->bug_fix_cntl) {
2393 			if (sc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
2394 				if ((scsi_cmd == SCSICMD_Read6) || (scsi_cmd == SCSICMD_Read10)) {
2395 					addr = scsiq->q1.data_addr + scsiq->q1.data_cnt;
2396 					extra_bytes = addr & 0x0003;
2397 					if ((extra_bytes != 0) &&
2398 					    ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0)) {
2399 						if ((scsiq->q1.data_cnt & 0x01FF) == 0) {
2400 							scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
2401 							scsiq->q1.data_cnt -= extra_bytes;
2402 							scsiq->q1.extra_bytes = extra_bytes;
2403 						}
2404 					}
2405 				}
2406 			}
2407 		}
2408 		n_q_required = 1;
2409 		if ((AscGetNumOfFreeQueue(sc, target_ix, 1) >= 1) ||
2410 		    ((scsiq->q1.cntl & ASC_QC_URGENT) != 0)) {
2411 			retval = AscSendScsiQueue(sc, scsiq, n_q_required);
2412 		}
2413 	}
2414 
2415 	return (retval);
2416 }
2417 
2418 
2419 static int
2420 AscSendScsiQueue(ASC_SOFTC *sc, ASC_SCSI_Q *scsiq, u_int8_t n_q_required)
2421 {
2422 	bus_space_tag_t iot = sc->sc_iot;
2423 	bus_space_handle_t ioh = sc->sc_ioh;
2424 	u_int8_t        free_q_head;
2425 	u_int8_t        next_qp;
2426 	u_int8_t        tid_no;
2427 	u_int8_t        target_ix;
2428 	int             retval;
2429 
2430 	target_ix = scsiq->q2.target_ix;
2431 	tid_no = ASC_TIX_TO_TID(target_ix);
2432 	retval = ASC_BUSY;
2433 	free_q_head = ASC_GET_VAR_FREE_QHEAD(iot, ioh);
2434 
2435 	if ((next_qp = AscAllocMultipleFreeQueue(iot, ioh, free_q_head, n_q_required))
2436 	    != ASC_QLINK_END) {
2437 		if (n_q_required > 1) {
2438 			sc->last_q_shortage = 0;
2439 			scsiq->sg_head->queue_cnt = n_q_required - 1;
2440 		}
2441 		scsiq->q1.q_no = free_q_head;
2442 
2443 		if ((retval = AscPutReadySgListQueue(sc, scsiq, free_q_head)) == ASC_NOERROR) {
2444 			ASC_PUT_VAR_FREE_QHEAD(iot, ioh, next_qp);
2445 			sc->cur_total_qng += n_q_required;
2446 			sc->cur_dvc_qng[tid_no]++;
2447 		}
2448 	}
2449 	return (retval);
2450 }
2451 
2452 
2453 static int
2454 AscPutReadySgListQueue(ASC_SOFTC *sc, ASC_SCSI_Q *scsiq, u_int8_t q_no)
2455 {
2456 	bus_space_tag_t iot = sc->sc_iot;
2457 	bus_space_handle_t ioh = sc->sc_ioh;
2458 	int             retval;
2459 	int             i;
2460 	ASC_SG_HEAD    *sg_head;
2461 	ASC_SG_LIST_Q   scsi_sg_q;
2462 	u_int32_t       saved_data_addr;
2463 	u_int32_t       saved_data_cnt;
2464 	u_int16_t       sg_list_dwords;
2465 	u_int16_t       sg_index;
2466 	u_int16_t       sg_entry_cnt;
2467 	u_int16_t       q_addr;
2468 	u_int8_t        next_qp;
2469 
2470 	saved_data_addr = scsiq->q1.data_addr;
2471 	saved_data_cnt = scsiq->q1.data_cnt;
2472 
2473 	if ((sg_head = scsiq->sg_head) != 0) {
2474 		scsiq->q1.data_addr = sg_head->sg_list[0].addr;
2475 		scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
2476 		sg_entry_cnt = sg_head->entry_cnt - 1;
2477 		if (sg_entry_cnt != 0) {
2478 			q_addr = ASC_QNO_TO_QADDR(q_no);
2479 			sg_index = 1;
2480 			scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
2481 			scsi_sg_q.sg_head_qp = q_no;
2482 			scsi_sg_q.cntl = ASC_QCSG_SG_XFER_LIST;
2483 
2484 			for (i = 0; i < sg_head->queue_cnt; i++) {
2485 				scsi_sg_q.seq_no = i + 1;
2486 				if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
2487 					sg_list_dwords = ASC_SG_LIST_PER_Q * 2;
2488 					sg_entry_cnt -= ASC_SG_LIST_PER_Q;
2489 					if (i == 0) {
2490 						scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
2491 						scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
2492 					} else {
2493 						scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
2494 						scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
2495 					}
2496 				} else {
2497 					scsi_sg_q.cntl |= ASC_QCSG_SG_XFER_END;
2498 					sg_list_dwords = sg_entry_cnt << 1;
2499 					if (i == 0) {
2500 						scsi_sg_q.sg_list_cnt = sg_entry_cnt;
2501 						scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
2502 					} else {
2503 						scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
2504 						scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
2505 					}
2506 
2507 					sg_entry_cnt = 0;
2508 				}
2509 
2510 				next_qp = AscReadLramByte(iot, ioh, q_addr + ASC_SCSIQ_B_FWD);
2511 				scsi_sg_q.q_no = next_qp;
2512 				q_addr = ASC_QNO_TO_QADDR(next_qp);
2513 
2514 				/*
2515 				 * Tell the board how many entries are in the S/G list
2516 				 */
2517 				AscMemWordCopyToLram(iot, ioh, q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
2518 							(u_int16_t *) & scsi_sg_q,
2519 							sizeof(ASC_SG_LIST_Q) >> 1);
2520 				/*
2521 				 * Tell the board the addresses of the S/G list segments
2522 				 */
2523 				AscMemDWordCopyToLram(iot, ioh, q_addr + ASC_SGQ_LIST_BEG,
2524 							(u_int32_t *) & sg_head->sg_list[sg_index],
2525 							sg_list_dwords);
2526 				sg_index += ASC_SG_LIST_PER_Q;
2527 			}
2528 		}
2529 	}
2530 	retval = AscPutReadyQueue(sc, scsiq, q_no);
2531 	scsiq->q1.data_addr = saved_data_addr;
2532 	scsiq->q1.data_cnt = saved_data_cnt;
2533 	return (retval);
2534 }
2535 
2536 
2537 static int
2538 AscPutReadyQueue(ASC_SOFTC *sc, ASC_SCSI_Q *scsiq, u_int8_t q_no)
2539 {
2540 	bus_space_tag_t iot = sc->sc_iot;
2541 	bus_space_handle_t ioh = sc->sc_ioh;
2542 	u_int16_t       q_addr;
2543 	u_int8_t        tid_no;
2544 	u_int8_t        sdtr_data;
2545 	u_int8_t        syn_period_ix;
2546 	u_int8_t        syn_offset;
2547 
2548 	if (((sc->init_sdtr & scsiq->q1.target_id) != 0) &&
2549 	    ((sc->sdtr_done & scsiq->q1.target_id) == 0)) {
2550 		tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
2551 		sdtr_data = ASC_GET_MCODE_INIT_SDTR_AT_ID(iot, ioh, tid_no);
2552 		syn_period_ix = (sdtr_data >> 4) & (sc->max_sdtr_index - 1);
2553 		syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
2554 		AscMsgOutSDTR(sc, sc->sdtr_period_tbl[syn_period_ix], syn_offset);
2555 		scsiq->q1.cntl |= ASC_QC_MSG_OUT;
2556 	}
2557 	q_addr = ASC_QNO_TO_QADDR(q_no);
2558 
2559 	if ((scsiq->q1.target_id & sc->use_tagged_qng) == 0) {
2560 		scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
2561 	}
2562 	scsiq->q1.status = ASC_QS_FREE;
2563 	AscMemWordCopyToLram(iot, ioh, q_addr + ASC_SCSIQ_CDB_BEG,
2564 		       (u_int16_t *) scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
2565 
2566 	AscPutSCSIQ(iot, ioh, q_addr + ASC_SCSIQ_CPY_BEG, scsiq);
2567 
2568 	/*
2569 	 * Let's start the command
2570 	 */
2571 	AscWriteLramWord(iot, ioh, q_addr + ASC_SCSIQ_B_STATUS,
2572 			 (scsiq->q1.q_no << 8) | ASC_QS_READY);
2573 
2574 	return (ASC_NOERROR);
2575 }
2576 
2577 
2578 static void
2579 AscPutSCSIQ(bus_space_tag_t iot, bus_space_handle_t ioh, u_int16_t addr,
2580     ASC_SCSI_Q *scsiq)
2581 {
2582 	u_int16_t	val;
2583 
2584 	ASC_SET_CHIP_LRAM_ADDR(iot, ioh, addr);
2585 
2586 	/* ASC_SCSIQ_1 */
2587 	val = MAKEWORD(scsiq->q1.cntl, scsiq->q1.sg_queue_cnt);
2588 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
2589 	val = MAKEWORD(scsiq->q1.target_id, scsiq->q1.target_lun);
2590 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
2591 	val = LO_WORD(scsiq->q1.data_addr);
2592 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
2593 	val = HI_WORD(scsiq->q1.data_addr);
2594 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
2595 	val = LO_WORD(scsiq->q1.data_cnt);
2596 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
2597 	val = HI_WORD(scsiq->q1.data_cnt);
2598 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
2599 	val = LO_WORD(scsiq->q1.sense_addr);
2600 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
2601 	val = HI_WORD(scsiq->q1.sense_addr);
2602 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
2603 	val = MAKEWORD(scsiq->q1.sense_len, scsiq->q1.extra_bytes);
2604 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
2605 
2606 	/* ASC_SCSIQ_2 */
2607 	val = LO_WORD(scsiq->q2.ccb_ptr);
2608 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
2609 	val = HI_WORD(scsiq->q2.ccb_ptr);
2610 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
2611 	val = MAKEWORD(scsiq->q2.target_ix, scsiq->q2.flag);
2612 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
2613 	val = MAKEWORD(scsiq->q2.cdb_len, scsiq->q2.tag_code);
2614 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
2615 	ASC_SET_CHIP_LRAM_DATA(iot, ioh, scsiq->q2.vm_id);
2616 }
2617 
2618 
2619 static int
2620 AscSgListToQueue(int sg_list)
2621 {
2622 	int             n_sg_list_qs;
2623 
2624 	n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
2625 	if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
2626 		n_sg_list_qs++;
2627 
2628 	return (n_sg_list_qs + 1);
2629 }
2630 
2631 
2632 static u_int
2633 AscGetNumOfFreeQueue(ASC_SOFTC *sc, u_int8_t target_ix, u_int8_t n_qs)
2634 {
2635 	u_int           cur_used_qs;
2636 	u_int           cur_free_qs;
2637 
2638 	if (n_qs == 1) {
2639 		cur_used_qs = sc->cur_total_qng +
2640 			sc->last_q_shortage +
2641 			ASC_MIN_FREE_Q;
2642 	} else {
2643 		cur_used_qs = sc->cur_total_qng + ASC_MIN_FREE_Q;
2644 	}
2645 
2646 	if ((cur_used_qs + n_qs) <= sc->max_total_qng) {
2647 		cur_free_qs = sc->max_total_qng - cur_used_qs;
2648 		return (cur_free_qs);
2649 	}
2650 	if (n_qs > 1)
2651 		if ((n_qs > sc->last_q_shortage) &&
2652 		    (n_qs <= (sc->max_total_qng - ASC_MIN_FREE_Q))) {
2653 			sc->last_q_shortage = n_qs;
2654 		}
2655 	return (0);
2656 }
2657 
2658 
2659 static u_int8_t
2660 AscAllocFreeQueue(bus_space_tag_t iot, bus_space_handle_t ioh,
2661     u_int8_t free_q_head)
2662 {
2663 	u_int16_t       q_addr;
2664 	u_int8_t        next_qp;
2665 	u_int8_t        q_status;
2666 
2667 	q_addr = ASC_QNO_TO_QADDR(free_q_head);
2668 	q_status = AscReadLramByte(iot, ioh, q_addr + ASC_SCSIQ_B_STATUS);
2669 	next_qp = AscReadLramByte(iot, ioh, q_addr + ASC_SCSIQ_B_FWD);
2670 	if (((q_status & ASC_QS_READY) == 0) && (next_qp != ASC_QLINK_END))
2671 		return (next_qp);
2672 
2673 	return (ASC_QLINK_END);
2674 }
2675 
2676 
2677 static u_int8_t
2678 AscAllocMultipleFreeQueue(bus_space_tag_t iot, bus_space_handle_t ioh,
2679     u_int8_t free_q_head, u_int8_t n_free_q)
2680 {
2681 	u_int8_t        i;
2682 
2683 	for (i = 0; i < n_free_q; i++) {
2684 		free_q_head = AscAllocFreeQueue(iot, ioh, free_q_head);
2685 		if (free_q_head == ASC_QLINK_END)
2686 			break;
2687 	}
2688 
2689 	return (free_q_head);
2690 }
2691 
2692 
2693 static int
2694 AscStopQueueExe(bus_space_tag_t iot, bus_space_handle_t ioh)
2695 {
2696 	int             count = 0;
2697 
2698 	if (AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B) == 0) {
2699 		AscWriteLramByte(iot, ioh, ASCV_STOP_CODE_B, ASC_STOP_REQ_RISC_STOP);
2700 		do {
2701 			if (AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B) &
2702 			    ASC_STOP_ACK_RISC_STOP)
2703 				return (1);
2704 
2705 			DvcSleepMilliSecond(100);
2706 		} while (count++ < 20);
2707 	}
2708 	return (0);
2709 }
2710 
2711 
2712 static void
2713 AscStartQueueExe(bus_space_tag_t iot, bus_space_handle_t ioh)
2714 {
2715 	if (AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B) != 0)
2716 		AscWriteLramByte(iot, ioh, ASCV_STOP_CODE_B, 0);
2717 }
2718 
2719 
2720 static void
2721 AscCleanUpBusyQueue(bus_space_tag_t iot, bus_space_handle_t ioh)
2722 {
2723 	int             count = 0;
2724 	u_int8_t        stop_code;
2725 
2726 	if (AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B) != 0) {
2727 		AscWriteLramByte(iot, ioh, ASCV_STOP_CODE_B, ASC_STOP_CLEAN_UP_BUSY_Q);
2728 		do {
2729 			stop_code = AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B);
2730 			if ((stop_code & ASC_STOP_CLEAN_UP_BUSY_Q) == 0)
2731 				break;
2732 
2733 			DvcSleepMilliSecond(100);
2734 		} while (count++ < 20);
2735 	}
2736 }
2737 
2738 
2739 static int
2740 _AscWaitQDone(bus_space_tag_t iot, bus_space_handle_t ioh, ASC_SCSI_Q *scsiq)
2741 {
2742 	u_int16_t       q_addr;
2743 	u_int8_t        q_status;
2744 	int             count = 0;
2745 
2746 	while (scsiq->q1.q_no == 0);
2747 
2748 	q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no);
2749 	do {
2750 		q_status = AscReadLramByte(iot, ioh, q_addr + ASC_SCSIQ_B_STATUS);
2751 		DvcSleepMilliSecond(100L);
2752 		if (count++ > 30)
2753 			return (0);
2754 
2755 	} while ((q_status & ASC_QS_READY) != 0);
2756 
2757 	return (1);
2758 }
2759 
2760 
2761 static int
2762 AscCleanUpDiscQueue(bus_space_tag_t iot, bus_space_handle_t ioh)
2763 {
2764 	int             count;
2765 	u_int8_t        stop_code;
2766 
2767 	count = 0;
2768 	if (AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B) != 0) {
2769 		AscWriteLramByte(iot, ioh, ASCV_STOP_CODE_B, ASC_STOP_CLEAN_UP_DISC_Q);
2770 		do {
2771 			stop_code = AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B);
2772 			if ((stop_code & ASC_STOP_CLEAN_UP_DISC_Q) == 0)
2773 				break;
2774 
2775 			DvcSleepMilliSecond(100);
2776 		} while (count++ < 20);
2777 	}
2778 	return (1);
2779 }
2780 
2781 
2782 /******************************************************************************/
2783 /*                           Abort and Reset CCB routines                     */
2784 /******************************************************************************/
2785 
2786 
2787 int
2788 AscAbortCCB(ASC_SOFTC *sc, u_int32_t ccb)
2789 {
2790 	bus_space_tag_t iot = sc->sc_iot;
2791 	bus_space_handle_t ioh = sc->sc_ioh;
2792 	int             retval;
2793 	ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
2794 
2795 	retval = -1;
2796 	saved_unit_not_ready = sc->unit_not_ready;
2797 	sc->unit_not_ready = 0xFF;
2798 	AscWaitISRDone(sc);
2799 	if (AscStopQueueExe(iot, ioh) == 1) {
2800 		if (AscRiscHaltedAbortCCB(sc, ccb) == 1) {
2801 			retval = 1;
2802 			AscCleanUpBusyQueue(iot, ioh);
2803 			AscStartQueueExe(iot, ioh);
2804 		} else {
2805 			retval = 0;
2806 			AscStartQueueExe(iot, ioh);
2807 		}
2808 	}
2809 	sc->unit_not_ready = saved_unit_not_ready;
2810 
2811 	return (retval);
2812 }
2813 
2814 
2815 static int
2816 AscRiscHaltedAbortCCB(ASC_SOFTC *sc, u_int32_t ccb)
2817 {
2818 	bus_space_tag_t iot = sc->sc_iot;
2819 	bus_space_handle_t ioh = sc->sc_ioh;
2820 	u_int16_t       q_addr;
2821 	u_int8_t        q_no;
2822 	ASC_QDONE_INFO  scsiq_buf;
2823 	ASC_QDONE_INFO *scsiq;
2824 	ASC_ISR_CALLBACK asc_isr_callback;
2825 	int             last_int_level;
2826 
2827 	asc_isr_callback = (ASC_ISR_CALLBACK) sc->isr_callback;
2828 	last_int_level = DvcEnterCritical();
2829 	scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
2830 
2831 	for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= sc->max_total_qng; q_no++) {
2832 		q_addr = ASC_QNO_TO_QADDR(q_no);
2833 		scsiq->d2.ccb_ptr = AscReadLramDWord(iot, ioh,
2834 					       q_addr + ASC_SCSIQ_D_CCBPTR);
2835 		if (scsiq->d2.ccb_ptr == ccb) {
2836 			_AscCopyLramScsiDoneQ(iot, ioh, q_addr, scsiq, sc->max_dma_count);
2837 			if (((scsiq->q_status & ASC_QS_READY) != 0)
2838 			    && ((scsiq->q_status & ASC_QS_ABORTED) == 0)
2839 			  && ((scsiq->cntl & ASC_QCSG_SG_XFER_LIST) == 0)) {
2840 				scsiq->q_status |= ASC_QS_ABORTED;
2841 				scsiq->d3.done_stat = ASC_QD_ABORTED_BY_HOST;
2842 				AscWriteLramDWord(iot, ioh, q_addr + ASC_SCSIQ_D_CCBPTR, 0L);
2843 				AscWriteLramByte(iot, ioh, q_addr + ASC_SCSIQ_B_STATUS,
2844 						 scsiq->q_status);
2845 				(*asc_isr_callback) (sc, scsiq);
2846 				DvcLeaveCritical(last_int_level);
2847 				return (1);
2848 			}
2849 		}
2850 	}
2851 
2852 	DvcLeaveCritical(last_int_level);
2853 	return (0);
2854 }
2855 
2856 
2857 static int
2858 AscRiscHaltedAbortTIX(ASC_SOFTC *sc, u_int8_t target_ix)
2859 {
2860 	bus_space_tag_t iot = sc->sc_iot;
2861 	bus_space_handle_t ioh = sc->sc_ioh;
2862 	u_int16_t       q_addr;
2863 	u_int8_t        q_no;
2864 	ASC_QDONE_INFO  scsiq_buf;
2865 	ASC_QDONE_INFO *scsiq;
2866 	ASC_ISR_CALLBACK asc_isr_callback;
2867 	int             last_int_level;
2868 
2869 	asc_isr_callback = (ASC_ISR_CALLBACK) sc->isr_callback;
2870 	last_int_level = DvcEnterCritical();
2871 	scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
2872 	for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= sc->max_total_qng; q_no++) {
2873 		q_addr = ASC_QNO_TO_QADDR(q_no);
2874 		_AscCopyLramScsiDoneQ(iot, ioh, q_addr, scsiq, sc->max_dma_count);
2875 		if (((scsiq->q_status & ASC_QS_READY) != 0) &&
2876 		    ((scsiq->q_status & ASC_QS_ABORTED) == 0) &&
2877 		    ((scsiq->cntl & ASC_QCSG_SG_XFER_LIST) == 0)) {
2878 			if (scsiq->d2.target_ix == target_ix) {
2879 				scsiq->q_status |= ASC_QS_ABORTED;
2880 				scsiq->d3.done_stat = ASC_QD_ABORTED_BY_HOST;
2881 				AscWriteLramDWord(iot, ioh, q_addr + ASC_SCSIQ_D_CCBPTR, 0L);
2882 				AscWriteLramByte(iot, ioh, q_addr + ASC_SCSIQ_B_STATUS,
2883 						 scsiq->q_status);
2884 				(*asc_isr_callback) (sc, scsiq);
2885 			}
2886 		}
2887 	}
2888 	DvcLeaveCritical(last_int_level);
2889 	return (1);
2890 }
2891 
2892 
2893 /*
2894  * AscResetDevice calls _AscWaitQDone which requires interrupt enabled,
2895  * so we cannot use this function with the actual NetBSD SCSI layer
2896  * because at boot time interrupts are disabled.
2897  */
2898 int
2899 AscResetDevice(ASC_SOFTC *sc, u_char target_ix)
2900 {
2901 	bus_space_tag_t iot = sc->sc_iot;
2902 	bus_space_handle_t ioh = sc->sc_ioh;
2903 	int             retval;
2904 	u_int8_t        tid_no;
2905 	ASC_SCSI_BIT_ID_TYPE target_id;
2906 	int             i;
2907 	ASC_SCSI_REQ_Q  scsiq_buf;
2908 	ASC_SCSI_REQ_Q *scsiq;
2909 	u_int8_t       *buf;
2910 	ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
2911 
2912 
2913 	tid_no = ASC_TIX_TO_TID(target_ix);
2914 	target_id = ASC_TID_TO_TARGET_ID(tid_no);
2915 	saved_unit_not_ready = sc->unit_not_ready;
2916 	sc->unit_not_ready = target_id;
2917 	retval = ASC_ERROR;
2918 
2919 	AscWaitTixISRDone(sc, target_ix);
2920 
2921 	if (AscStopQueueExe(iot, ioh) == 1) {
2922 		if (AscRiscHaltedAbortTIX(sc, target_ix) == 1) {
2923 			AscCleanUpBusyQueue(iot, ioh);
2924 			AscStartQueueExe(iot, ioh);
2925 			AscWaitTixISRDone(sc, target_ix);
2926 			retval = ASC_NOERROR;
2927 			scsiq = (ASC_SCSI_REQ_Q *) & scsiq_buf;
2928 			buf = (u_char *) & scsiq_buf;
2929 			for (i = 0; i < sizeof(ASC_SCSI_REQ_Q); i++)
2930 				*buf++ = 0x00;
2931 			scsiq->q1.status = (u_char) ASC_QS_READY;
2932 			scsiq->q2.cdb_len = 6;
2933 			scsiq->q2.tag_code = M2_QTAG_MSG_SIMPLE;
2934 			scsiq->q1.target_id = target_id;
2935 			scsiq->q2.target_ix = ASC_TIDLUN_TO_IX(tid_no, 0);
2936 			scsiq->cdbptr = (u_int8_t *) scsiq->cdb;
2937 			scsiq->q1.cntl = ASC_QC_NO_CALLBACK | ASC_QC_MSG_OUT | ASC_QC_URGENT;
2938 			AscWriteLramByte(iot, ioh, ASCV_MSGOUT_BEG, M1_BUS_DVC_RESET);
2939 			sc->unit_not_ready &= ~target_id;
2940 			sc->sdtr_done |= target_id;
2941 			if (AscExeScsiQueue(sc, (ASC_SCSI_Q *) scsiq) == ASC_NOERROR) {
2942 				sc->unit_not_ready = target_id;
2943 				DvcSleepMilliSecond(1000);
2944 				_AscWaitQDone(iot, ioh, (ASC_SCSI_Q *) scsiq);
2945 				if (AscStopQueueExe(iot, ioh) == ASC_NOERROR) {
2946 					AscCleanUpDiscQueue(iot, ioh);
2947 					AscStartQueueExe(iot, ioh);
2948 					if (sc->pci_fix_asyn_xfer & target_id)
2949 						AscSetRunChipSynRegAtID(iot, ioh, tid_no,
2950 								ASYN_SDTR_DATA_FIX_PCI_REV_AB);
2951 					AscWaitTixISRDone(sc, target_ix);
2952 				}
2953 			} else
2954 				retval = ASC_BUSY;
2955 			sc->sdtr_done &= ~target_id;
2956 		} else {
2957 			retval = ASC_ERROR;
2958 			AscStartQueueExe(iot, ioh);
2959 		}
2960 	}
2961 	sc->unit_not_ready = saved_unit_not_ready;
2962 	return (retval);
2963 }
2964 
2965 
2966 int
2967 AscResetBus(ASC_SOFTC *sc)
2968 {
2969 	bus_space_tag_t iot = sc->sc_iot;
2970 	bus_space_handle_t ioh = sc->sc_ioh;
2971 	int             retval;
2972 	int             i;
2973 
2974 	sc->unit_not_ready = 0xFF;
2975 	retval = ASC_NOERROR;
2976 
2977 	AscWaitISRDone(sc);
2978 	AscStopQueueExe(iot, ioh);
2979 	sc->sdtr_done = 0;
2980 	AscResetChipAndScsiBus(iot, ioh);
2981 	DvcSleepMilliSecond((u_long) ((u_int16_t) sc->scsi_reset_wait * 1000));
2982 	AscReInitLram(sc);
2983 	for (i = 0; i <= ASC_MAX_TID; i++) {
2984 		sc->cur_dvc_qng[i] = 0;
2985 		if (sc->pci_fix_asyn_xfer & (ASC_SCSI_BIT_ID_TYPE) (0x01 << i))
2986 			AscSetChipSynRegAtID(iot, ioh, i, ASYN_SDTR_DATA_FIX_PCI_REV_AB);
2987 	}
2988 
2989 	ASC_SET_PC_ADDR(iot, ioh, ASC_MCODE_START_ADDR);
2990 	if (ASC_GET_PC_ADDR(iot, ioh) != ASC_MCODE_START_ADDR)
2991 		retval = ASC_ERROR;
2992 
2993 	if (AscStartChip(iot, ioh) == 0)
2994 		retval = ASC_ERROR;
2995 
2996 	AscStartQueueExe(iot, ioh);
2997 	sc->unit_not_ready = 0;
2998 	sc->queue_full_or_busy = 0;
2999 	return (retval);
3000 }
3001 
3002 
3003 /******************************************************************************/
3004 /*                            Error Handling routines                         */
3005 /******************************************************************************/
3006 
3007 
3008 static int
3009 AscSetLibErrorCode(ASC_SOFTC *sc, u_int16_t err_code)
3010 {
3011 	/*
3012 	 * if(sc->err_code == 0) { sc->err_code = err_code;
3013 	 */ AscWriteLramWord(sc->sc_iot, sc->sc_ioh, ASCV_ASCDVC_ERR_CODE_W,
3014 			       err_code);
3015 	/*
3016 	 * }
3017 	 */
3018 	return (err_code);
3019 }
3020 
3021 
3022 /******************************************************************************/
3023 /*                            Handle bugged borads routines                   */
3024 /******************************************************************************/
3025 
3026 
3027 void
3028 AscInquiryHandling(ASC_SOFTC *sc, u_int8_t tid_no, ASC_SCSI_INQUIRY *inq)
3029 {
3030 	bus_space_tag_t iot = sc->sc_iot;
3031 	bus_space_handle_t ioh = sc->sc_ioh;
3032 	ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
3033 	ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
3034 
3035 	orig_init_sdtr = sc->init_sdtr;
3036 	orig_use_tagged_qng = sc->use_tagged_qng;
3037 
3038 	sc->init_sdtr &= ~tid_bit;
3039 	sc->can_tagged_qng &= ~tid_bit;
3040 	sc->use_tagged_qng &= ~tid_bit;
3041 
3042 	if (inq->byte3.rsp_data_fmt >= 2 || inq->byte2.ansi_apr_ver >= 2) {
3043 		if ((sc->sdtr_enable & tid_bit) && inq->byte7.Sync)
3044 			sc->init_sdtr |= tid_bit;
3045 
3046 		if ((sc->cmd_qng_enabled & tid_bit) && inq->byte7.CmdQue)
3047 			if (AscTagQueuingSafe(inq)) {
3048 				sc->use_tagged_qng |= tid_bit;
3049 				sc->can_tagged_qng |= tid_bit;
3050 			}
3051 	}
3052 	if (orig_use_tagged_qng != sc->use_tagged_qng) {
3053 		AscWriteLramByte(iot, ioh, ASCV_DISC_ENABLE_B,
3054 				 sc->disc_enable);
3055 		AscWriteLramByte(iot, ioh, ASCV_USE_TAGGED_QNG_B,
3056 				 sc->use_tagged_qng);
3057 		AscWriteLramByte(iot, ioh, ASCV_CAN_TAGGED_QNG_B,
3058 				 sc->can_tagged_qng);
3059 
3060 		sc->max_dvc_qng[tid_no] =
3061 			sc->max_tag_qng[tid_no];
3062 		AscWriteLramByte(iot, ioh, ASCV_MAX_DVC_QNG_BEG + tid_no,
3063 				 sc->max_dvc_qng[tid_no]);
3064 	}
3065 	if (orig_init_sdtr != sc->init_sdtr)
3066 		AscAsyncFix(sc, tid_no, inq);
3067 }
3068 
3069 
3070 static int
3071 AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
3072 {
3073 	if ((inq->add_len >= 32) &&
3074 	    (AscCompareString(inq->vendor_id, "QUANTUM XP34301", 15) == 0) &&
3075 	    (AscCompareString(inq->product_rev_level, "1071", 4) == 0)) {
3076 		return 0;
3077 	}
3078 	return 1;
3079 }
3080 
3081 
3082 static void
3083 AscAsyncFix(ASC_SOFTC *sc, u_int8_t tid_no, ASC_SCSI_INQUIRY *inq)
3084 {
3085 	u_int8_t        dvc_type;
3086 	ASC_SCSI_BIT_ID_TYPE tid_bits;
3087 
3088 	dvc_type = inq->byte0.peri_dvc_type;
3089 	tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
3090 
3091 	if (sc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
3092 		if (!(sc->init_sdtr & tid_bits)) {
3093 			if ((dvc_type == SCSI_TYPE_CDROM) &&
3094 			(AscCompareString(inq->vendor_id, "HP ", 3) == 0)) {
3095 				sc->pci_fix_asyn_xfer_always |= tid_bits;
3096 			}
3097 			sc->pci_fix_asyn_xfer |= tid_bits;
3098 			if ((dvc_type == SCSI_TYPE_PROC) ||
3099 			    (dvc_type == SCSI_TYPE_SCANNER)) {
3100 				sc->pci_fix_asyn_xfer &= ~tid_bits;
3101 			}
3102 			if ((dvc_type == SCSI_TYPE_SASD) &&
3103 			    (AscCompareString(inq->vendor_id, "TANDBERG", 8) == 0) &&
3104 			    (AscCompareString(inq->product_id, " TDC 36", 7) == 0)) {
3105 				sc->pci_fix_asyn_xfer &= ~tid_bits;
3106 			}
3107 			if ((dvc_type == SCSI_TYPE_SASD) &&
3108 			    (AscCompareString(inq->vendor_id, "WANGTEK ", 8) == 0)) {
3109 				sc->pci_fix_asyn_xfer &= ~tid_bits;
3110 			}
3111 			if ((dvc_type == SCSI_TYPE_CDROM) &&
3112 			    (AscCompareString(inq->vendor_id, "NEC	 ", 8) == 0) &&
3113 			    (AscCompareString(inq->product_id, "CD-ROM DRIVE	", 16) == 0)) {
3114 				sc->pci_fix_asyn_xfer &= ~tid_bits;
3115 			}
3116 			if ((dvc_type == SCSI_TYPE_CDROM) &&
3117 			    (AscCompareString(inq->vendor_id, "YAMAHA", 6) == 0) &&
3118 			    (AscCompareString(inq->product_id, "CDR400", 6) == 0)) {
3119 				sc->pci_fix_asyn_xfer &= ~tid_bits;
3120 			}
3121 			if (sc->pci_fix_asyn_xfer & tid_bits) {
3122 				AscSetRunChipSynRegAtID(sc->sc_iot, sc->sc_ioh, tid_no,
3123 					     ASYN_SDTR_DATA_FIX_PCI_REV_AB);
3124 			}
3125 		}
3126 	}
3127 }
3128 
3129 
3130 /******************************************************************************/
3131 /*                              Miscellaneous routines                        */
3132 /******************************************************************************/
3133 
3134 
3135 static int
3136 AscCompareString(u_char *str1, u_char *str2, int len)
3137 {
3138 	int             i;
3139 	int             diff;
3140 
3141 	for (i = 0; i < len; i++) {
3142 		diff = (int) (str1[i] - str2[i]);
3143 		if (diff != 0)
3144 			return (diff);
3145 	}
3146 
3147 	return (0);
3148 }
3149 
3150 
3151 /******************************************************************************/
3152 /*                            Device oriented routines                        */
3153 /******************************************************************************/
3154 
3155 
3156 static int
3157 DvcEnterCritical(void)
3158 {
3159 	int             s;
3160 
3161 	s = splbio();
3162 	return (s);
3163 }
3164 
3165 
3166 static void
3167 DvcLeaveCritical(int s)
3168 {
3169 	splx(s);
3170 }
3171 
3172 
3173 static void
3174 DvcSleepMilliSecond(u_int32_t n)
3175 {
3176 	DELAY(n * 1000);
3177 }
3178 
3179 #ifdef UNUSED
3180 static void
3181 DvcDelayMicroSecond(u_int32_t n)
3182 {
3183 	DELAY(n);
3184 }
3185 #endif
3186 
3187 static void
3188 DvcDelayNanoSecond(u_int32_t n)
3189 {
3190 	DELAY((n + 999) / 1000);
3191 }
3192