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