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