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