1 /* $NetBSD: advlib.c,v 1.25 2006/11/16 01:32:50 christos Exp $ */
4 * Low level routines for the Advanced Systems Inc. SCSI controllers chips
6 * Copyright (c) 1998 The NetBSD Foundation, Inc.
9 * Author: Baldassare Dante Profeta <dante@mclink.it>
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
43 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
45 * Copyright (c) 1995-1998 Advanced System Products, Inc.
46 * All Rights Reserved.
48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that redistributions of source
50 * code retain the above copyright notice and this comment without
55 #include <sys/cdefs.h>
56 __KERNEL_RCSID(0, "$NetBSD: advlib.c,v 1.25 2006/11/16 01:32:50 christos Exp $");
58 #include <sys/param.h>
59 #include <sys/systm.h>
60 #include <sys/malloc.h>
61 #include <sys/kernel.h>
62 #include <sys/queue.h>
63 #include <sys/device.h>
68 #include <dev/scsipi/scsi_all.h>
69 #include <dev/scsipi/scsipi_all.h>
70 #include <dev/scsipi/scsiconf.h>
72 #include <uvm/uvm_extern.h>
74 #include <dev/ic/advlib.h>
75 #include <dev/ic/adv.h>
76 #include <dev/ic/advmcode.h>
79 /* #define ASC_DEBUG */
81 /******************************************************************************/
82 /* Static functions */
83 /******************************************************************************/
85 /* Initialization routines */
86 static u_int32_t
AscLoadMicroCode(bus_space_tag_t
, bus_space_handle_t
,
87 u_int16_t
, const u_int16_t
*, u_int16_t
);
88 static void AscInitLram(ASC_SOFTC
*);
89 static void AscInitQLinkVar(ASC_SOFTC
*);
90 static int AscResetChipAndScsiBus(bus_space_tag_t
, bus_space_handle_t
);
91 static u_int16_t
AscGetChipBusType(bus_space_tag_t
, bus_space_handle_t
);
93 static u_int16_t
AscGetEisaChipCfg(bus_space_tag_t
, bus_space_handle_t
);
96 /* Chip register routines */
97 static void AscSetBank(bus_space_tag_t
, bus_space_handle_t
, u_int8_t
);
99 /* RISC Chip routines */
100 static int AscStartChip(bus_space_tag_t
, bus_space_handle_t
);
101 static int AscStopChip(bus_space_tag_t
, bus_space_handle_t
);
102 static u_int8_t
AscSetChipScsiID(bus_space_tag_t
, bus_space_handle_t
, u_int8_t
);
103 static u_int8_t
AscGetChipScsiCtrl(bus_space_tag_t
, bus_space_handle_t
);
104 static int AscSetRunChipSynRegAtID(bus_space_tag_t
, bus_space_handle_t
,
106 static int AscSetChipSynRegAtID(bus_space_tag_t
, bus_space_handle_t
,
108 static int AscHostReqRiscHalt(bus_space_tag_t
, bus_space_handle_t
);
109 static int AscIsChipHalted(bus_space_tag_t
, bus_space_handle_t
);
110 static void AscSetChipIH(bus_space_tag_t
, bus_space_handle_t
, u_int16_t
);
113 static u_int8_t
AscReadLramByte(bus_space_tag_t
, bus_space_handle_t
, u_int16_t
);
114 static void AscWriteLramByte(bus_space_tag_t
, bus_space_handle_t
,
115 u_int16_t
, u_int8_t
);
116 static u_int16_t
AscReadLramWord(bus_space_tag_t
, bus_space_handle_t
,
118 static void AscWriteLramWord(bus_space_tag_t
, bus_space_handle_t
,
119 u_int16_t
, u_int16_t
);
120 static u_int32_t
AscReadLramDWord(bus_space_tag_t
, bus_space_handle_t
,
122 static void AscWriteLramDWord(bus_space_tag_t
, bus_space_handle_t
,
123 u_int16_t
, u_int32_t
);
124 static void AscMemWordSetLram(bus_space_tag_t
, bus_space_handle_t
,
125 u_int16_t
, u_int16_t
, int);
126 static void AscMemWordCopyToLram(bus_space_tag_t
, bus_space_handle_t
,
127 u_int16_t
, const u_int16_t
*, int);
128 static void AscMemWordCopyFromLram(bus_space_tag_t
, bus_space_handle_t
,
129 u_int16_t
, u_int16_t
*, int);
130 static void AscMemDWordCopyToLram(bus_space_tag_t
, bus_space_handle_t
,
131 u_int16_t
, u_int32_t
*, int);
132 static u_int32_t
AscMemSumLramWord(bus_space_tag_t
, bus_space_handle_t
,
134 static int AscTestExternalLram(bus_space_tag_t
, bus_space_handle_t
);
136 /* MicroCode routines */
137 static u_int16_t
AscInitMicroCodeVar(ASC_SOFTC
*);
139 /* EEProm routines */
140 static int AscWriteEEPCmdReg(bus_space_tag_t
, bus_space_handle_t
, u_int8_t
);
141 static int AscWriteEEPDataReg(bus_space_tag_t
, bus_space_handle_t
, u_int16_t
);
142 static void AscWaitEEPRead(void);
143 static void AscWaitEEPWrite(void);
144 static u_int16_t
AscReadEEPWord(bus_space_tag_t
, bus_space_handle_t
, u_int8_t
);
145 static u_int16_t
AscWriteEEPWord(bus_space_tag_t
, bus_space_handle_t
,
146 u_int8_t
, u_int16_t
);
147 static u_int16_t
AscGetEEPConfig(bus_space_tag_t
, bus_space_handle_t
,
148 ASCEEP_CONFIG
*, u_int16_t
);
149 static int AscSetEEPConfig(bus_space_tag_t
, bus_space_handle_t
,
150 ASCEEP_CONFIG
*, u_int16_t
);
151 static int AscSetEEPConfigOnce(bus_space_tag_t
, bus_space_handle_t
,
152 ASCEEP_CONFIG
*, u_int16_t
);
154 static void AscPrintEEPConfig(ASCEEP_CONFIG
*, u_int16_t
);
157 /* Interrupt routines */
158 static void AscIsrChipHalted(ASC_SOFTC
*);
159 static int AscIsrQDone(ASC_SOFTC
*);
160 static int AscWaitTixISRDone(ASC_SOFTC
*, u_int8_t
);
161 static int AscWaitISRDone(ASC_SOFTC
*);
162 static u_int8_t
_AscCopyLramScsiDoneQ(bus_space_tag_t
, bus_space_handle_t
,
163 u_int16_t
, ASC_QDONE_INFO
*, u_int32_t
);
164 static void AscGetQDoneInfo(bus_space_tag_t
, bus_space_handle_t
, u_int16_t
,
166 static void AscToggleIRQAct(bus_space_tag_t
, bus_space_handle_t
);
167 static void AscDisableInterrupt(bus_space_tag_t
, bus_space_handle_t
);
168 static void AscEnableInterrupt(bus_space_tag_t
, bus_space_handle_t
);
169 static u_int8_t
AscSetChipIRQ(bus_space_tag_t
, bus_space_handle_t
,
170 u_int8_t
, u_int16_t
);
171 static void AscAckInterrupt(bus_space_tag_t
, bus_space_handle_t
);
172 static u_int32_t
AscGetMaxDmaCount(u_int16_t
);
173 static u_int16_t
AscSetIsaDmaChannel(bus_space_tag_t
, bus_space_handle_t
,
175 static u_int8_t
AscGetIsaDmaSpeed(bus_space_tag_t
, bus_space_handle_t
);
176 static u_int8_t
AscSetIsaDmaSpeed(bus_space_tag_t
, bus_space_handle_t
,
179 /* Messages routines */
180 static void AscHandleExtMsgIn(ASC_SOFTC
*, u_int16_t
, u_int8_t
,
181 ASC_SCSI_BIT_ID_TYPE
, int, u_int8_t
);
182 static u_int8_t
AscMsgOutSDTR(ASC_SOFTC
*, u_int8_t
, u_int8_t
);
185 static void AscSetChipSDTR(bus_space_tag_t
, bus_space_handle_t
,
187 static u_int8_t
AscCalSDTRData(ASC_SOFTC
*, u_int8_t
, u_int8_t
);
188 static u_int8_t
AscGetSynPeriodIndex(ASC_SOFTC
*, u_int8_t
);
191 static int AscSendScsiQueue(ASC_SOFTC
*, ASC_SCSI_Q
*, u_int8_t
);
192 static int AscSgListToQueue(int);
193 static u_int
AscGetNumOfFreeQueue(ASC_SOFTC
*, u_int8_t
, u_int8_t
);
194 static int AscPutReadyQueue(ASC_SOFTC
*, ASC_SCSI_Q
*, u_int8_t
);
195 static void AscPutSCSIQ(bus_space_tag_t
, bus_space_handle_t
,
196 u_int16_t
, ASC_SCSI_Q
*);
197 static int AscPutReadySgListQueue(ASC_SOFTC
*, ASC_SCSI_Q
*, u_int8_t
);
198 static u_int8_t
AscAllocFreeQueue(bus_space_tag_t
, bus_space_handle_t
,
200 static u_int8_t
AscAllocMultipleFreeQueue(bus_space_tag_t
, bus_space_handle_t
,
202 static int AscStopQueueExe(bus_space_tag_t
, bus_space_handle_t
);
203 static void AscStartQueueExe(bus_space_tag_t
, bus_space_handle_t
);
204 static void AscCleanUpBusyQueue(bus_space_tag_t
, bus_space_handle_t
);
205 static int _AscWaitQDone(bus_space_tag_t
, bus_space_handle_t
,
207 static int AscCleanUpDiscQueue(bus_space_tag_t
, bus_space_handle_t
);
209 /* Abort and Reset CCB routines */
210 static int AscRiscHaltedAbortCCB(ASC_SOFTC
*, ADV_CCB
*);
211 static int AscRiscHaltedAbortTIX(ASC_SOFTC
*, u_int8_t
);
213 /* Error Handling routines */
214 static int AscSetLibErrorCode(ASC_SOFTC
*, u_int16_t
);
216 /* Handle bugged borads routines */
217 static int AscTagQueuingSafe(ASC_SCSI_INQUIRY
*);
218 static void AscAsyncFix(ASC_SOFTC
*, u_int8_t
, ASC_SCSI_INQUIRY
*);
220 /* Miscellaneous routines */
221 static int AscCompareString(const u_char
*, const u_char
*, int);
223 /* Device oriented routines */
224 static int DvcEnterCritical(void);
225 static void DvcLeaveCritical(int);
226 static void DvcSleepMilliSecond(u_int32_t
);
228 static void DvcDelayMicroSecond(u_int32_t
);
230 static void DvcDelayNanoSecond(u_int32_t
);
233 /******************************************************************************/
234 /* Initialization routines */
235 /******************************************************************************/
238 * This function perform the following steps:
239 * - initialize ASC_SOFTC structure with defaults values.
240 * - inquire board registers to know what kind of board it is.
241 * - keep track of bugged borads.
244 AscInitASC_SOFTC(ASC_SOFTC
*sc
)
246 bus_space_tag_t iot
= sc
->sc_iot
;
247 bus_space_handle_t ioh
= sc
->sc_ioh
;
251 ASC_SET_CHIP_CONTROL(iot
, ioh
, ASC_CC_HALT
);
252 ASC_SET_CHIP_STATUS(iot
, ioh
, 0);
254 sc
->bug_fix_cntl
= 0;
255 sc
->pci_fix_asyn_xfer
= 0;
256 sc
->pci_fix_asyn_xfer_always
= 0;
258 sc
->cur_total_qng
= 0;
259 sc
->last_q_shortage
= 0;
260 sc
->use_tagged_qng
= 0;
261 sc
->unit_not_ready
= 0;
262 sc
->queue_full_or_busy
= 0;
263 sc
->host_init_sdtr_index
= 0;
264 sc
->can_tagged_qng
= 0;
265 sc
->cmd_qng_enabled
= 0;
266 sc
->dvc_cntl
= ASC_DEF_DVC_CNTL
;
268 sc
->max_total_qng
= ASC_DEF_MAX_TOTAL_QNG
;
269 sc
->scsi_reset_wait
= 3;
270 sc
->start_motor
= ASC_SCSI_WIDTH_BIT_SET
;
271 sc
->max_dma_count
= AscGetMaxDmaCount(sc
->bus_type
);
272 sc
->sdtr_enable
= ASC_SCSI_WIDTH_BIT_SET
;
273 sc
->disc_enable
= ASC_SCSI_WIDTH_BIT_SET
;
274 sc
->chip_scsi_id
= ASC_DEF_CHIP_SCSI_ID
;
275 sc
->lib_serial_no
= ASC_LIB_SERIAL_NUMBER
;
276 sc
->lib_version
= (ASC_LIB_VERSION_MAJOR
<< 8) | ASC_LIB_VERSION_MINOR
;
277 if ((sc
->bus_type
& ASC_IS_PCI
) &&
278 (sc
->chip_version
>= ASC_CHIP_VER_PCI_ULTRA_3150
)) {
279 sc
->bus_type
= ASC_IS_PCI_ULTRA
;
280 sc
->sdtr_period_tbl
[0] = SYN_ULTRA_XFER_NS_0
;
281 sc
->sdtr_period_tbl
[1] = SYN_ULTRA_XFER_NS_1
;
282 sc
->sdtr_period_tbl
[2] = SYN_ULTRA_XFER_NS_2
;
283 sc
->sdtr_period_tbl
[3] = SYN_ULTRA_XFER_NS_3
;
284 sc
->sdtr_period_tbl
[4] = SYN_ULTRA_XFER_NS_4
;
285 sc
->sdtr_period_tbl
[5] = SYN_ULTRA_XFER_NS_5
;
286 sc
->sdtr_period_tbl
[6] = SYN_ULTRA_XFER_NS_6
;
287 sc
->sdtr_period_tbl
[7] = SYN_ULTRA_XFER_NS_7
;
288 sc
->sdtr_period_tbl
[8] = SYN_ULTRA_XFER_NS_8
;
289 sc
->sdtr_period_tbl
[9] = SYN_ULTRA_XFER_NS_9
;
290 sc
->sdtr_period_tbl
[10] = SYN_ULTRA_XFER_NS_10
;
291 sc
->sdtr_period_tbl
[11] = SYN_ULTRA_XFER_NS_11
;
292 sc
->sdtr_period_tbl
[12] = SYN_ULTRA_XFER_NS_12
;
293 sc
->sdtr_period_tbl
[13] = SYN_ULTRA_XFER_NS_13
;
294 sc
->sdtr_period_tbl
[14] = SYN_ULTRA_XFER_NS_14
;
295 sc
->sdtr_period_tbl
[15] = SYN_ULTRA_XFER_NS_15
;
296 sc
->max_sdtr_index
= 15;
297 if (sc
->chip_version
== ASC_CHIP_VER_PCI_ULTRA_3150
)
298 ASC_SET_EXTRA_CONTROL(iot
, ioh
,
299 (SEC_ACTIVE_NEGATE
| SEC_SLEW_RATE
));
300 else if (sc
->chip_version
>= ASC_CHIP_VER_PCI_ULTRA_3050
)
301 ASC_SET_EXTRA_CONTROL(iot
, ioh
,
302 (SEC_ACTIVE_NEGATE
| SEC_ENABLE_FILTER
));
304 sc
->sdtr_period_tbl
[0] = SYN_XFER_NS_0
;
305 sc
->sdtr_period_tbl
[1] = SYN_XFER_NS_1
;
306 sc
->sdtr_period_tbl
[2] = SYN_XFER_NS_2
;
307 sc
->sdtr_period_tbl
[3] = SYN_XFER_NS_3
;
308 sc
->sdtr_period_tbl
[4] = SYN_XFER_NS_4
;
309 sc
->sdtr_period_tbl
[5] = SYN_XFER_NS_5
;
310 sc
->sdtr_period_tbl
[6] = SYN_XFER_NS_6
;
311 sc
->sdtr_period_tbl
[7] = SYN_XFER_NS_7
;
312 sc
->max_sdtr_index
= 7;
315 if (sc
->bus_type
== ASC_IS_PCI
)
316 ASC_SET_EXTRA_CONTROL(iot
, ioh
,
317 (SEC_ACTIVE_NEGATE
| SEC_SLEW_RATE
));
319 sc
->isa_dma_speed
= ASC_DEF_ISA_DMA_SPEED
;
320 if (AscGetChipBusType(iot
, ioh
) == ASC_IS_ISAPNP
) {
321 ASC_SET_CHIP_IFC(iot
, ioh
, ASC_IFC_INIT_DEFAULT
);
322 sc
->bus_type
= ASC_IS_ISAPNP
;
324 if ((sc
->bus_type
& ASC_IS_ISA
) != 0)
325 sc
->isa_dma_channel
= AscGetIsaDmaChannel(iot
, ioh
);
327 for (i
= 0; i
<= ASC_MAX_TID
; i
++) {
328 sc
->cur_dvc_qng
[i
] = 0;
329 sc
->max_dvc_qng
[i
] = ASC_MAX_SCSI1_QNG
;
330 sc
->max_tag_qng
[i
] = ASC_MAX_INRAM_TAG_QNG
;
336 * This function initialize some ASC_SOFTC fields with values read from
340 AscInitFromEEP(ASC_SOFTC
*sc
)
342 bus_space_tag_t iot
= sc
->sc_iot
;
343 bus_space_handle_t ioh
= sc
->sc_ioh
;
344 ASCEEP_CONFIG eep_config_buf
;
345 ASCEEP_CONFIG
*eep_config
;
348 u_int16_t cfg_msw
, cfg_lsw
;
354 AscWriteLramWord(iot
, ioh
, ASCV_HALTCODE_W
, 0x00FE);
355 AscStopQueueExe(iot
, ioh
);
357 AscStopChip(iot
, ioh
);
358 AscResetChipAndScsiBus(iot
, ioh
);
359 DvcSleepMilliSecond(sc
->scsi_reset_wait
* 1000);
361 if ((AscStopChip(iot
, ioh
) == FALSE
) ||
362 (AscGetChipScsiCtrl(iot
, ioh
) != 0)) {
363 AscResetChipAndScsiBus(iot
, ioh
);
364 DvcSleepMilliSecond(sc
->scsi_reset_wait
* 1000);
366 if (AscIsChipHalted(iot
, ioh
) == FALSE
)
369 ASC_SET_PC_ADDR(iot
, ioh
, ASC_MCODE_START_ADDR
);
370 if (ASC_GET_PC_ADDR(iot
, ioh
) != ASC_MCODE_START_ADDR
)
373 eep_config
= &eep_config_buf
;
374 cfg_msw
= ASC_GET_CHIP_CFG_MSW(iot
, ioh
);
375 cfg_lsw
= ASC_GET_CHIP_CFG_LSW(iot
, ioh
);
376 if ((cfg_msw
& ASC_CFG_MSW_CLR_MASK
) != 0) {
377 cfg_msw
&= (~(ASC_CFG_MSW_CLR_MASK
));
378 warn_code
|= ASC_WARN_CFG_MSW_RECOVER
;
379 ASC_SET_CHIP_CFG_MSW(iot
, ioh
, cfg_msw
);
381 chksum
= AscGetEEPConfig(iot
, ioh
, eep_config
, sc
->bus_type
);
383 AscPrintEEPConfig(eep_config
, chksum
);
388 if (ASC_GET_CHIP_STATUS(iot
, ioh
) & ASC_CSW_AUTO_CONFIG
) {
389 warn_code
|= ASC_WARN_AUTO_CONFIG
;
390 if (sc
->chip_version
== 3) {
391 if (eep_config
->cfg_lsw
!= cfg_lsw
) {
392 warn_code
|= ASC_WARN_EEPROM_RECOVER
;
393 eep_config
->cfg_lsw
= ASC_GET_CHIP_CFG_LSW(iot
, ioh
);
395 if (eep_config
->cfg_msw
!= cfg_msw
) {
396 warn_code
|= ASC_WARN_EEPROM_RECOVER
;
397 eep_config
->cfg_msw
= ASC_GET_CHIP_CFG_MSW(iot
, ioh
);
401 eep_config
->cfg_msw
&= ~ASC_CFG_MSW_CLR_MASK
;
402 eep_config
->cfg_lsw
|= ASC_CFG0_HOST_INT_ON
;
404 if (chksum
!= eep_config
->chksum
) {
405 if (sc
->chip_version
== ASC_CHIP_VER_PCI_ULTRA_3050
) {
406 eep_config
->init_sdtr
= 0xFF;
407 eep_config
->disc_enable
= 0xFF;
408 eep_config
->start_motor
= 0xFF;
409 eep_config
->use_cmd_qng
= 0;
410 eep_config
->max_total_qng
= 0xF0;
411 eep_config
->max_tag_qng
= 0x20;
412 eep_config
->cntl
= 0xBFFF;
413 eep_config
->chip_scsi_id
= 7;
414 eep_config
->no_scam
= 0;
415 eep_config
->adapter_info
[0] = 0;
416 eep_config
->adapter_info
[1] = 0;
417 eep_config
->adapter_info
[2] = 0;
418 eep_config
->adapter_info
[3] = 0;
419 #if BYTE_ORDER == BIG_ENDIAN
420 eep_config
->adapter_info
[5] = 0;
421 /* Indicate EEPROM-less board. */
422 eep_config
->adapter_info
[4] = 0xBB;
424 eep_config
->adapter_info
[4] = 0;
425 /* Indicate EEPROM-less board. */
426 eep_config
->adapter_info
[5] = 0xBB;
430 warn_code
|= ASC_WARN_EEPROM_CHKSUM
;
433 sc
->sdtr_enable
= eep_config
->init_sdtr
;
434 sc
->disc_enable
= eep_config
->disc_enable
;
435 sc
->cmd_qng_enabled
= eep_config
->use_cmd_qng
;
436 sc
->isa_dma_speed
= eep_config
->isa_dma_speed
;
437 sc
->start_motor
= eep_config
->start_motor
;
438 sc
->dvc_cntl
= eep_config
->cntl
;
439 #if BYTE_ORDER == BIG_ENDIAN
440 sc
->adapter_info
[0] = eep_config
->adapter_info
[1];
441 sc
->adapter_info
[1] = eep_config
->adapter_info
[0];
442 sc
->adapter_info
[2] = eep_config
->adapter_info
[3];
443 sc
->adapter_info
[3] = eep_config
->adapter_info
[2];
444 sc
->adapter_info
[4] = eep_config
->adapter_info
[5];
445 sc
->adapter_info
[5] = eep_config
->adapter_info
[4];
447 sc
->adapter_info
[0] = eep_config
->adapter_info
[0];
448 sc
->adapter_info
[1] = eep_config
->adapter_info
[1];
449 sc
->adapter_info
[2] = eep_config
->adapter_info
[2];
450 sc
->adapter_info
[3] = eep_config
->adapter_info
[3];
451 sc
->adapter_info
[4] = eep_config
->adapter_info
[4];
452 sc
->adapter_info
[5] = eep_config
->adapter_info
[5];
455 if (!AscTestExternalLram(iot
, ioh
)) {
456 if (((sc
->bus_type
& ASC_IS_PCI_ULTRA
) == ASC_IS_PCI_ULTRA
)) {
457 eep_config
->max_total_qng
= ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG
;
458 eep_config
->max_tag_qng
= ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG
;
460 eep_config
->cfg_msw
|= 0x0800;
462 ASC_SET_CHIP_CFG_MSW(iot
, ioh
, cfg_msw
);
463 eep_config
->max_total_qng
= ASC_MAX_PCI_INRAM_TOTAL_QNG
;
464 eep_config
->max_tag_qng
= ASC_MAX_INRAM_TAG_QNG
;
467 if (eep_config
->max_total_qng
< ASC_MIN_TOTAL_QNG
)
468 eep_config
->max_total_qng
= ASC_MIN_TOTAL_QNG
;
470 if (eep_config
->max_total_qng
> ASC_MAX_TOTAL_QNG
)
471 eep_config
->max_total_qng
= ASC_MAX_TOTAL_QNG
;
473 if (eep_config
->max_tag_qng
> eep_config
->max_total_qng
)
474 eep_config
->max_tag_qng
= eep_config
->max_total_qng
;
476 if (eep_config
->max_tag_qng
< ASC_MIN_TAG_Q_PER_DVC
)
477 eep_config
->max_tag_qng
= ASC_MIN_TAG_Q_PER_DVC
;
479 sc
->max_total_qng
= eep_config
->max_total_qng
;
480 if ((eep_config
->use_cmd_qng
& eep_config
->disc_enable
) !=
481 eep_config
->use_cmd_qng
) {
482 eep_config
->disc_enable
= eep_config
->use_cmd_qng
;
483 warn_code
|= ASC_WARN_CMD_QNG_CONFLICT
;
485 if (sc
->bus_type
& (ASC_IS_ISA
| ASC_IS_VL
| ASC_IS_EISA
))
486 sc
->irq_no
= AscGetChipIRQ(iot
, ioh
, sc
->bus_type
);
488 eep_config
->chip_scsi_id
&= ASC_MAX_TID
;
489 sc
->chip_scsi_id
= eep_config
->chip_scsi_id
;
490 if (((sc
->bus_type
& ASC_IS_PCI_ULTRA
) == ASC_IS_PCI_ULTRA
) &&
491 !(sc
->dvc_cntl
& ASC_CNTL_SDTR_ENABLE_ULTRA
)) {
492 sc
->host_init_sdtr_index
= ASC_SDTR_ULTRA_PCI_10MB_INDEX
;
494 for (i
= 0; i
<= ASC_MAX_TID
; i
++) {
495 sc
->max_tag_qng
[i
] = eep_config
->max_tag_qng
;
496 sc
->sdtr_period_offset
[i
] = ASC_DEF_SDTR_OFFSET
|
497 (sc
->host_init_sdtr_index
<< 4);
500 eep_config
->cfg_msw
= ASC_GET_CHIP_CFG_MSW(iot
, ioh
);
502 AscSetEEPConfig(iot
, ioh
, eep_config
, sc
->bus_type
);
504 AscPrintEEPConfig(eep_config
, 0);
513 AscInitFromASC_SOFTC(ASC_SOFTC
*sc
)
515 bus_space_tag_t iot
= sc
->sc_iot
;
516 bus_space_handle_t ioh
= sc
->sc_ioh
;
519 u_int16_t pci_device_id
= sc
->pci_device_id
;
523 cfg_msw
= ASC_GET_CHIP_CFG_MSW(iot
, ioh
);
525 if ((cfg_msw
& ASC_CFG_MSW_CLR_MASK
) != 0) {
526 cfg_msw
&= (~(ASC_CFG_MSW_CLR_MASK
));
527 warn_code
|= ASC_WARN_CFG_MSW_RECOVER
;
528 ASC_SET_CHIP_CFG_MSW(iot
, ioh
, cfg_msw
);
530 if ((sc
->cmd_qng_enabled
& sc
->disc_enable
) != sc
->cmd_qng_enabled
) {
531 sc
->disc_enable
= sc
->cmd_qng_enabled
;
532 warn_code
|= ASC_WARN_CMD_QNG_CONFLICT
;
534 if (ASC_GET_CHIP_STATUS(iot
, ioh
) & ASC_CSW_AUTO_CONFIG
) {
535 warn_code
|= ASC_WARN_AUTO_CONFIG
;
537 if ((sc
->bus_type
& (ASC_IS_ISA
| ASC_IS_VL
)) != 0) {
538 AscSetChipIRQ(iot
, ioh
, sc
->irq_no
, sc
->bus_type
);
540 if (sc
->bus_type
& ASC_IS_PCI
) {
542 ASC_SET_CHIP_CFG_MSW(iot
, ioh
, cfg_msw
);
544 if ((sc
->bus_type
& ASC_IS_PCI_ULTRA
) != ASC_IS_PCI_ULTRA
) {
545 if ((pci_device_id
== ASC_PCI_DEVICE_ID_REV_A
) ||
546 (pci_device_id
== ASC_PCI_DEVICE_ID_REV_B
)) {
547 sc
->bug_fix_cntl
|= ASC_BUG_FIX_IF_NOT_DWB
;
548 sc
->bug_fix_cntl
|= ASC_BUG_FIX_ASYN_USE_SYN
;
551 } else if (sc
->bus_type
== ASC_IS_ISAPNP
) {
552 if (sc
->chip_version
== ASC_CHIP_VER_ASYN_BUG
) {
553 sc
->bug_fix_cntl
|= ASC_BUG_FIX_ASYN_USE_SYN
;
556 AscSetChipScsiID(iot
, ioh
, sc
->chip_scsi_id
);
558 if (sc
->bus_type
& ASC_IS_ISA
) {
559 AscSetIsaDmaChannel(iot
, ioh
, sc
->isa_dma_channel
);
560 AscSetIsaDmaSpeed(iot
, ioh
, sc
->isa_dma_speed
);
567 * - Initialize RISC chip
569 * - Load uCode into Lram
570 * - Enable Interrupts
573 AscInitDriver(ASC_SOFTC
*sc
)
575 bus_space_tag_t iot
= sc
->sc_iot
;
576 bus_space_handle_t ioh
= sc
->sc_ioh
;
580 if (!AscFindSignature(iot
, ioh
))
583 AscDisableInterrupt(iot
, ioh
);
586 chksum
= AscLoadMicroCode(iot
, ioh
, 0, (const u_int16_t
*) asc_mcode
,
588 if (chksum
!= asc_mcode_chksum
)
591 if (AscInitMicroCodeVar(sc
) == 0)
594 AscEnableInterrupt(iot
, ioh
);
601 AscFindSignature(bus_space_tag_t iot
, bus_space_handle_t ioh
)
605 if (ASC_GET_CHIP_SIGNATURE_BYTE(iot
, ioh
) == ASC_1000_ID1B
) {
606 sig_word
= ASC_GET_CHIP_SIGNATURE_WORD(iot
, ioh
);
607 if (sig_word
== ASC_1000_ID0W
||
608 sig_word
== ASC_1000_ID0W_FIX
)
616 AscInitLram(ASC_SOFTC
*sc
)
618 bus_space_tag_t iot
= sc
->sc_iot
;
619 bus_space_handle_t ioh
= sc
->sc_ioh
;
624 AscMemWordSetLram(iot
, ioh
, ASC_QADR_BEG
, 0,
625 (((sc
->max_total_qng
+ 2 + 1) * 64) >> 1));
627 i
= ASC_MIN_ACTIVE_QNO
;
628 s_addr
= ASC_QADR_BEG
+ ASC_QBLK_SIZE
;
629 AscWriteLramByte(iot
, ioh
, s_addr
+ ASC_SCSIQ_B_FWD
, i
+ 1);
630 AscWriteLramByte(iot
, ioh
, s_addr
+ ASC_SCSIQ_B_BWD
, sc
->max_total_qng
);
631 AscWriteLramByte(iot
, ioh
, s_addr
+ ASC_SCSIQ_B_QNO
, i
);
633 s_addr
+= ASC_QBLK_SIZE
;
634 for (; i
< sc
->max_total_qng
; i
++, s_addr
+= ASC_QBLK_SIZE
) {
635 AscWriteLramByte(iot
, ioh
, s_addr
+ ASC_SCSIQ_B_FWD
, i
+ 1);
636 AscWriteLramByte(iot
, ioh
, s_addr
+ ASC_SCSIQ_B_BWD
, i
- 1);
637 AscWriteLramByte(iot
, ioh
, s_addr
+ ASC_SCSIQ_B_QNO
, i
);
639 AscWriteLramByte(iot
, ioh
, s_addr
+ ASC_SCSIQ_B_FWD
, ASC_QLINK_END
);
640 AscWriteLramByte(iot
, ioh
, s_addr
+ ASC_SCSIQ_B_BWD
, sc
->max_total_qng
- 1);
641 AscWriteLramByte(iot
, ioh
, s_addr
+ ASC_SCSIQ_B_QNO
, sc
->max_total_qng
);
643 s_addr
+= ASC_QBLK_SIZE
;
644 for (; i
<= (u_int8_t
) (sc
->max_total_qng
+ 3); i
++, s_addr
+= ASC_QBLK_SIZE
) {
645 AscWriteLramByte(iot
, ioh
, s_addr
+ ASC_SCSIQ_B_FWD
, i
);
646 AscWriteLramByte(iot
, ioh
, s_addr
+ ASC_SCSIQ_B_BWD
, i
);
647 AscWriteLramByte(iot
, ioh
, s_addr
+ ASC_SCSIQ_B_QNO
, i
);
653 AscReInitLram(ASC_SOFTC
*sc
)
662 AscInitQLinkVar(ASC_SOFTC
*sc
)
664 bus_space_tag_t iot
= sc
->sc_iot
;
665 bus_space_handle_t ioh
= sc
->sc_ioh
;
670 ASC_PUT_RISC_VAR_FREE_QHEAD(iot
, ioh
, 1);
671 ASC_PUT_RISC_VAR_DONE_QTAIL(iot
, ioh
, sc
->max_total_qng
);
672 ASC_PUT_VAR_FREE_QHEAD(iot
, ioh
, 1);
673 ASC_PUT_VAR_DONE_QTAIL(iot
, ioh
, sc
->max_total_qng
);
674 AscWriteLramByte(iot
, ioh
, ASCV_BUSY_QHEAD_B
, sc
->max_total_qng
+ 1);
675 AscWriteLramByte(iot
, ioh
, ASCV_DISC1_QHEAD_B
, sc
->max_total_qng
+ 2);
676 AscWriteLramByte(iot
, ioh
, ASCV_TOTAL_READY_Q_B
, sc
->max_total_qng
);
677 AscWriteLramWord(iot
, ioh
, ASCV_ASCDVC_ERR_CODE_W
, 0);
678 AscWriteLramWord(iot
, ioh
, ASCV_HALTCODE_W
, 0);
679 AscWriteLramByte(iot
, ioh
, ASCV_STOP_CODE_B
, 0);
680 AscWriteLramByte(iot
, ioh
, ASCV_SCSIBUSY_B
, 0);
681 AscWriteLramByte(iot
, ioh
, ASCV_WTM_FLAG_B
, 0);
682 ASC_PUT_QDONE_IN_PROGRESS(iot
, ioh
, 0);
683 lram_addr
= ASC_QADR_BEG
;
684 for (i
= 0; i
< 32; i
++, lram_addr
+= 2)
685 AscWriteLramWord(iot
, ioh
, lram_addr
, 0);
690 AscResetChipAndScsiBus(bus_space_tag_t iot
, bus_space_handle_t ioh
)
692 while (ASC_GET_CHIP_STATUS(iot
, ioh
) & ASC_CSW_SCSI_RESET_ACTIVE
);
694 AscStopChip(iot
, ioh
);
695 ASC_SET_CHIP_CONTROL(iot
, ioh
, ASC_CC_CHIP_RESET
| ASC_CC_SCSI_RESET
| ASC_CC_HALT
);
697 DvcDelayNanoSecond(60000);
699 AscSetChipIH(iot
, ioh
, ASC_INS_RFLAG_WTM
);
700 AscSetChipIH(iot
, ioh
, ASC_INS_HALT
);
701 ASC_SET_CHIP_CONTROL(iot
, ioh
, ASC_CC_CHIP_RESET
| ASC_CC_HALT
);
702 ASC_SET_CHIP_CONTROL(iot
, ioh
, ASC_CC_HALT
);
704 DvcSleepMilliSecond(200);
706 ASC_SET_CHIP_STATUS(iot
, ioh
, ASC_CIW_CLR_SCSI_RESET_INT
);
707 ASC_SET_CHIP_STATUS(iot
, ioh
, 0);
709 DvcSleepMilliSecond(200);
711 return (AscIsChipHalted(iot
, ioh
));
716 AscGetChipBusType(bus_space_tag_t iot
, bus_space_handle_t ioh
)
720 chip_ver
= ASC_GET_CHIP_VER_NO(iot
, ioh
);
722 if ((chip_ver
>= ASC_CHIP_MIN_VER_VL
) &&
723 (chip_ver
<= ASC_CHIP_MAX_VER_VL
)) {
724 if(((ioh
& 0x0C30) == 0x0C30) || ((ioh
& 0x0C50) == 0x0C50)) {
725 return (ASC_IS_EISA
);
732 if ((chip_ver
>= ASC_CHIP_MIN_VER_ISA
) &&
733 (chip_ver
<= ASC_CHIP_MAX_VER_ISA
)) {
734 if (chip_ver
>= ASC_CHIP_MIN_VER_ISA_PNP
)
735 return (ASC_IS_ISAPNP
);
738 } else if ((chip_ver
>= ASC_CHIP_MIN_VER_PCI
) &&
739 (chip_ver
<= ASC_CHIP_MAX_VER_PCI
))
747 AscGetEisaChipCfg(bus_space_tag_t iot, bus_space_handle_t ioh)
751 eisa_cfg_iop = ASC_GET_EISA_SLOT(ioh) | (ASC_EISA_CFG_IOP_MASK);
752 return (inw(eisa_cfg_iop));
756 /******************************************************************************/
757 /* Chip register routines */
758 /******************************************************************************/
762 AscSetBank(bus_space_tag_t iot
, bus_space_handle_t ioh
, u_int8_t bank
)
766 val
= ASC_GET_CHIP_CONTROL(iot
, ioh
) &
767 (~(ASC_CC_SINGLE_STEP
| ASC_CC_TEST
|
768 ASC_CC_DIAG
| ASC_CC_SCSI_RESET
|
773 val
|= ASC_CC_BANK_ONE
;
777 val
|= ASC_CC_DIAG
| ASC_CC_BANK_ONE
;
781 val
&= ~ASC_CC_BANK_ONE
;
784 ASC_SET_CHIP_CONTROL(iot
, ioh
, val
);
789 /******************************************************************************/
791 /******************************************************************************/
795 AscStartChip(bus_space_tag_t iot
, bus_space_handle_t ioh
)
797 ASC_SET_CHIP_CONTROL(iot
, ioh
, 0);
798 if ((ASC_GET_CHIP_STATUS(iot
, ioh
) & ASC_CSW_HALTED
) != 0)
806 AscStopChip(bus_space_tag_t iot
, bus_space_handle_t ioh
)
810 cc_val
= ASC_GET_CHIP_CONTROL(iot
, ioh
) &
811 (~(ASC_CC_SINGLE_STEP
| ASC_CC_TEST
| ASC_CC_DIAG
));
812 ASC_SET_CHIP_CONTROL(iot
, ioh
, cc_val
| ASC_CC_HALT
);
813 AscSetChipIH(iot
, ioh
, ASC_INS_HALT
);
814 AscSetChipIH(iot
, ioh
, ASC_INS_RFLAG_WTM
);
815 if ((ASC_GET_CHIP_STATUS(iot
, ioh
) & ASC_CSW_HALTED
) == 0)
823 AscSetChipScsiID(bus_space_tag_t iot
, bus_space_handle_t ioh
, u_int8_t new_id
)
827 if (ASC_GET_CHIP_SCSI_ID(iot
, ioh
) == new_id
)
830 cfg_lsw
= ASC_GET_CHIP_SCSI_ID(iot
, ioh
);
832 cfg_lsw
|= (new_id
& ASC_MAX_TID
) << 8;
833 ASC_SET_CHIP_CFG_LSW(iot
, ioh
, cfg_lsw
);
834 return (ASC_GET_CHIP_SCSI_ID(iot
, ioh
));
839 AscGetChipScsiCtrl(bus_space_tag_t iot
, bus_space_handle_t ioh
)
843 AscSetBank(iot
, ioh
, 1);
844 scsi_ctrl
= bus_space_read_1(iot
, ioh
, ASC_IOP_REG_SC
);
845 AscSetBank(iot
, ioh
, 0);
851 AscSetRunChipSynRegAtID(bus_space_tag_t iot
, bus_space_handle_t ioh
,
852 u_int8_t tid_no
, u_int8_t sdtr_data
)
856 if (AscHostReqRiscHalt(iot
, ioh
)) {
857 retval
= AscSetChipSynRegAtID(iot
, ioh
, tid_no
, sdtr_data
);
858 AscStartChip(iot
, ioh
);
865 AscSetChipSynRegAtID(bus_space_tag_t iot
, bus_space_handle_t ioh
,
866 u_int8_t id
, u_int8_t sdtr_data
)
868 ASC_SCSI_BIT_ID_TYPE org_id
;
872 AscSetBank(iot
, ioh
, 1);
873 org_id
= ASC_READ_CHIP_DVC_ID(iot
, ioh
);
874 for (i
= 0; i
<= ASC_MAX_TID
; i
++)
875 if (org_id
== (0x01 << i
))
879 ASC_WRITE_CHIP_DVC_ID(iot
, ioh
, id
);
880 if (ASC_READ_CHIP_DVC_ID(iot
, ioh
) == (0x01 << id
)) {
881 AscSetBank(iot
, ioh
, 0);
882 ASC_SET_CHIP_SYN(iot
, ioh
, sdtr_data
);
883 if (ASC_GET_CHIP_SYN(iot
, ioh
) != sdtr_data
)
888 AscSetBank(iot
, ioh
, 1);
889 ASC_WRITE_CHIP_DVC_ID(iot
, ioh
, org_id
);
890 AscSetBank(iot
, ioh
, 0);
896 AscHostReqRiscHalt(bus_space_tag_t iot
, bus_space_handle_t ioh
)
900 u_int8_t saved_stop_code
;
903 if (AscIsChipHalted(iot
, ioh
))
905 saved_stop_code
= AscReadLramByte(iot
, ioh
, ASCV_STOP_CODE_B
);
906 AscWriteLramByte(iot
, ioh
, ASCV_STOP_CODE_B
,
907 ASC_STOP_HOST_REQ_RISC_HALT
| ASC_STOP_REQ_RISC_STOP
);
910 if (AscIsChipHalted(iot
, ioh
)) {
914 DvcSleepMilliSecond(100);
915 } while (count
++ < 20);
917 AscWriteLramByte(iot
, ioh
, ASCV_STOP_CODE_B
, saved_stop_code
);
924 AscIsChipHalted(bus_space_tag_t iot
, bus_space_handle_t ioh
)
926 if ((ASC_GET_CHIP_STATUS(iot
, ioh
) & ASC_CSW_HALTED
) != 0)
927 if ((ASC_GET_CHIP_CONTROL(iot
, ioh
) & ASC_CC_HALT
) != 0)
935 AscSetChipIH(bus_space_tag_t iot
, bus_space_handle_t ioh
, u_int16_t ins_code
)
937 AscSetBank(iot
, ioh
, 1);
938 ASC_WRITE_CHIP_IH(iot
, ioh
, ins_code
);
939 AscSetBank(iot
, ioh
, 0);
945 /******************************************************************************/
947 /******************************************************************************/
951 AscReadLramByte(bus_space_tag_t iot
, bus_space_handle_t ioh
, u_int16_t addr
)
957 ASC_SET_CHIP_LRAM_ADDR(iot
, ioh
, addr
& 0xFFFE);
958 word_data
= ASC_GET_CHIP_LRAM_DATA(iot
, ioh
);
962 byte_data
= (u_int8_t
) ((word_data
>> 8) & 0xFF);
965 byte_data
= (u_int8_t
) (word_data
& 0xFF);
973 AscWriteLramByte(bus_space_tag_t iot
, bus_space_handle_t ioh
,
974 u_int16_t addr
, u_int8_t data
)
979 word_data
= AscReadLramWord(iot
, ioh
, addr
& 0xFFFE);
984 word_data
|= (((u_int16_t
) data
) << 8) & 0xFF00;
988 word_data
|= ((u_int16_t
) data
) & 0x00FF;
991 AscWriteLramWord(iot
, ioh
, addr
& 0xFFFE, word_data
);
996 AscReadLramWord(bus_space_tag_t iot
, bus_space_handle_t ioh
, u_int16_t addr
)
999 ASC_SET_CHIP_LRAM_ADDR(iot
, ioh
, addr
);
1000 return (ASC_GET_CHIP_LRAM_DATA(iot
, ioh
));
1005 AscWriteLramWord(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1006 u_int16_t addr
, u_int16_t data
)
1009 ASC_SET_CHIP_LRAM_ADDR(iot
, ioh
, addr
);
1010 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, data
);
1015 AscReadLramDWord(bus_space_tag_t iot
, bus_space_handle_t ioh
, u_int16_t addr
)
1017 u_int16_t low_word
, hi_word
;
1020 ASC_SET_CHIP_LRAM_ADDR(iot
, ioh
, addr
);
1021 low_word
= ASC_GET_CHIP_LRAM_DATA(iot
, ioh
);
1022 hi_word
= ASC_GET_CHIP_LRAM_DATA(iot
, ioh
);
1024 return ((((u_int32_t
) hi_word
) << 16) | (u_int32_t
) low_word
);
1029 AscWriteLramDWord(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1030 u_int16_t addr
, u_int32_t data
)
1033 ASC_SET_CHIP_LRAM_ADDR(iot
, ioh
, addr
);
1034 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, (u_int16_t
) (data
& 0x0000FFFF));
1035 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, (u_int16_t
) (data
>> 16));
1040 AscMemWordSetLram(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1041 u_int16_t s_addr
, u_int16_t s_words
, int count
)
1045 ASC_SET_CHIP_LRAM_ADDR(iot
, ioh
, s_addr
);
1046 for (i
= 0; i
< count
; i
++)
1047 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, s_words
);
1052 AscMemWordCopyToLram(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1053 u_int16_t s_addr
, const u_int16_t
*s_buffer
, int words
)
1057 ASC_SET_CHIP_LRAM_ADDR(iot
, ioh
, s_addr
);
1058 for (i
= 0; i
< words
; i
++, s_buffer
++)
1059 ASC_SET_CHIP_LRAM_DATA_NO_SWAP(iot
, ioh
, *s_buffer
);
1064 AscMemWordCopyFromLram(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1065 u_int16_t s_addr
, u_int16_t
*s_buffer
, int words
)
1069 ASC_SET_CHIP_LRAM_ADDR(iot
, ioh
, s_addr
);
1070 for (i
= 0; i
< words
; i
++, s_buffer
++)
1071 *s_buffer
= ASC_GET_CHIP_LRAM_DATA_NO_SWAP(iot
, ioh
);
1076 AscMemDWordCopyToLram(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1077 u_int16_t s_addr
, u_int32_t
*s_buffer
, int dwords
)
1082 ASC_SET_CHIP_LRAM_ADDR(iot
, ioh
, s_addr
);
1085 for (i
= 0; i
< dwords
; i
++, pw
++) {
1086 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, LO_WORD(*pw
));
1088 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, HI_WORD(*pw
));
1094 AscMemSumLramWord(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1095 u_int16_t s_addr
, int words
)
1101 for (i
= 0; i
< words
; i
++, s_addr
+= 2)
1102 sum
+= AscReadLramWord(iot
, ioh
, s_addr
);
1109 AscTestExternalLram(bus_space_tag_t iot
, bus_space_handle_t ioh
)
1112 u_int16_t saved_word
;
1117 q_addr
= ASC_QNO_TO_QADDR(241);
1118 saved_word
= AscReadLramWord(iot
, ioh
, q_addr
);
1119 ASC_SET_CHIP_LRAM_ADDR(iot
, ioh
, q_addr
);
1120 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, 0x55AA);
1121 DvcSleepMilliSecond(10);
1122 ASC_SET_CHIP_LRAM_ADDR(iot
, ioh
, q_addr
);
1124 if (ASC_GET_CHIP_LRAM_DATA(iot
, ioh
) == 0x55AA) {
1126 AscWriteLramWord(iot
, ioh
, q_addr
, saved_word
);
1132 /******************************************************************************/
1133 /* MicroCode routines */
1134 /******************************************************************************/
1138 AscInitMicroCodeVar(ASC_SOFTC
*sc
)
1140 bus_space_tag_t iot
= sc
->sc_iot
;
1141 bus_space_handle_t ioh
= sc
->sc_ioh
;
1146 for (i
= 0; i
<= ASC_MAX_TID
; i
++)
1147 ASC_PUT_MCODE_INIT_SDTR_AT_ID(iot
, ioh
, i
,
1148 sc
->sdtr_period_offset
[i
]);
1150 AscInitQLinkVar(sc
);
1151 AscWriteLramByte(iot
, ioh
, ASCV_DISC_ENABLE_B
, sc
->disc_enable
);
1152 AscWriteLramByte(iot
, ioh
, ASCV_HOSTSCSI_ID_B
,
1153 ASC_TID_TO_TARGET_ID(sc
->chip_scsi_id
));
1155 phy_addr
= (sc
->overrun_buf
& 0xfffffff8) + 8;
1156 AscWriteLramDWord(iot
, ioh
, ASCV_OVERRUN_PADDR_D
, phy_addr
);
1157 AscWriteLramDWord(iot
, ioh
, ASCV_OVERRUN_BSIZE_D
,
1158 ASC_OVERRUN_BSIZE
- 8);
1160 sc
->mcode_date
= AscReadLramWord(iot
, ioh
, ASCV_MC_DATE_W
);
1161 sc
->mcode_version
= AscReadLramWord(iot
, ioh
, ASCV_MC_VER_W
);
1162 ASC_SET_PC_ADDR(iot
, ioh
, ASC_MCODE_START_ADDR
);
1164 if (ASC_GET_PC_ADDR(iot
, ioh
) != ASC_MCODE_START_ADDR
) {
1167 if (AscStartChip(iot
, ioh
) != 1) {
1175 AscLoadMicroCode(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1176 u_int16_t s_addr
, const u_int16_t
*mcode_buf
, u_int16_t mcode_size
)
1179 u_int16_t mcode_word_size
;
1180 u_int16_t mcode_chksum
;
1182 mcode_word_size
= mcode_size
>> 1;
1183 /* clear board memory */
1184 AscMemWordSetLram(iot
, ioh
, s_addr
, 0, mcode_word_size
);
1185 /* copy uCode to board memory */
1186 AscMemWordCopyToLram(iot
, ioh
, s_addr
, mcode_buf
, mcode_word_size
);
1187 chksum
= AscMemSumLramWord(iot
, ioh
, s_addr
, mcode_word_size
);
1188 mcode_chksum
= AscMemSumLramWord(iot
, ioh
, ASC_CODE_SEC_BEG
,
1189 ((mcode_size
- s_addr
- ASC_CODE_SEC_BEG
) >> 1));
1190 AscWriteLramWord(iot
, ioh
, ASCV_MCODE_CHKSUM_W
, mcode_chksum
);
1191 AscWriteLramWord(iot
, ioh
, ASCV_MCODE_SIZE_W
, mcode_size
);
1197 /******************************************************************************/
1198 /* EEProm routines */
1199 /******************************************************************************/
1203 AscWriteEEPCmdReg(bus_space_tag_t iot
, bus_space_handle_t ioh
, u_int8_t cmd_reg
)
1211 ASC_SET_CHIP_EEP_CMD(iot
, ioh
, cmd_reg
);
1212 DvcSleepMilliSecond(1);
1213 read_back
= ASC_GET_CHIP_EEP_CMD(iot
, ioh
);
1214 if (read_back
== cmd_reg
)
1217 if (retry
++ > ASC_EEP_MAX_RETRY
)
1224 AscWriteEEPDataReg(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1227 u_int16_t read_back
;
1232 ASC_SET_CHIP_EEP_DATA(iot
, ioh
, data_reg
);
1233 DvcSleepMilliSecond(1);
1234 read_back
= ASC_GET_CHIP_EEP_DATA(iot
, ioh
);
1235 if (read_back
== data_reg
)
1238 if (retry
++ > ASC_EEP_MAX_RETRY
)
1245 AscWaitEEPRead(void)
1248 DvcSleepMilliSecond(1);
1253 AscWaitEEPWrite(void)
1256 DvcSleepMilliSecond(1);
1261 AscReadEEPWord(bus_space_tag_t iot
, bus_space_handle_t ioh
, u_int8_t addr
)
1263 u_int16_t read_wval
;
1266 AscWriteEEPCmdReg(iot
, ioh
, ASC_EEP_CMD_WRITE_DISABLE
);
1268 cmd_reg
= addr
| ASC_EEP_CMD_READ
;
1269 AscWriteEEPCmdReg(iot
, ioh
, cmd_reg
);
1271 read_wval
= ASC_GET_CHIP_EEP_DATA(iot
, ioh
);
1279 AscWriteEEPWord(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1280 u_int8_t addr
, u_int16_t word_val
)
1282 u_int16_t read_wval
;
1284 read_wval
= AscReadEEPWord(iot
, ioh
, addr
);
1285 if (read_wval
!= word_val
) {
1286 AscWriteEEPCmdReg(iot
, ioh
, ASC_EEP_CMD_WRITE_ABLE
);
1288 AscWriteEEPDataReg(iot
, ioh
, word_val
);
1290 AscWriteEEPCmdReg(iot
, ioh
, ASC_EEP_CMD_WRITE
| addr
);
1292 AscWriteEEPCmdReg(iot
, ioh
, ASC_EEP_CMD_WRITE_DISABLE
);
1294 return (AscReadEEPWord(iot
, ioh
, addr
));
1301 AscGetEEPConfig(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1302 ASCEEP_CONFIG
*cfg_buf
, u_int16_t bus_type
)
1313 wbuf
= (u_int16_t
*) cfg_buf
;
1317 for (s_addr
= 0; s_addr
< (2 + isa_pnp_wsize
); s_addr
++, wbuf
++) {
1318 wval
= AscReadEEPWord(iot
, ioh
, s_addr
);
1323 if (bus_type
& ASC_IS_VL
) {
1324 cfg_beg
= ASC_EEP_DVC_CFG_BEG_VL
;
1325 cfg_end
= ASC_EEP_MAX_DVC_ADDR_VL
;
1327 cfg_beg
= ASC_EEP_DVC_CFG_BEG
;
1328 cfg_end
= ASC_EEP_MAX_DVC_ADDR
;
1331 for (s_addr
= cfg_beg
; s_addr
<= (cfg_end
- 1); s_addr
++, wbuf
++) {
1332 wval
= AscReadEEPWord(iot
, ioh
, s_addr
);
1337 *wbuf
= AscReadEEPWord(iot
, ioh
, s_addr
);
1344 AscSetEEPConfig(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1345 ASCEEP_CONFIG
*cfg_buf
, u_int16_t bus_type
)
1352 if ((n_error
= AscSetEEPConfigOnce(iot
, ioh
, cfg_buf
, bus_type
)) == 0)
1355 if (++retry
> ASC_EEP_MAX_RETRY
)
1364 AscSetEEPConfigOnce(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1365 ASCEEP_CONFIG
*cfg_buf
, u_int16_t bus_type
)
1374 wbuf
= (u_int16_t
*) cfg_buf
;
1378 for (s_addr
= 0; s_addr
< 2; s_addr
++, wbuf
++) {
1380 if (*wbuf
!= AscWriteEEPWord(iot
, ioh
, s_addr
, *wbuf
))
1384 if (bus_type
& ASC_IS_VL
) {
1385 cfg_beg
= ASC_EEP_DVC_CFG_BEG_VL
;
1386 cfg_end
= ASC_EEP_MAX_DVC_ADDR_VL
;
1388 cfg_beg
= ASC_EEP_DVC_CFG_BEG
;
1389 cfg_end
= ASC_EEP_MAX_DVC_ADDR
;
1392 for (s_addr
= cfg_beg
; s_addr
<= (cfg_end
- 1); s_addr
++, wbuf
++) {
1394 if (*wbuf
!= AscWriteEEPWord(iot
, ioh
, s_addr
, *wbuf
))
1399 if (sum
!= AscWriteEEPWord(iot
, ioh
, s_addr
, sum
))
1402 wbuf
= (u_int16_t
*) cfg_buf
;
1403 for (s_addr
= 0; s_addr
< 2; s_addr
++, wbuf
++) {
1404 if (*wbuf
!= AscReadEEPWord(iot
, ioh
, s_addr
))
1408 for (s_addr
= cfg_beg
; s_addr
<= cfg_end
; s_addr
++, wbuf
++) {
1409 if (*wbuf
!= AscReadEEPWord(iot
, ioh
, s_addr
))
1419 AscPrintEEPConfig(ASCEEP_CONFIG
*eep_config
, u_int16_t chksum
)
1421 printf("---- ASC EEprom settings ----\n");
1422 printf("cfg_lsw = 0x%x\n", eep_config
->cfg_lsw
);
1423 printf("cfg_msw = 0x%x\n", eep_config
->cfg_msw
);
1424 printf("init_sdtr = 0x%x\n", eep_config
->init_sdtr
);
1425 printf("disc_enable = 0x%x\n", eep_config
->disc_enable
);
1426 printf("use_cmd_qng = %d\n", eep_config
->use_cmd_qng
);
1427 printf("start_motor = 0x%x\n", eep_config
->start_motor
);
1428 printf("max_total_qng = 0x%x\n", eep_config
->max_total_qng
);
1429 printf("max_tag_qng = 0x%x\n", eep_config
->max_tag_qng
);
1430 printf("bios_scan = 0x%x\n", eep_config
->bios_scan
);
1431 printf("power_up_wait = 0x%x\n", eep_config
->power_up_wait
);
1432 printf("no_scam = %d\n", eep_config
->no_scam
);
1433 printf("chip_scsi_id = %d\n", eep_config
->chip_scsi_id
);
1434 printf("isa_dma_speed = %d\n", eep_config
->isa_dma_speed
);
1435 printf("cntl = 0x%x\n", eep_config
->cntl
);
1436 #if BYTE_ORDER == BIG_ENDIAN
1437 printf("adapter_info[0] = 0x%x\n", eep_config
->adapter_info
[1]);
1438 printf("adapter_info[1] = 0x%x\n", eep_config
->adapter_info
[0]);
1439 printf("adapter_info[2] = 0x%x\n", eep_config
->adapter_info
[3]);
1440 printf("adapter_info[3] = 0x%x\n", eep_config
->adapter_info
[2]);
1441 printf("adapter_info[4] = 0x%x\n", eep_config
->adapter_info
[5]);
1442 printf("adapter_info[5] = 0x%x\n", eep_config
->adapter_info
[4]);
1444 printf("adapter_info[0] = 0x%x\n", eep_config
->adapter_info
[0]);
1445 printf("adapter_info[1] = 0x%x\n", eep_config
->adapter_info
[1]);
1446 printf("adapter_info[2] = 0x%x\n", eep_config
->adapter_info
[2]);
1447 printf("adapter_info[3] = 0x%x\n", eep_config
->adapter_info
[3]);
1448 printf("adapter_info[4] = 0x%x\n", eep_config
->adapter_info
[4]);
1449 printf("adapter_info[5] = 0x%x\n", eep_config
->adapter_info
[5]);
1451 printf("checksum = 0x%x\n", eep_config
->chksum
);
1452 printf("calculated checksum = 0x%x\n", chksum
);
1453 printf("-----------------------------\n");
1458 /******************************************************************************/
1459 /* Interrupt routines */
1460 /******************************************************************************/
1464 AscISR(ASC_SOFTC
*sc
)
1466 bus_space_tag_t iot
= sc
->sc_iot
;
1467 bus_space_handle_t ioh
= sc
->sc_ioh
;
1469 u_int16_t saved_ram_addr
;
1471 u_int8_t saved_ctrl_reg
;
1477 int_pending
= FALSE
;
1479 ctrl_reg
= ASC_GET_CHIP_CONTROL(iot
, ioh
);
1480 saved_ctrl_reg
= ctrl_reg
& (~(ASC_CC_SCSI_RESET
| ASC_CC_CHIP_RESET
|
1481 ASC_CC_SINGLE_STEP
| ASC_CC_DIAG
| ASC_CC_TEST
));
1482 chipstat
= ASC_GET_CHIP_STATUS(iot
, ioh
);
1483 if (chipstat
& ASC_CSW_SCSI_RESET_LATCH
) {
1484 if (!(sc
->bus_type
& (ASC_IS_VL
| ASC_IS_EISA
))) {
1487 saved_ctrl_reg
&= (u_int8_t
) (~ASC_CC_HALT
);
1489 while (ASC_GET_CHIP_STATUS(iot
, ioh
) & ASC_CSW_SCSI_RESET_ACTIVE
);
1491 ASC_SET_CHIP_CONTROL(iot
, ioh
, (ASC_CC_CHIP_RESET
| ASC_CC_HALT
));
1492 ASC_SET_CHIP_CONTROL(iot
, ioh
, ASC_CC_HALT
);
1493 ASC_SET_CHIP_STATUS(iot
, ioh
, ASC_CIW_CLR_SCSI_RESET_INT
);
1494 ASC_SET_CHIP_STATUS(iot
, ioh
, 0);
1495 chipstat
= ASC_GET_CHIP_STATUS(iot
, ioh
);
1498 saved_ram_addr
= ASC_GET_CHIP_LRAM_ADDR(iot
, ioh
);
1499 host_flag
= AscReadLramByte(iot
, ioh
, ASCV_HOST_FLAG_B
) &
1500 (u_int8_t
) (~ASC_HOST_FLAG_IN_ISR
);
1501 AscWriteLramByte(iot
, ioh
, ASCV_HOST_FLAG_B
,
1502 (host_flag
| ASC_HOST_FLAG_IN_ISR
));
1504 if ((chipstat
& ASC_CSW_INT_PENDING
) || (int_pending
)) {
1505 AscAckInterrupt(iot
, ioh
);
1508 if ((chipstat
& ASC_CSW_HALTED
) &&
1509 (ctrl_reg
& ASC_CC_SINGLE_STEP
)) {
1510 AscIsrChipHalted(sc
);
1511 saved_ctrl_reg
&= ~ASC_CC_HALT
;
1513 if (sc
->dvc_cntl
& ASC_CNTL_INT_MULTI_Q
) {
1514 while (((status
= AscIsrQDone(sc
)) & 0x01) != 0);
1517 if ((status
= AscIsrQDone(sc
)) == 1)
1519 } while (status
== 0x11);
1526 AscWriteLramByte(iot
, ioh
, ASCV_HOST_FLAG_B
, host_flag
);
1527 ASC_SET_CHIP_LRAM_ADDR(iot
, ioh
, saved_ram_addr
);
1528 ASC_SET_CHIP_CONTROL(iot
, ioh
, saved_ctrl_reg
);
1531 /* return(int_pending); */
1536 AscIsrQDone(ASC_SOFTC
*sc
)
1540 u_int8_t sg_list_qp
;
1541 u_int8_t sg_queue_cnt
;
1543 u_int8_t done_q_tail
;
1545 ASC_SCSI_BIT_ID_TYPE scsi_busy
;
1546 ASC_SCSI_BIT_ID_TYPE target_id
;
1547 bus_space_tag_t iot
= sc
->sc_iot
;
1548 bus_space_handle_t ioh
= sc
->sc_ioh
;
1550 u_int16_t sg_q_addr
;
1551 u_int8_t cur_target_qng
;
1552 ASC_QDONE_INFO scsiq_buf
;
1553 ASC_QDONE_INFO
*scsiq
;
1554 ASC_ISR_CALLBACK asc_isr_callback
;
1557 asc_isr_callback
= (ASC_ISR_CALLBACK
) sc
->isr_callback
;
1559 scsiq
= (ASC_QDONE_INFO
*) & scsiq_buf
;
1560 done_q_tail
= ASC_GET_VAR_DONE_QTAIL(iot
, ioh
);
1561 q_addr
= ASC_QNO_TO_QADDR(done_q_tail
);
1562 next_qp
= AscReadLramByte(iot
, ioh
, (q_addr
+ ASC_SCSIQ_B_FWD
));
1564 if (next_qp
!= ASC_QLINK_END
) {
1565 ASC_PUT_VAR_DONE_QTAIL(iot
, ioh
, next_qp
);
1566 q_addr
= ASC_QNO_TO_QADDR(next_qp
);
1567 sg_queue_cnt
= _AscCopyLramScsiDoneQ(iot
, ioh
, q_addr
, scsiq
,
1569 AscWriteLramByte(iot
, ioh
, (q_addr
+ ASC_SCSIQ_B_STATUS
),
1570 (scsiq
->q_status
& ~(ASC_QS_READY
| ASC_QS_ABORTED
)));
1571 tid_no
= ASC_TIX_TO_TID(scsiq
->d2
.target_ix
);
1572 target_id
= ASC_TIX_TO_TARGET_ID(scsiq
->d2
.target_ix
);
1573 if ((scsiq
->cntl
& ASC_QC_SG_HEAD
) != 0) {
1575 sg_list_qp
= next_qp
;
1576 for (q_cnt
= 0; q_cnt
< sg_queue_cnt
; q_cnt
++) {
1577 sg_list_qp
= AscReadLramByte(iot
, ioh
,
1578 sg_q_addr
+ ASC_SCSIQ_B_FWD
);
1579 sg_q_addr
= ASC_QNO_TO_QADDR(sg_list_qp
);
1580 if (sg_list_qp
== ASC_QLINK_END
) {
1581 AscSetLibErrorCode(sc
, ASCQ_ERR_SG_Q_LINKS
);
1582 scsiq
->d3
.done_stat
= ASC_QD_WITH_ERROR
;
1583 scsiq
->d3
.host_stat
= ASC_QHSTA_D_QDONE_SG_LIST_CORRUPTED
;
1584 panic("AscIsrQDone: Corrupted SG list encountered");
1586 AscWriteLramByte(iot
, ioh
,
1587 sg_q_addr
+ ASC_SCSIQ_B_STATUS
, ASC_QS_FREE
);
1589 n_q_used
= sg_queue_cnt
+ 1;
1590 ASC_PUT_VAR_DONE_QTAIL(iot
, ioh
, sg_list_qp
);
1592 if (sc
->queue_full_or_busy
& target_id
) {
1593 cur_target_qng
= AscReadLramByte(iot
, ioh
,
1594 ASC_QADR_BEG
+ scsiq
->d2
.target_ix
);
1596 if (cur_target_qng
< sc
->max_dvc_qng
[tid_no
]) {
1597 scsi_busy
= AscReadLramByte(iot
, ioh
, ASCV_SCSIBUSY_B
);
1598 scsi_busy
&= ~target_id
;
1599 AscWriteLramByte(iot
, ioh
, ASCV_SCSIBUSY_B
, scsi_busy
);
1600 sc
->queue_full_or_busy
&= ~target_id
;
1603 if (sc
->cur_total_qng
>= n_q_used
) {
1604 sc
->cur_total_qng
-= n_q_used
;
1605 if (sc
->cur_dvc_qng
[tid_no
] != 0) {
1606 sc
->cur_dvc_qng
[tid_no
]--;
1609 AscSetLibErrorCode(sc
, ASCQ_ERR_CUR_QNG
);
1610 scsiq
->d3
.done_stat
= ASC_QD_WITH_ERROR
;
1611 panic("AscIsrQDone: Attempting to free more queues than are active");
1614 if ((adv_ccb_phys_kv(sc
, scsiq
->d2
.ccb_ptr
) == 0UL) ||
1615 ((scsiq
->q_status
& ASC_QS_ABORTED
) != 0)) {
1617 } else if (scsiq
->q_status
== ASC_QS_DONE
) {
1618 scsiq
->remain_bytes
+= scsiq
->extra_bytes
;
1620 if (scsiq
->d3
.done_stat
== ASC_QD_WITH_ERROR
) {
1621 if (scsiq
->d3
.host_stat
== ASC_QHSTA_M_DATA_OVER_RUN
) {
1622 if ((scsiq
->cntl
& (ASC_QC_DATA_IN
| ASC_QC_DATA_OUT
)) == 0) {
1623 scsiq
->d3
.done_stat
= ASC_QD_NO_ERROR
;
1624 scsiq
->d3
.host_stat
= ASC_QHSTA_NO_ERROR
;
1626 } else if (scsiq
->d3
.host_stat
== ASC_QHSTA_M_HUNG_REQ_SCSI_BUS_RESET
) {
1627 AscStopChip(iot
, ioh
);
1628 ASC_SET_CHIP_CONTROL(iot
, ioh
, (ASC_CC_SCSI_RESET
| ASC_CC_HALT
));
1629 DvcDelayNanoSecond(60000);
1630 ASC_SET_CHIP_CONTROL(iot
, ioh
, ASC_CC_HALT
);
1631 ASC_SET_CHIP_STATUS(iot
, ioh
, ASC_CIW_CLR_SCSI_RESET_INT
);
1632 ASC_SET_CHIP_STATUS(iot
, ioh
, 0);
1633 ASC_SET_CHIP_CONTROL(iot
, ioh
, 0);
1636 (*asc_isr_callback
) (sc
, scsiq
);
1640 AscSetLibErrorCode(sc
, ASCQ_ERR_Q_STATUS
);
1641 panic("AscIsrQDone: completed scsiq with unknown status");
1651 * handle all the conditions that may halt the board
1652 * waiting us to intervene
1655 AscIsrChipHalted(ASC_SOFTC
*sc
)
1657 bus_space_tag_t iot
= sc
->sc_iot
;
1658 bus_space_handle_t ioh
= sc
->sc_ioh
;
1660 u_int16_t int_halt_code
;
1661 u_int16_t halt_q_addr
;
1668 u_int8_t cur_dvc_qng
;
1670 u_int8_t scsi_status
;
1672 ASC_SCSI_BIT_ID_TYPE scsi_busy
;
1673 ASC_SCSI_BIT_ID_TYPE target_id
;
1676 int_halt_code
= AscReadLramWord(iot
, ioh
, ASCV_HALTCODE_W
);
1678 halt_qp
= AscReadLramByte(iot
, ioh
, ASCV_CURCDB_B
);
1679 halt_q_addr
= ASC_QNO_TO_QADDR(halt_qp
);
1680 target_ix
= AscReadLramByte(iot
, ioh
, halt_q_addr
+ ASC_SCSIQ_B_TARGET_IX
);
1681 q_cntl
= AscReadLramByte(iot
, ioh
, halt_q_addr
+ ASC_SCSIQ_B_CNTL
);
1682 tid_no
= ASC_TIX_TO_TID(target_ix
);
1683 target_id
= ASC_TID_TO_TARGET_ID(tid_no
);
1685 if (sc
->pci_fix_asyn_xfer
& target_id
) {
1686 asyn_sdtr
= ASYN_SDTR_DATA_FIX_PCI_REV_AB
;
1691 if (int_halt_code
== ASC_HALT_DISABLE_ASYN_USE_SYN_FIX
) {
1692 if (sc
->pci_fix_asyn_xfer
& target_id
) {
1693 AscSetChipSDTR(iot
, ioh
, 0, tid_no
);
1694 sc
->sdtr_data
[tid_no
] = 0;
1696 AscWriteLramWord(iot
, ioh
, ASCV_HALTCODE_W
, 0);
1697 } else if (int_halt_code
== ASC_HALT_ENABLE_ASYN_USE_SYN_FIX
) {
1698 if (sc
->pci_fix_asyn_xfer
& target_id
) {
1699 AscSetChipSDTR(iot
, ioh
, asyn_sdtr
, tid_no
);
1700 sc
->sdtr_data
[tid_no
] = asyn_sdtr
;
1702 AscWriteLramWord(iot
, ioh
, ASCV_HALTCODE_W
, 0);
1703 } else if (int_halt_code
== ASC_HALT_EXTMSG_IN
) {
1704 AscHandleExtMsgIn(sc
, halt_q_addr
, q_cntl
, target_id
,
1706 AscWriteLramWord(iot
, ioh
, ASCV_HALTCODE_W
, 0);
1707 } else if (int_halt_code
== ASC_HALT_CHK_CONDITION
) {
1708 q_cntl
|= ASC_QC_REQ_SENSE
;
1710 if (sc
->init_sdtr
& target_id
) {
1711 sc
->sdtr_done
&= ~target_id
;
1713 sdtr_data
= ASC_GET_MCODE_INIT_SDTR_AT_ID(iot
, ioh
, tid_no
);
1714 q_cntl
|= ASC_QC_MSG_OUT
;
1715 AscMsgOutSDTR(sc
, sc
->sdtr_period_tbl
[(sdtr_data
>> 4) &
1716 (sc
->max_sdtr_index
- 1)],
1717 (sdtr_data
& ASC_SYN_MAX_OFFSET
));
1719 AscWriteLramByte(iot
, ioh
, halt_q_addr
+ ASC_SCSIQ_B_CNTL
, q_cntl
);
1721 tag_code
= AscReadLramByte(iot
, ioh
, halt_q_addr
+ ASC_SCSIQ_B_TAG_CODE
);
1724 if ((sc
->pci_fix_asyn_xfer
& target_id
) &&
1725 !(sc
->pci_fix_asyn_xfer_always
& target_id
)) {
1726 tag_code
|= (ASC_TAG_FLAG_DISABLE_DISCONNECT
|
1727 ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX
);
1729 AscWriteLramByte(iot
, ioh
, halt_q_addr
+ ASC_SCSIQ_B_TAG_CODE
, tag_code
);
1731 q_status
= AscReadLramByte(iot
, ioh
, halt_q_addr
+ ASC_SCSIQ_B_STATUS
);
1732 q_status
|= ASC_QS_READY
| ASC_QS_BUSY
;
1734 AscWriteLramByte(iot
, ioh
, halt_q_addr
+ ASC_SCSIQ_B_STATUS
, q_status
);
1736 scsi_busy
= AscReadLramByte(iot
, ioh
, ASCV_SCSIBUSY_B
);
1737 scsi_busy
&= ~target_id
;
1738 AscWriteLramByte(iot
, ioh
, ASCV_SCSIBUSY_B
, scsi_busy
);
1740 AscWriteLramWord(iot
, ioh
, ASCV_HALTCODE_W
, 0);
1741 } else if (int_halt_code
== ASC_HALT_SDTR_REJECTED
) {
1742 AscMemWordCopyFromLram(iot
, ioh
, ASCV_MSGOUT_BEG
,
1743 (u_int16_t
*) & out_msg
, sizeof(EXT_MSG
) >> 1);
1745 if ((out_msg
.msg_type
== MS_EXTEND
) &&
1746 (out_msg
.msg_len
== MS_SDTR_LEN
) &&
1747 (out_msg
.msg_req
== MS_SDTR_CODE
)) {
1748 sc
->init_sdtr
&= ~target_id
;
1749 sc
->sdtr_done
&= ~target_id
;
1750 AscSetChipSDTR(iot
, ioh
, asyn_sdtr
, tid_no
);
1751 sc
->sdtr_data
[tid_no
] = asyn_sdtr
;
1753 q_cntl
&= ~ASC_QC_MSG_OUT
;
1754 AscWriteLramByte(iot
, ioh
, halt_q_addr
+ ASC_SCSIQ_B_CNTL
, q_cntl
);
1755 AscWriteLramWord(iot
, ioh
, ASCV_HALTCODE_W
, 0);
1756 } else if (int_halt_code
== ASC_HALT_SS_QUEUE_FULL
) {
1757 scsi_status
= AscReadLramByte(iot
, ioh
,
1758 halt_q_addr
+ ASC_SCSIQ_SCSI_STATUS
);
1759 cur_dvc_qng
= AscReadLramByte(iot
, ioh
, target_ix
+ ASC_QADR_BEG
);
1761 if ((cur_dvc_qng
> 0) && (sc
->cur_dvc_qng
[tid_no
] > 0)) {
1762 scsi_busy
= AscReadLramByte(iot
, ioh
, ASCV_SCSIBUSY_B
);
1763 scsi_busy
|= target_id
;
1764 AscWriteLramByte(iot
, ioh
, ASCV_SCSIBUSY_B
, scsi_busy
);
1765 sc
->queue_full_or_busy
|= target_id
;
1767 if (scsi_status
== SS_QUEUE_FULL
) {
1768 if (cur_dvc_qng
> ASC_MIN_TAGGED_CMD
) {
1770 sc
->max_dvc_qng
[tid_no
] = cur_dvc_qng
;
1772 AscWriteLramByte(iot
, ioh
,
1773 tid_no
+ ASCV_MAX_DVC_QNG_BEG
, cur_dvc_qng
);
1775 #if ASC_QUEUE_FLOW_CONTROL
1776 if ((sc
->device
[tid_no
] != NULL
) &&
1777 (sc
->device
[tid_no
]->queue_curr_depth
> cur_dvc_qng
)) {
1778 sc
->device
[tid_no
]->queue_curr_depth
= cur_dvc_qng
;
1780 #endif /* ASC_QUEUE_FLOW_CONTROL */
1784 AscWriteLramWord(iot
, ioh
, ASCV_HALTCODE_W
, 0);
1791 AscWaitTixISRDone(ASC_SOFTC
*sc
, u_int8_t target_ix
)
1797 tid_no
= ASC_TIX_TO_TID(target_ix
);
1799 if ((cur_req
= sc
->cur_dvc_qng
[tid_no
]) == 0)
1802 DvcSleepMilliSecond(1000L);
1803 if (sc
->cur_dvc_qng
[tid_no
] == cur_req
)
1810 AscWaitISRDone(ASC_SOFTC
*sc
)
1814 for (tid
= 0; tid
<= ASC_MAX_TID
; tid
++)
1815 AscWaitTixISRDone(sc
, ASC_TID_TO_TIX(tid
));
1822 _AscCopyLramScsiDoneQ(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1823 u_int16_t q_addr
, ASC_QDONE_INFO
*scsiq
, u_int32_t max_dma_count
)
1826 u_int8_t sg_queue_cnt
;
1828 AscGetQDoneInfo(iot
, ioh
, q_addr
+ ASC_SCSIQ_DONE_INFO_BEG
, scsiq
);
1830 _val
= AscReadLramWord(iot
, ioh
, q_addr
+ ASC_SCSIQ_B_STATUS
);
1831 scsiq
->q_status
= LO_BYTE(_val
);
1832 scsiq
->q_no
= HI_BYTE(_val
);
1833 _val
= AscReadLramWord(iot
, ioh
, q_addr
+ ASC_SCSIQ_B_CNTL
);
1834 scsiq
->cntl
= LO_BYTE(_val
);
1835 sg_queue_cnt
= HI_BYTE(_val
);
1836 _val
= AscReadLramWord(iot
, ioh
, q_addr
+ ASC_SCSIQ_B_SENSE_LEN
);
1837 scsiq
->sense_len
= LO_BYTE(_val
);
1838 scsiq
->extra_bytes
= HI_BYTE(_val
);
1839 scsiq
->remain_bytes
= AscReadLramWord(iot
, ioh
,
1840 q_addr
+ ASC_SCSIQ_DW_REMAIN_XFER_CNT
);
1841 scsiq
->remain_bytes
&= max_dma_count
;
1843 return (sg_queue_cnt
);
1848 AscGetQDoneInfo(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1849 u_int16_t addr
, ASC_QDONE_INFO
*scsiq
)
1853 ASC_SET_CHIP_LRAM_ADDR(iot
, ioh
, addr
);
1855 val
= ASC_GET_CHIP_LRAM_DATA(iot
, ioh
);
1856 scsiq
->d2
.ccb_ptr
= MAKELONG(val
, ASC_GET_CHIP_LRAM_DATA(iot
, ioh
));
1857 val
= ASC_GET_CHIP_LRAM_DATA(iot
, ioh
);
1858 scsiq
->d2
.target_ix
= LO_BYTE(val
);
1859 scsiq
->d2
.flag
= HI_BYTE(val
);
1860 val
= ASC_GET_CHIP_LRAM_DATA(iot
, ioh
);
1861 scsiq
->d2
.cdb_len
= LO_BYTE(val
);
1862 scsiq
->d2
.tag_code
= HI_BYTE(val
);
1863 scsiq
->d2
.vm_id
= ASC_GET_CHIP_LRAM_DATA(iot
, ioh
);
1865 val
= ASC_GET_CHIP_LRAM_DATA(iot
, ioh
);
1866 scsiq
->d3
.done_stat
= LO_BYTE(val
);
1867 scsiq
->d3
.host_stat
= HI_BYTE(val
);
1868 val
= ASC_GET_CHIP_LRAM_DATA(iot
, ioh
);
1869 scsiq
->d3
.scsi_stat
= LO_BYTE(val
);
1870 scsiq
->d3
.scsi_msg
= HI_BYTE(val
);
1875 AscToggleIRQAct(bus_space_tag_t iot
, bus_space_handle_t ioh
)
1878 ASC_SET_CHIP_STATUS(iot
, ioh
, ASC_CIW_IRQ_ACT
);
1879 ASC_SET_CHIP_STATUS(iot
, ioh
, 0);
1884 AscDisableInterrupt(bus_space_tag_t iot
, bus_space_handle_t ioh
)
1888 cfg
= ASC_GET_CHIP_CFG_LSW(iot
, ioh
);
1889 ASC_SET_CHIP_CFG_LSW(iot
, ioh
, cfg
& (~ASC_CFG0_HOST_INT_ON
));
1894 AscEnableInterrupt(bus_space_tag_t iot
, bus_space_handle_t ioh
)
1898 cfg
= ASC_GET_CHIP_CFG_LSW(iot
, ioh
);
1899 ASC_SET_CHIP_CFG_LSW(iot
, ioh
, cfg
| ASC_CFG0_HOST_INT_ON
);
1904 AscGetChipIRQ(bus_space_tag_t iot
, bus_space_handle_t ioh
, u_int16_t bus_type
)
1911 if (bus_type
& ASC_IS_EISA
) {
1912 cfg_lsw
= AscGetEisaChipCfg(iot
, ioh
);
1913 chip_irq
= ((cfg_lsw
>> 8) & 0x07) + 10;
1914 if((chip_irq
== 13) || (chip_irq
> 15))
1919 if ((bus_type
& ASC_IS_VL
) != 0) {
1920 cfg_lsw
= ASC_GET_CHIP_CFG_LSW(iot
, ioh
);
1921 chip_irq
= (cfg_lsw
>> 2) & 0x07;
1922 if ((chip_irq
== 0) ||
1927 return (chip_irq
+ (ASC_MIN_IRQ_NO
- 1));
1929 cfg_lsw
= ASC_GET_CHIP_CFG_LSW(iot
, ioh
);
1930 chip_irq
= (cfg_lsw
>> 2) & 0x03;
1933 return (chip_irq
+ ASC_MIN_IRQ_NO
);
1938 AscSetChipIRQ(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1939 u_int8_t irq_no
, u_int16_t bus_type
)
1944 if (bus_type
& ASC_IS_VL
) {
1946 if ((irq_no
< ASC_MIN_IRQ_NO
) || (irq_no
> ASC_MAX_IRQ_NO
))
1949 irq_no
-= ASC_MIN_IRQ_NO
- 1;
1952 cfg_lsw
= ASC_GET_CHIP_CFG_LSW(iot
, ioh
) & 0xFFE3;
1954 ASC_SET_CHIP_CFG_LSW(iot
, ioh
, cfg_lsw
);
1955 AscToggleIRQAct(iot
, ioh
);
1956 cfg_lsw
= ASC_GET_CHIP_CFG_LSW(iot
, ioh
) & 0xFFE0;
1957 cfg_lsw
|= (irq_no
& 0x07) << 2;
1958 ASC_SET_CHIP_CFG_LSW(iot
, ioh
, cfg_lsw
);
1959 AscToggleIRQAct(iot
, ioh
);
1961 return (AscGetChipIRQ(iot
, ioh
, bus_type
));
1963 if (bus_type
& ASC_IS_ISA
) {
1966 irq_no
-= ASC_MIN_IRQ_NO
;
1967 cfg_lsw
= ASC_GET_CHIP_CFG_LSW(iot
, ioh
) & 0xFFF3;
1968 cfg_lsw
|= (irq_no
& 0x03) << 2;
1969 ASC_SET_CHIP_CFG_LSW(iot
, ioh
, cfg_lsw
);
1971 return (AscGetChipIRQ(iot
, ioh
, bus_type
));
1978 AscAckInterrupt(bus_space_tag_t iot
, bus_space_handle_t ioh
)
1987 risc_flag
= AscReadLramByte(iot
, ioh
, ASCV_RISC_FLAG_B
);
1988 if (loop
++ > 0x7FFF)
1990 } while ((risc_flag
& ASC_RISC_FLAG_GEN_INT
) != 0);
1992 host_flag
= AscReadLramByte(iot
, ioh
, ASCV_HOST_FLAG_B
) &
1993 (~ASC_HOST_FLAG_ACK_INT
);
1994 AscWriteLramByte(iot
, ioh
, ASCV_HOST_FLAG_B
,
1995 host_flag
| ASC_HOST_FLAG_ACK_INT
);
1996 ASC_SET_CHIP_STATUS(iot
, ioh
, ASC_CIW_INT_ACK
);
1999 while (ASC_GET_CHIP_STATUS(iot
, ioh
) & ASC_CSW_INT_PENDING
) {
2000 ASC_SET_CHIP_STATUS(iot
, ioh
, ASC_CIW_INT_ACK
);
2005 AscWriteLramByte(iot
, ioh
, ASCV_HOST_FLAG_B
, host_flag
);
2010 AscGetMaxDmaCount(u_int16_t bus_type
)
2012 if (bus_type
& ASC_IS_ISA
)
2013 return (ASC_MAX_ISA_DMA_COUNT
);
2014 else if (bus_type
& (ASC_IS_EISA
| ASC_IS_VL
))
2015 return (ASC_MAX_VL_DMA_COUNT
);
2016 return (ASC_MAX_PCI_DMA_COUNT
);
2021 AscGetIsaDmaChannel(bus_space_tag_t iot
, bus_space_handle_t ioh
)
2025 channel
= ASC_GET_CHIP_CFG_LSW(iot
, ioh
) & 0x0003;
2026 if (channel
== 0x03)
2028 else if (channel
== 0x00)
2030 return (channel
+ 4);
2035 AscSetIsaDmaChannel(bus_space_tag_t iot
, bus_space_handle_t ioh
,
2036 u_int16_t dma_channel
)
2041 if ((dma_channel
>= 5) && (dma_channel
<= 7)) {
2042 if (dma_channel
== 7)
2045 value
= dma_channel
- 4;
2046 cfg_lsw
= ASC_GET_CHIP_CFG_LSW(iot
, ioh
) & 0xFFFC;
2048 ASC_SET_CHIP_CFG_LSW(iot
, ioh
, cfg_lsw
);
2049 return (AscGetIsaDmaChannel(iot
, ioh
));
2056 AscGetIsaDmaSpeed(bus_space_tag_t iot
, bus_space_handle_t ioh
)
2058 u_int8_t speed_value
;
2060 AscSetBank(iot
, ioh
, 1);
2061 speed_value
= ASC_READ_CHIP_DMA_SPEED(iot
, ioh
);
2062 speed_value
&= 0x07;
2063 AscSetBank(iot
, ioh
, 0);
2064 return (speed_value
);
2069 AscSetIsaDmaSpeed(bus_space_tag_t iot
, bus_space_handle_t ioh
,
2070 u_int8_t speed_value
)
2072 speed_value
&= 0x07;
2073 AscSetBank(iot
, ioh
, 1);
2074 ASC_WRITE_CHIP_DMA_SPEED(iot
, ioh
, speed_value
);
2075 AscSetBank(iot
, ioh
, 0);
2076 return (AscGetIsaDmaSpeed(iot
, ioh
));
2080 /******************************************************************************/
2081 /* Messages routines */
2082 /******************************************************************************/
2086 AscHandleExtMsgIn(ASC_SOFTC
*sc
, u_int16_t halt_q_addr
, u_int8_t q_cntl
,
2087 ASC_SCSI_BIT_ID_TYPE target_id
, int tid_no
, u_int8_t asyn_sdtr
)
2089 bus_space_tag_t iot
= sc
->sc_iot
;
2090 bus_space_handle_t ioh
= sc
->sc_ioh
;
2096 AscMemWordCopyFromLram(iot
, ioh
, ASCV_MSGIN_BEG
,
2097 (u_int16_t
*) & ext_msg
, sizeof(EXT_MSG
) >> 1);
2099 if (ext_msg
.msg_type
== MS_EXTEND
&&
2100 ext_msg
.msg_req
== MS_SDTR_CODE
&&
2101 ext_msg
.msg_len
== MS_SDTR_LEN
) {
2104 if (ext_msg
.req_ack_offset
> ASC_SYN_MAX_OFFSET
) {
2105 sdtr_accept
= FALSE
;
2106 ext_msg
.req_ack_offset
= ASC_SYN_MAX_OFFSET
;
2108 if ((ext_msg
.xfer_period
<
2109 sc
->sdtr_period_tbl
[sc
->host_init_sdtr_index
]) ||
2110 (ext_msg
.xfer_period
>
2111 sc
->sdtr_period_tbl
[sc
->max_sdtr_index
])) {
2112 sdtr_accept
= FALSE
;
2113 ext_msg
.xfer_period
= sc
->sdtr_period_tbl
[sc
->host_init_sdtr_index
];
2116 sdtr_data
= AscCalSDTRData(sc
, ext_msg
.xfer_period
,
2117 ext_msg
.req_ack_offset
);
2118 if (sdtr_data
== 0xFF) {
2119 q_cntl
|= ASC_QC_MSG_OUT
;
2120 sc
->init_sdtr
&= ~target_id
;
2121 sc
->sdtr_done
&= ~target_id
;
2122 AscSetChipSDTR(iot
, ioh
, asyn_sdtr
, tid_no
);
2123 sc
->sdtr_data
[tid_no
] = asyn_sdtr
;
2126 if (ext_msg
.req_ack_offset
== 0) {
2127 q_cntl
&= ~ASC_QC_MSG_OUT
;
2128 sc
->init_sdtr
&= ~target_id
;
2129 sc
->sdtr_done
&= ~target_id
;
2130 AscSetChipSDTR(iot
, ioh
, asyn_sdtr
, tid_no
);
2132 if (sdtr_accept
&& (q_cntl
& ASC_QC_MSG_OUT
)) {
2133 q_cntl
&= ~ASC_QC_MSG_OUT
;
2134 sc
->sdtr_done
|= target_id
;
2135 sc
->init_sdtr
|= target_id
;
2136 sc
->pci_fix_asyn_xfer
&= ~target_id
;
2137 sdtr_data
= AscCalSDTRData(sc
, ext_msg
.xfer_period
,
2138 ext_msg
.req_ack_offset
);
2139 AscSetChipSDTR(iot
, ioh
, sdtr_data
, tid_no
);
2140 sc
->sdtr_data
[tid_no
] = sdtr_data
;
2142 q_cntl
|= ASC_QC_MSG_OUT
;
2143 AscMsgOutSDTR(sc
, ext_msg
.xfer_period
,
2144 ext_msg
.req_ack_offset
);
2145 sc
->pci_fix_asyn_xfer
&= ~target_id
;
2146 sdtr_data
= AscCalSDTRData(sc
, ext_msg
.xfer_period
,
2147 ext_msg
.req_ack_offset
);
2148 AscSetChipSDTR(iot
, ioh
, sdtr_data
, tid_no
);
2149 sc
->sdtr_data
[tid_no
] = sdtr_data
;
2150 sc
->sdtr_done
|= target_id
;
2151 sc
->init_sdtr
|= target_id
;
2154 } else if (ext_msg
.msg_type
== MS_EXTEND
&&
2155 ext_msg
.msg_req
== MS_WDTR_CODE
&&
2156 ext_msg
.msg_len
== MS_WDTR_LEN
) {
2157 ext_msg
.wdtr_width
= 0;
2158 AscMemWordCopyToLram(iot
, ioh
, ASCV_MSGOUT_BEG
,
2159 (const u_int16_t
*) & ext_msg
, sizeof(EXT_MSG
) >> 1);
2160 q_cntl
|= ASC_QC_MSG_OUT
;
2162 ext_msg
.msg_type
= M1_MSG_REJECT
;
2163 AscMemWordCopyToLram(iot
, ioh
, ASCV_MSGOUT_BEG
,
2164 (const u_int16_t
*) & ext_msg
, sizeof(EXT_MSG
) >> 1);
2165 q_cntl
|= ASC_QC_MSG_OUT
;
2168 AscWriteLramByte(iot
, ioh
, halt_q_addr
+ ASC_SCSIQ_B_CNTL
, q_cntl
);
2173 AscMsgOutSDTR(ASC_SOFTC
*sc
, u_int8_t sdtr_period
, u_int8_t sdtr_offset
)
2175 bus_space_tag_t iot
= sc
->sc_iot
;
2176 bus_space_handle_t ioh
= sc
->sc_ioh
;
2178 u_int8_t sdtr_period_index
;
2181 sdtr_buf
.msg_type
= MS_EXTEND
;
2182 sdtr_buf
.msg_len
= MS_SDTR_LEN
;
2183 sdtr_buf
.msg_req
= MS_SDTR_CODE
;
2184 sdtr_buf
.xfer_period
= sdtr_period
;
2185 sdtr_offset
&= ASC_SYN_MAX_OFFSET
;
2186 sdtr_buf
.req_ack_offset
= sdtr_offset
;
2187 if ((sdtr_period_index
= AscGetSynPeriodIndex(sc
, sdtr_period
)) <=
2188 sc
->max_sdtr_index
) {
2189 AscMemWordCopyToLram(iot
, ioh
, ASCV_MSGOUT_BEG
,
2190 (const u_int16_t
*) & sdtr_buf
, sizeof(EXT_MSG
) >> 1);
2191 return ((sdtr_period_index
<< 4) | sdtr_offset
);
2193 sdtr_buf
.req_ack_offset
= 0;
2194 AscMemWordCopyToLram(iot
, ioh
, ASCV_MSGOUT_BEG
,
2195 (const u_int16_t
*) & sdtr_buf
, sizeof(EXT_MSG
) >> 1);
2201 /******************************************************************************/
2203 /******************************************************************************/
2207 AscSetChipSDTR(bus_space_tag_t iot
, bus_space_handle_t ioh
,
2208 u_int8_t sdtr_data
, u_int8_t tid_no
)
2210 AscSetChipSynRegAtID(iot
, ioh
, tid_no
, sdtr_data
);
2211 AscWriteLramByte(iot
, ioh
, tid_no
+ ASCV_SDTR_DONE_BEG
, sdtr_data
);
2216 AscCalSDTRData(ASC_SOFTC
*sc
, u_int8_t sdtr_period
, u_int8_t syn_offset
)
2219 u_int8_t sdtr_period_ix
;
2221 sdtr_period_ix
= AscGetSynPeriodIndex(sc
, sdtr_period
);
2222 if (sdtr_period_ix
> sc
->max_sdtr_index
)
2225 byte
= (sdtr_period_ix
<< 4) | (syn_offset
& ASC_SYN_MAX_OFFSET
);
2231 AscGetSynPeriodIndex(ASC_SOFTC
*sc
, u_int8_t syn_time
)
2233 u_int8_t
*period_table
;
2238 period_table
= sc
->sdtr_period_tbl
;
2239 max_index
= sc
->max_sdtr_index
;
2240 min_index
= sc
->host_init_sdtr_index
;
2241 if ((syn_time
<= period_table
[max_index
])) {
2242 for (i
= min_index
; i
< (max_index
- 1); i
++) {
2243 if (syn_time
<= period_table
[i
])
2249 return (max_index
+ 1);
2253 /******************************************************************************/
2254 /* Queue routines */
2255 /******************************************************************************/
2258 * Send a command to the board
2261 AscExeScsiQueue(ASC_SOFTC
*sc
, ASC_SCSI_Q
*scsiq
)
2263 bus_space_tag_t iot
= sc
->sc_iot
;
2264 bus_space_handle_t ioh
= sc
->sc_ioh
;
2265 ASC_SG_HEAD
*sg_head
= scsiq
->sg_head
;
2268 int disable_syn_offset_one_fix
;
2271 u_int16_t sg_entry_cnt
= 0;
2272 u_int16_t sg_entry_cnt_minus_one
= 0;
2276 u_int8_t extra_bytes
;
2282 if ((scsiq
->q2
.tag_code
& ASC_TAG_FLAG_EXTRA_BYTES
) == 0)
2283 scsiq
->q1
.extra_bytes
= 0;
2286 target_ix
= scsiq
->q2
.target_ix
;
2287 tid_no
= ASC_TIX_TO_TID(target_ix
);
2290 if (scsiq
->cdbptr
[0] == SCSICMD_RequestSense
)
2291 if ((sc
->init_sdtr
& scsiq
->q1
.target_id
) != 0) {
2292 sc
->sdtr_done
&= ~scsiq
->q1
.target_id
;
2293 sdtr_data
= ASC_GET_MCODE_INIT_SDTR_AT_ID(iot
, ioh
, tid_no
);
2294 AscMsgOutSDTR(sc
, sc
->sdtr_period_tbl
[(sdtr_data
>> 4) &
2295 (sc
->max_sdtr_index
- 1)],
2296 sdtr_data
& ASC_SYN_MAX_OFFSET
);
2297 scsiq
->q1
.cntl
|= (ASC_QC_MSG_OUT
| ASC_QC_URGENT
);
2300 * if there is just one segment into S/G list then
2301 * map it as it was a single request, filling
2302 * data_addr and data_cnt of ASC_SCSIQ structure.
2304 if ((scsiq
->q1
.cntl
& ASC_QC_SG_HEAD
) != 0) {
2305 sg_entry_cnt
= sg_head
->entry_cnt
;
2307 if (sg_entry_cnt
< 1)
2308 panic("AscExeScsiQueue: Queue with QC_SG_HEAD set but %d segs.",
2311 if (sg_entry_cnt
> ASC_MAX_SG_LIST
)
2312 panic("AscExeScsiQueue: Queue with too many segs.");
2314 if (sg_entry_cnt
== 1) {
2315 scsiq
->q1
.data_addr
= sg_head
->sg_list
[0].addr
;
2316 scsiq
->q1
.data_cnt
= sg_head
->sg_list
[0].bytes
;
2317 scsiq
->q1
.cntl
&= ~(ASC_QC_SG_HEAD
| ASC_QC_SG_SWAP_QUEUE
);
2319 sg_entry_cnt_minus_one
= sg_entry_cnt
- 1;
2321 scsi_cmd
= scsiq
->cdbptr
[0];
2322 disable_syn_offset_one_fix
= FALSE
;
2323 if ((sc
->pci_fix_asyn_xfer
& scsiq
->q1
.target_id
) &&
2324 !(sc
->pci_fix_asyn_xfer_always
& scsiq
->q1
.target_id
)) {
2325 if (scsiq
->q1
.cntl
& ASC_QC_SG_HEAD
) {
2327 for (i
= 0; i
< sg_entry_cnt
; i
++)
2328 data_cnt
+= sg_head
->sg_list
[i
].bytes
;
2330 data_cnt
= scsiq
->q1
.data_cnt
;
2333 if (data_cnt
!= 0ul) {
2334 if (data_cnt
< 512ul) {
2335 disable_syn_offset_one_fix
= TRUE
;
2337 if (scsi_cmd
== SCSICMD_Inquiry
||
2338 scsi_cmd
== SCSICMD_RequestSense
||
2339 scsi_cmd
== SCSICMD_ReadCapacity
||
2340 scsi_cmd
== SCSICMD_ReadTOC
||
2341 scsi_cmd
== SCSICMD_ModeSelect6
||
2342 scsi_cmd
== SCSICMD_ModeSense6
||
2343 scsi_cmd
== SCSICMD_ModeSelect10
||
2344 scsi_cmd
== SCSICMD_ModeSense10
) {
2345 disable_syn_offset_one_fix
= TRUE
;
2350 if (disable_syn_offset_one_fix
) {
2351 scsiq
->q2
.tag_code
&= ~M2_QTAG_MSG_SIMPLE
;
2352 scsiq
->q2
.tag_code
|= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX
|
2353 ASC_TAG_FLAG_DISABLE_DISCONNECT
);
2355 scsiq
->q2
.tag_code
&= 0x23;
2358 if ((scsiq
->q1
.cntl
& ASC_QC_SG_HEAD
) != 0) {
2359 if (sc
->bug_fix_cntl
) {
2360 if (sc
->bug_fix_cntl
& ASC_BUG_FIX_IF_NOT_DWB
) {
2361 if ((scsi_cmd
== SCSICMD_Read6
) || (scsi_cmd
== SCSICMD_Read10
)) {
2362 addr
= sg_head
->sg_list
[sg_entry_cnt_minus_one
].addr
+
2363 sg_head
->sg_list
[sg_entry_cnt_minus_one
].bytes
;
2364 extra_bytes
= addr
& 0x0003;
2365 if ((extra_bytes
!= 0) &&
2366 ((scsiq
->q2
.tag_code
& ASC_TAG_FLAG_EXTRA_BYTES
) == 0)) {
2367 scsiq
->q2
.tag_code
|= ASC_TAG_FLAG_EXTRA_BYTES
;
2368 scsiq
->q1
.extra_bytes
= extra_bytes
;
2369 sg_head
->sg_list
[sg_entry_cnt_minus_one
].bytes
-=
2375 sg_head
->entry_to_copy
= sg_head
->entry_cnt
;
2376 n_q_required
= AscSgListToQueue(sg_entry_cnt
);
2377 if ((AscGetNumOfFreeQueue(sc
, target_ix
, n_q_required
) >= n_q_required
)
2378 || ((scsiq
->q1
.cntl
& ASC_QC_URGENT
) != 0)) {
2379 retval
= AscSendScsiQueue(sc
, scsiq
, n_q_required
);
2382 if (sc
->bug_fix_cntl
) {
2383 if (sc
->bug_fix_cntl
& ASC_BUG_FIX_IF_NOT_DWB
) {
2384 if ((scsi_cmd
== SCSICMD_Read6
) || (scsi_cmd
== SCSICMD_Read10
)) {
2385 addr
= scsiq
->q1
.data_addr
+ scsiq
->q1
.data_cnt
;
2386 extra_bytes
= addr
& 0x0003;
2387 if ((extra_bytes
!= 0) &&
2388 ((scsiq
->q2
.tag_code
& ASC_TAG_FLAG_EXTRA_BYTES
) == 0)) {
2389 if ((scsiq
->q1
.data_cnt
& 0x01FF) == 0) {
2390 scsiq
->q2
.tag_code
|= ASC_TAG_FLAG_EXTRA_BYTES
;
2391 scsiq
->q1
.data_cnt
-= extra_bytes
;
2392 scsiq
->q1
.extra_bytes
= extra_bytes
;
2399 if ((AscGetNumOfFreeQueue(sc
, target_ix
, 1) >= 1) ||
2400 ((scsiq
->q1
.cntl
& ASC_QC_URGENT
) != 0)) {
2401 retval
= AscSendScsiQueue(sc
, scsiq
, n_q_required
);
2410 AscSendScsiQueue(ASC_SOFTC
*sc
, ASC_SCSI_Q
*scsiq
, u_int8_t n_q_required
)
2412 bus_space_tag_t iot
= sc
->sc_iot
;
2413 bus_space_handle_t ioh
= sc
->sc_ioh
;
2414 u_int8_t free_q_head
;
2421 target_ix
= scsiq
->q2
.target_ix
;
2422 tid_no
= ASC_TIX_TO_TID(target_ix
);
2424 free_q_head
= ASC_GET_VAR_FREE_QHEAD(iot
, ioh
);
2426 if ((next_qp
= AscAllocMultipleFreeQueue(iot
, ioh
, free_q_head
, n_q_required
))
2428 if (n_q_required
> 1) {
2429 sc
->last_q_shortage
= 0;
2430 scsiq
->sg_head
->queue_cnt
= n_q_required
- 1;
2432 scsiq
->q1
.q_no
= free_q_head
;
2434 if ((retval
= AscPutReadySgListQueue(sc
, scsiq
, free_q_head
)) == ASC_NOERROR
) {
2435 ASC_PUT_VAR_FREE_QHEAD(iot
, ioh
, next_qp
);
2436 sc
->cur_total_qng
+= n_q_required
;
2437 sc
->cur_dvc_qng
[tid_no
]++;
2445 AscPutReadySgListQueue(ASC_SOFTC
*sc
, ASC_SCSI_Q
*scsiq
, u_int8_t q_no
)
2447 bus_space_tag_t iot
= sc
->sc_iot
;
2448 bus_space_handle_t ioh
= sc
->sc_ioh
;
2451 ASC_SG_HEAD
*sg_head
;
2452 ASC_SG_LIST_Q scsi_sg_q
;
2453 u_int32_t saved_data_addr
;
2454 u_int32_t saved_data_cnt
;
2455 u_int16_t sg_list_dwords
;
2457 u_int16_t sg_entry_cnt
;
2462 saved_data_addr
= scsiq
->q1
.data_addr
;
2463 saved_data_cnt
= scsiq
->q1
.data_cnt
;
2465 if ((sg_head
= scsiq
->sg_head
) != 0) {
2466 scsiq
->q1
.data_addr
= sg_head
->sg_list
[0].addr
;
2467 scsiq
->q1
.data_cnt
= sg_head
->sg_list
[0].bytes
;
2468 sg_entry_cnt
= sg_head
->entry_cnt
- 1;
2469 if (sg_entry_cnt
!= 0) {
2470 q_addr
= ASC_QNO_TO_QADDR(q_no
);
2472 scsiq
->q1
.sg_queue_cnt
= sg_head
->queue_cnt
;
2473 scsi_sg_q
.sg_head_qp
= q_no
;
2474 scsi_sg_q
.cntl
= ASC_QCSG_SG_XFER_LIST
;
2476 for (i
= 0; i
< sg_head
->queue_cnt
; i
++) {
2477 scsi_sg_q
.seq_no
= i
+ 1;
2478 if (sg_entry_cnt
> ASC_SG_LIST_PER_Q
) {
2479 sg_list_dwords
= ASC_SG_LIST_PER_Q
* 2;
2480 sg_entry_cnt
-= ASC_SG_LIST_PER_Q
;
2482 scsi_sg_q
.sg_list_cnt
= ASC_SG_LIST_PER_Q
;
2483 scsi_sg_q
.sg_cur_list_cnt
= ASC_SG_LIST_PER_Q
;
2485 scsi_sg_q
.sg_list_cnt
= ASC_SG_LIST_PER_Q
- 1;
2486 scsi_sg_q
.sg_cur_list_cnt
= ASC_SG_LIST_PER_Q
- 1;
2489 scsi_sg_q
.cntl
|= ASC_QCSG_SG_XFER_END
;
2490 sg_list_dwords
= sg_entry_cnt
<< 1;
2492 scsi_sg_q
.sg_list_cnt
= sg_entry_cnt
;
2493 scsi_sg_q
.sg_cur_list_cnt
= sg_entry_cnt
;
2495 scsi_sg_q
.sg_list_cnt
= sg_entry_cnt
- 1;
2496 scsi_sg_q
.sg_cur_list_cnt
= sg_entry_cnt
- 1;
2502 next_qp
= AscReadLramByte(iot
, ioh
, q_addr
+ ASC_SCSIQ_B_FWD
);
2503 scsi_sg_q
.q_no
= next_qp
;
2504 q_addr
= ASC_QNO_TO_QADDR(next_qp
);
2507 * Tell the board how many entries are in the S/G list
2509 AscMemWordCopyToLram(iot
, ioh
, q_addr
+ ASC_SCSIQ_SGHD_CPY_BEG
,
2510 (const u_int16_t
*) & scsi_sg_q
,
2511 sizeof(ASC_SG_LIST_Q
) >> 1);
2513 * Tell the board the addresses of the S/G list segments
2515 AscMemDWordCopyToLram(iot
, ioh
, q_addr
+ ASC_SGQ_LIST_BEG
,
2516 (u_int32_t
*) & sg_head
->sg_list
[sg_index
],
2518 sg_index
+= ASC_SG_LIST_PER_Q
;
2522 retval
= AscPutReadyQueue(sc
, scsiq
, q_no
);
2523 scsiq
->q1
.data_addr
= saved_data_addr
;
2524 scsiq
->q1
.data_cnt
= saved_data_cnt
;
2530 AscPutReadyQueue(ASC_SOFTC
*sc
, ASC_SCSI_Q
*scsiq
, u_int8_t q_no
)
2532 bus_space_tag_t iot
= sc
->sc_iot
;
2533 bus_space_handle_t ioh
= sc
->sc_ioh
;
2537 u_int8_t syn_period_ix
;
2538 u_int8_t syn_offset
;
2541 if (((sc
->init_sdtr
& scsiq
->q1
.target_id
) != 0) &&
2542 ((sc
->sdtr_done
& scsiq
->q1
.target_id
) == 0)) {
2543 tid_no
= ASC_TIX_TO_TID(scsiq
->q2
.target_ix
);
2544 sdtr_data
= ASC_GET_MCODE_INIT_SDTR_AT_ID(iot
, ioh
, tid_no
);
2545 syn_period_ix
= (sdtr_data
>> 4) & (sc
->max_sdtr_index
- 1);
2546 syn_offset
= sdtr_data
& ASC_SYN_MAX_OFFSET
;
2547 AscMsgOutSDTR(sc
, sc
->sdtr_period_tbl
[syn_period_ix
], syn_offset
);
2548 scsiq
->q1
.cntl
|= ASC_QC_MSG_OUT
;
2550 q_addr
= ASC_QNO_TO_QADDR(q_no
);
2552 if ((scsiq
->q1
.target_id
& sc
->use_tagged_qng
) == 0) {
2553 scsiq
->q2
.tag_code
&= ~M2_QTAG_MSG_SIMPLE
;
2555 scsiq
->q1
.status
= ASC_QS_FREE
;
2556 AscMemWordCopyToLram(iot
, ioh
, q_addr
+ ASC_SCSIQ_CDB_BEG
,
2557 (const u_int16_t
*) scsiq
->cdbptr
, scsiq
->q2
.cdb_len
>> 1);
2559 AscPutSCSIQ(iot
, ioh
, q_addr
+ ASC_SCSIQ_CPY_BEG
, scsiq
);
2562 * Let's start the command
2564 AscWriteLramWord(iot
, ioh
, q_addr
+ ASC_SCSIQ_B_STATUS
,
2565 (scsiq
->q1
.q_no
<< 8) | ASC_QS_READY
);
2567 return (ASC_NOERROR
);
2572 AscPutSCSIQ(bus_space_tag_t iot
, bus_space_handle_t ioh
,
2573 u_int16_t addr
, ASC_SCSI_Q
*scsiq
)
2578 ASC_SET_CHIP_LRAM_ADDR(iot
, ioh
, addr
);
2581 val
= MAKEWORD(scsiq
->q1
.cntl
, scsiq
->q1
.sg_queue_cnt
);
2582 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, val
);
2583 val
= MAKEWORD(scsiq
->q1
.target_id
, scsiq
->q1
.target_lun
);
2584 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, val
);
2585 val
= LO_WORD(scsiq
->q1
.data_addr
);
2586 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, val
);
2587 val
= HI_WORD(scsiq
->q1
.data_addr
);
2588 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, val
);
2589 val
= LO_WORD(scsiq
->q1
.data_cnt
);
2590 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, val
);
2591 val
= HI_WORD(scsiq
->q1
.data_cnt
);
2592 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, val
);
2593 val
= LO_WORD(scsiq
->q1
.sense_addr
);
2594 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, val
);
2595 val
= HI_WORD(scsiq
->q1
.sense_addr
);
2596 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, val
);
2597 val
= MAKEWORD(scsiq
->q1
.sense_len
, scsiq
->q1
.extra_bytes
);
2598 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, val
);
2601 val
= LO_WORD(scsiq
->q2
.ccb_ptr
);
2602 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, val
);
2603 val
= HI_WORD(scsiq
->q2
.ccb_ptr
);
2604 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, val
);
2605 val
= MAKEWORD(scsiq
->q2
.target_ix
, scsiq
->q2
.flag
);
2606 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, val
);
2607 val
= MAKEWORD(scsiq
->q2
.cdb_len
, scsiq
->q2
.tag_code
);
2608 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, val
);
2609 ASC_SET_CHIP_LRAM_DATA(iot
, ioh
, scsiq
->q2
.vm_id
);
2614 AscSgListToQueue(int sg_list
)
2618 n_sg_list_qs
= ((sg_list
- 1) / ASC_SG_LIST_PER_Q
);
2619 if (((sg_list
- 1) % ASC_SG_LIST_PER_Q
) != 0)
2622 return (n_sg_list_qs
+ 1);
2627 AscGetNumOfFreeQueue(ASC_SOFTC
*sc
, u_int8_t target_ix
, u_int8_t n_qs
)
2634 cur_used_qs
= sc
->cur_total_qng
+
2635 sc
->last_q_shortage
+
2638 cur_used_qs
= sc
->cur_total_qng
+ ASC_MIN_FREE_Q
;
2641 if ((cur_used_qs
+ n_qs
) <= sc
->max_total_qng
) {
2642 cur_free_qs
= sc
->max_total_qng
- cur_used_qs
;
2643 return (cur_free_qs
);
2646 if ((n_qs
> sc
->last_q_shortage
) &&
2647 (n_qs
<= (sc
->max_total_qng
- ASC_MIN_FREE_Q
))) {
2648 sc
->last_q_shortage
= n_qs
;
2655 AscAllocFreeQueue(bus_space_tag_t iot
, bus_space_handle_t ioh
,
2656 u_int8_t free_q_head
)
2663 q_addr
= ASC_QNO_TO_QADDR(free_q_head
);
2664 q_status
= AscReadLramByte(iot
, ioh
, q_addr
+ ASC_SCSIQ_B_STATUS
);
2665 next_qp
= AscReadLramByte(iot
, ioh
, q_addr
+ ASC_SCSIQ_B_FWD
);
2666 if (((q_status
& ASC_QS_READY
) == 0) && (next_qp
!= ASC_QLINK_END
))
2669 return (ASC_QLINK_END
);
2674 AscAllocMultipleFreeQueue(bus_space_tag_t iot
, bus_space_handle_t ioh
,
2675 u_int8_t free_q_head
, u_int8_t n_free_q
)
2679 for (i
= 0; i
< n_free_q
; i
++) {
2680 free_q_head
= AscAllocFreeQueue(iot
, ioh
, free_q_head
);
2681 if (free_q_head
== ASC_QLINK_END
)
2685 return (free_q_head
);
2690 AscStopQueueExe(bus_space_tag_t iot
, bus_space_handle_t ioh
)
2694 if (AscReadLramByte(iot
, ioh
, ASCV_STOP_CODE_B
) == 0) {
2695 AscWriteLramByte(iot
, ioh
, ASCV_STOP_CODE_B
, ASC_STOP_REQ_RISC_STOP
);
2697 if (AscReadLramByte(iot
, ioh
, ASCV_STOP_CODE_B
) &
2698 ASC_STOP_ACK_RISC_STOP
)
2701 DvcSleepMilliSecond(100);
2702 } while (count
++ < 20);
2709 AscStartQueueExe(bus_space_tag_t iot
, bus_space_handle_t ioh
)
2712 if (AscReadLramByte(iot
, ioh
, ASCV_STOP_CODE_B
) != 0)
2713 AscWriteLramByte(iot
, ioh
, ASCV_STOP_CODE_B
, 0);
2718 AscCleanUpBusyQueue(bus_space_tag_t iot
, bus_space_handle_t ioh
)
2724 if (AscReadLramByte(iot
, ioh
, ASCV_STOP_CODE_B
) != 0) {
2725 AscWriteLramByte(iot
, ioh
, ASCV_STOP_CODE_B
, ASC_STOP_CLEAN_UP_BUSY_Q
);
2727 stop_code
= AscReadLramByte(iot
, ioh
, ASCV_STOP_CODE_B
);
2728 if ((stop_code
& ASC_STOP_CLEAN_UP_BUSY_Q
) == 0)
2731 DvcSleepMilliSecond(100);
2732 } while (count
++ < 20);
2738 _AscWaitQDone(bus_space_tag_t iot
, bus_space_handle_t ioh
, ASC_SCSI_Q
*scsiq
)
2744 while (scsiq
->q1
.q_no
== 0);
2746 q_addr
= ASC_QNO_TO_QADDR(scsiq
->q1
.q_no
);
2748 q_status
= AscReadLramByte(iot
, ioh
, q_addr
+ ASC_SCSIQ_B_STATUS
);
2749 DvcSleepMilliSecond(100L);
2753 } while ((q_status
& ASC_QS_READY
) != 0);
2760 AscCleanUpDiscQueue(bus_space_tag_t iot
, bus_space_handle_t ioh
)
2766 if (AscReadLramByte(iot
, ioh
, ASCV_STOP_CODE_B
) != 0) {
2767 AscWriteLramByte(iot
, ioh
, ASCV_STOP_CODE_B
, ASC_STOP_CLEAN_UP_DISC_Q
);
2769 stop_code
= AscReadLramByte(iot
, ioh
, ASCV_STOP_CODE_B
);
2770 if ((stop_code
& ASC_STOP_CLEAN_UP_DISC_Q
) == 0)
2773 DvcSleepMilliSecond(100);
2774 } while (count
++ < 20);
2780 /******************************************************************************/
2781 /* Abort and Reset CCB routines */
2782 /******************************************************************************/
2786 AscAbortCCB(ASC_SOFTC
*sc
, ADV_CCB
*ccb
)
2788 bus_space_tag_t iot
= sc
->sc_iot
;
2789 bus_space_handle_t ioh
= sc
->sc_ioh
;
2791 ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready
;
2795 saved_unit_not_ready
= sc
->unit_not_ready
;
2796 sc
->unit_not_ready
= 0xFF;
2798 if (AscStopQueueExe(iot
, ioh
) == 1) {
2799 if (AscRiscHaltedAbortCCB(sc
, ccb
) == 1) {
2801 AscCleanUpBusyQueue(iot
, ioh
);
2802 AscStartQueueExe(iot
, ioh
);
2805 AscStartQueueExe(iot
, ioh
);
2808 sc
->unit_not_ready
= saved_unit_not_ready
;
2815 AscRiscHaltedAbortCCB(ASC_SOFTC
*sc
, ADV_CCB
*ccb
)
2817 bus_space_tag_t iot
= sc
->sc_iot
;
2818 bus_space_handle_t ioh
= sc
->sc_ioh
;
2821 ASC_QDONE_INFO scsiq_buf
;
2822 ASC_QDONE_INFO
*scsiq
;
2823 ASC_ISR_CALLBACK asc_isr_callback
;
2827 asc_isr_callback
= (ASC_ISR_CALLBACK
) sc
->isr_callback
;
2828 last_int_level
= DvcEnterCritical();
2829 scsiq
= (ASC_QDONE_INFO
*) & scsiq_buf
;
2831 for (q_no
= ASC_MIN_ACTIVE_QNO
; q_no
<= sc
->max_total_qng
; q_no
++) {
2832 q_addr
= ASC_QNO_TO_QADDR(q_no
);
2833 scsiq
->d2
.ccb_ptr
= AscReadLramDWord(iot
, ioh
,
2834 q_addr
+ ASC_SCSIQ_D_CCBPTR
);
2835 if (adv_ccb_phys_kv(sc
, scsiq
->d2
.ccb_ptr
) == ccb
) {
2836 _AscCopyLramScsiDoneQ(iot
, ioh
, q_addr
, scsiq
, sc
->max_dma_count
);
2837 if (((scsiq
->q_status
& ASC_QS_READY
) != 0)
2838 && ((scsiq
->q_status
& ASC_QS_ABORTED
) == 0)
2839 && ((scsiq
->cntl
& ASC_QCSG_SG_XFER_LIST
) == 0)) {
2840 scsiq
->q_status
|= ASC_QS_ABORTED
;
2841 scsiq
->d3
.done_stat
= ASC_QD_ABORTED_BY_HOST
;
2842 AscWriteLramDWord(iot
, ioh
, q_addr
+ ASC_SCSIQ_D_CCBPTR
, 0L);
2843 AscWriteLramByte(iot
, ioh
, q_addr
+ ASC_SCSIQ_B_STATUS
,
2845 (*asc_isr_callback
) (sc
, scsiq
);
2851 DvcLeaveCritical(last_int_level
);
2857 AscRiscHaltedAbortTIX(ASC_SOFTC
*sc
, u_int8_t target_ix
)
2859 bus_space_tag_t iot
= sc
->sc_iot
;
2860 bus_space_handle_t ioh
= sc
->sc_ioh
;
2863 ASC_QDONE_INFO scsiq_buf
;
2864 ASC_QDONE_INFO
*scsiq
;
2865 ASC_ISR_CALLBACK asc_isr_callback
;
2869 asc_isr_callback
= (ASC_ISR_CALLBACK
) sc
->isr_callback
;
2870 last_int_level
= DvcEnterCritical();
2871 scsiq
= (ASC_QDONE_INFO
*) & scsiq_buf
;
2872 for (q_no
= ASC_MIN_ACTIVE_QNO
; q_no
<= sc
->max_total_qng
; q_no
++) {
2873 q_addr
= ASC_QNO_TO_QADDR(q_no
);
2874 _AscCopyLramScsiDoneQ(iot
, ioh
, q_addr
, scsiq
, sc
->max_dma_count
);
2875 if (((scsiq
->q_status
& ASC_QS_READY
) != 0) &&
2876 ((scsiq
->q_status
& ASC_QS_ABORTED
) == 0) &&
2877 ((scsiq
->cntl
& ASC_QCSG_SG_XFER_LIST
) == 0)) {
2878 if (scsiq
->d2
.target_ix
== target_ix
) {
2879 scsiq
->q_status
|= ASC_QS_ABORTED
;
2880 scsiq
->d3
.done_stat
= ASC_QD_ABORTED_BY_HOST
;
2881 AscWriteLramDWord(iot
, ioh
, q_addr
+ ASC_SCSIQ_D_CCBPTR
, 0L);
2882 AscWriteLramByte(iot
, ioh
, q_addr
+ ASC_SCSIQ_B_STATUS
,
2884 (*asc_isr_callback
) (sc
, scsiq
);
2888 DvcLeaveCritical(last_int_level
);
2894 * AscResetDevice calls _AscWaitQDone which requires interrupt enabled,
2895 * so we cannot use this function with the actual NetBSD SCSI layer
2896 * because at boot time interrupts are disabled.
2899 AscResetDevice(ASC_SOFTC
*sc
, u_char target_ix
)
2901 bus_space_tag_t iot
= sc
->sc_iot
;
2902 bus_space_handle_t ioh
= sc
->sc_ioh
;
2905 ASC_SCSI_BIT_ID_TYPE target_id
;
2907 ASC_SCSI_REQ_Q scsiq_buf
;
2908 ASC_SCSI_REQ_Q
*scsiq
;
2910 ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready
;
2913 tid_no
= ASC_TIX_TO_TID(target_ix
);
2914 target_id
= ASC_TID_TO_TARGET_ID(tid_no
);
2915 saved_unit_not_ready
= sc
->unit_not_ready
;
2916 sc
->unit_not_ready
= target_id
;
2919 AscWaitTixISRDone(sc
, target_ix
);
2921 if (AscStopQueueExe(iot
, ioh
) == 1) {
2922 if (AscRiscHaltedAbortTIX(sc
, target_ix
) == 1) {
2923 AscCleanUpBusyQueue(iot
, ioh
);
2924 AscStartQueueExe(iot
, ioh
);
2925 AscWaitTixISRDone(sc
, target_ix
);
2926 retval
= ASC_NOERROR
;
2927 scsiq
= (ASC_SCSI_REQ_Q
*) & scsiq_buf
;
2928 buf
= (u_char
*) & scsiq_buf
;
2929 for (i
= 0; i
< sizeof(ASC_SCSI_REQ_Q
); i
++)
2931 scsiq
->q1
.status
= (u_char
) ASC_QS_READY
;
2932 scsiq
->q2
.cdb_len
= 6;
2933 scsiq
->q2
.tag_code
= M2_QTAG_MSG_SIMPLE
;
2934 scsiq
->q1
.target_id
= target_id
;
2935 scsiq
->q2
.target_ix
= ASC_TIDLUN_TO_IX(tid_no
, 0);
2936 scsiq
->cdbptr
= scsiq
->cdb
;
2937 scsiq
->q1
.cntl
= ASC_QC_NO_CALLBACK
| ASC_QC_MSG_OUT
| ASC_QC_URGENT
;
2938 AscWriteLramByte(iot
, ioh
, ASCV_MSGOUT_BEG
, M1_BUS_DVC_RESET
);
2939 sc
->unit_not_ready
&= ~target_id
;
2940 sc
->sdtr_done
|= target_id
;
2941 if (AscExeScsiQueue(sc
, (ASC_SCSI_Q
*) scsiq
) == ASC_NOERROR
) {
2942 sc
->unit_not_ready
= target_id
;
2943 DvcSleepMilliSecond(1000);
2944 _AscWaitQDone(iot
, ioh
, (ASC_SCSI_Q
*) scsiq
);
2945 if (AscStopQueueExe(iot
, ioh
) == ASC_NOERROR
) {
2946 AscCleanUpDiscQueue(iot
, ioh
);
2947 AscStartQueueExe(iot
, ioh
);
2948 if (sc
->pci_fix_asyn_xfer
& target_id
)
2949 AscSetRunChipSynRegAtID(iot
, ioh
, tid_no
,
2950 ASYN_SDTR_DATA_FIX_PCI_REV_AB
);
2951 AscWaitTixISRDone(sc
, target_ix
);
2955 sc
->sdtr_done
&= ~target_id
;
2958 AscStartQueueExe(iot
, ioh
);
2961 sc
->unit_not_ready
= saved_unit_not_ready
;
2967 AscResetBus(ASC_SOFTC
*sc
)
2969 bus_space_tag_t iot
= sc
->sc_iot
;
2970 bus_space_handle_t ioh
= sc
->sc_ioh
;
2975 sc
->unit_not_ready
= 0xFF;
2976 retval
= ASC_NOERROR
;
2979 AscStopQueueExe(iot
, ioh
);
2981 AscResetChipAndScsiBus(iot
, ioh
);
2982 DvcSleepMilliSecond((u_long
) ((u_int16_t
) sc
->scsi_reset_wait
* 1000));
2984 for (i
= 0; i
<= ASC_MAX_TID
; i
++) {
2985 sc
->cur_dvc_qng
[i
] = 0;
2986 if (sc
->pci_fix_asyn_xfer
& (ASC_SCSI_BIT_ID_TYPE
) (0x01 << i
))
2987 AscSetChipSynRegAtID(iot
, ioh
, i
, ASYN_SDTR_DATA_FIX_PCI_REV_AB
);
2990 ASC_SET_PC_ADDR(iot
, ioh
, ASC_MCODE_START_ADDR
);
2991 if (ASC_GET_PC_ADDR(iot
, ioh
) != ASC_MCODE_START_ADDR
)
2994 if (AscStartChip(iot
, ioh
) == 0)
2997 AscStartQueueExe(iot
, ioh
);
2998 sc
->unit_not_ready
= 0;
2999 sc
->queue_full_or_busy
= 0;
3004 /******************************************************************************/
3005 /* Error Handling routines */
3006 /******************************************************************************/
3010 AscSetLibErrorCode(ASC_SOFTC
*sc
, u_int16_t err_code
)
3013 * if(sc->err_code == 0) { sc->err_code = err_code;
3014 */ AscWriteLramWord(sc
->sc_iot
, sc
->sc_ioh
, ASCV_ASCDVC_ERR_CODE_W
,
3023 /******************************************************************************/
3024 /* Handle bugged borads routines */
3025 /******************************************************************************/
3029 AscInquiryHandling(ASC_SOFTC
*sc
, u_int8_t tid_no
, ASC_SCSI_INQUIRY
*inq
)
3031 bus_space_tag_t iot
= sc
->sc_iot
;
3032 bus_space_handle_t ioh
= sc
->sc_ioh
;
3033 ASC_SCSI_BIT_ID_TYPE tid_bit
= ASC_TIX_TO_TARGET_ID(tid_no
);
3034 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr
, orig_use_tagged_qng
;
3036 orig_init_sdtr
= sc
->init_sdtr
;
3037 orig_use_tagged_qng
= sc
->use_tagged_qng
;
3039 sc
->init_sdtr
&= ~tid_bit
;
3040 sc
->can_tagged_qng
&= ~tid_bit
;
3041 sc
->use_tagged_qng
&= ~tid_bit
;
3043 if (inq
->byte3
.rsp_data_fmt
>= 2 || inq
->byte2
.ansi_apr_ver
>= 2) {
3044 if ((sc
->sdtr_enable
& tid_bit
) && inq
->byte7
.Sync
)
3045 sc
->init_sdtr
|= tid_bit
;
3047 if ((sc
->cmd_qng_enabled
& tid_bit
) && inq
->byte7
.CmdQue
)
3048 if (AscTagQueuingSafe(inq
)) {
3049 sc
->use_tagged_qng
|= tid_bit
;
3050 sc
->can_tagged_qng
|= tid_bit
;
3053 if (orig_use_tagged_qng
!= sc
->use_tagged_qng
) {
3054 AscWriteLramByte(iot
, ioh
, ASCV_DISC_ENABLE_B
,
3056 AscWriteLramByte(iot
, ioh
, ASCV_USE_TAGGED_QNG_B
,
3057 sc
->use_tagged_qng
);
3058 AscWriteLramByte(iot
, ioh
, ASCV_CAN_TAGGED_QNG_B
,
3059 sc
->can_tagged_qng
);
3061 sc
->max_dvc_qng
[tid_no
] =
3062 sc
->max_tag_qng
[tid_no
];
3063 AscWriteLramByte(iot
, ioh
, ASCV_MAX_DVC_QNG_BEG
+ tid_no
,
3064 sc
->max_dvc_qng
[tid_no
]);
3066 if (orig_init_sdtr
!= sc
->init_sdtr
)
3067 AscAsyncFix(sc
, tid_no
, inq
);
3072 AscTagQueuingSafe(ASC_SCSI_INQUIRY
*inq
)
3074 if ((inq
->add_len
>= 32) &&
3075 (AscCompareString(inq
->vendor_id
, "QUANTUM XP34301", 15) == 0) &&
3076 (AscCompareString(inq
->product_rev_level
, "1071", 4) == 0)) {
3084 AscAsyncFix(ASC_SOFTC
*sc
, u_int8_t tid_no
, ASC_SCSI_INQUIRY
*inq
)
3087 ASC_SCSI_BIT_ID_TYPE tid_bits
;
3090 dvc_type
= inq
->byte0
.peri_dvc_type
;
3091 tid_bits
= ASC_TIX_TO_TARGET_ID(tid_no
);
3093 if (sc
->bug_fix_cntl
& ASC_BUG_FIX_ASYN_USE_SYN
) {
3094 if (!(sc
->init_sdtr
& tid_bits
)) {
3095 if ((dvc_type
== SCSI_TYPE_CDROM
) &&
3096 (AscCompareString(inq
->vendor_id
, "HP ", 3) == 0)) {
3097 sc
->pci_fix_asyn_xfer_always
|= tid_bits
;
3099 sc
->pci_fix_asyn_xfer
|= tid_bits
;
3100 if ((dvc_type
== SCSI_TYPE_PROC
) ||
3101 (dvc_type
== SCSI_TYPE_SCANNER
)) {
3102 sc
->pci_fix_asyn_xfer
&= ~tid_bits
;
3104 if ((dvc_type
== SCSI_TYPE_SASD
) &&
3105 (AscCompareString(inq
->vendor_id
, "TANDBERG", 8) == 0) &&
3106 (AscCompareString(inq
->product_id
, " TDC 36", 7) == 0)) {
3107 sc
->pci_fix_asyn_xfer
&= ~tid_bits
;
3109 if ((dvc_type
== SCSI_TYPE_SASD
) &&
3110 (AscCompareString(inq
->vendor_id
, "WANGTEK ", 8) == 0)) {
3111 sc
->pci_fix_asyn_xfer
&= ~tid_bits
;
3113 if ((dvc_type
== SCSI_TYPE_CDROM
) &&
3114 (AscCompareString(inq
->vendor_id
, "NEC ", 8) == 0) &&
3115 (AscCompareString(inq
->product_id
, "CD-ROM DRIVE ", 16) == 0)) {
3116 sc
->pci_fix_asyn_xfer
&= ~tid_bits
;
3118 if ((dvc_type
== SCSI_TYPE_CDROM
) &&
3119 (AscCompareString(inq
->vendor_id
, "YAMAHA", 6) == 0) &&
3120 (AscCompareString(inq
->product_id
, "CDR400", 6) == 0)) {
3121 sc
->pci_fix_asyn_xfer
&= ~tid_bits
;
3123 if (sc
->pci_fix_asyn_xfer
& tid_bits
) {
3124 AscSetRunChipSynRegAtID(sc
->sc_iot
, sc
->sc_ioh
, tid_no
,
3125 ASYN_SDTR_DATA_FIX_PCI_REV_AB
);
3132 /******************************************************************************/
3133 /* Miscellaneous routines */
3134 /******************************************************************************/
3138 AscCompareString(const u_char
*str1
, const u_char
*str2
, int len
)
3143 for (i
= 0; i
< len
; i
++) {
3144 diff
= (int) (str1
[i
] - str2
[i
]);
3153 /******************************************************************************/
3154 /* Device oriented routines */
3155 /******************************************************************************/
3159 DvcEnterCritical(void)
3169 DvcLeaveCritical(int s
)
3177 DvcSleepMilliSecond(u_int32_t n
)
3185 DvcDelayMicroSecond(u_int32_t n
)
3193 DvcDelayNanoSecond(u_int32_t n
)
3196 DELAY((n
+ 999) / 1000);