[SCSI] advansys: Merge ASC_IERR definitions
[linux-2.6.git] / drivers / scsi / advansys.c
blob0f309e80aaad1c9f80ed57a238fccef81f185d9d
1 #define DRV_NAME "advansys"
2 #define ASC_VERSION "3.4" /* AdvanSys Driver Version */
4 /*
5 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
7 * Copyright (c) 1995-2000 Advanced System Products, Inc.
8 * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
9 * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
10 * All Rights Reserved.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
19 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
20 * changed its name to ConnectCom Solutions, Inc.
21 * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
24 #include <linux/module.h>
25 #include <linux/string.h>
26 #include <linux/kernel.h>
27 #include <linux/types.h>
28 #include <linux/ioport.h>
29 #include <linux/interrupt.h>
30 #include <linux/delay.h>
31 #include <linux/slab.h>
32 #include <linux/mm.h>
33 #include <linux/proc_fs.h>
34 #include <linux/init.h>
35 #include <linux/blkdev.h>
36 #include <linux/isa.h>
37 #include <linux/eisa.h>
38 #include <linux/pci.h>
39 #include <linux/spinlock.h>
40 #include <linux/dma-mapping.h>
42 #include <asm/io.h>
43 #include <asm/system.h>
44 #include <asm/dma.h>
46 #include <scsi/scsi_cmnd.h>
47 #include <scsi/scsi_device.h>
48 #include <scsi/scsi_tcq.h>
49 #include <scsi/scsi.h>
50 #include <scsi/scsi_host.h>
52 /* FIXME:
54 * 1. Although all of the necessary command mapping places have the
55 * appropriate dma_map.. APIs, the driver still processes its internal
56 * queue using bus_to_virt() and virt_to_bus() which are illegal under
57 * the API. The entire queue processing structure will need to be
58 * altered to fix this.
59 * 2. Need to add memory mapping workaround. Test the memory mapping.
60 * If it doesn't work revert to I/O port access. Can a test be done
61 * safely?
62 * 3. Handle an interrupt not working. Keep an interrupt counter in
63 * the interrupt handler. In the timeout function if the interrupt
64 * has not occurred then print a message and run in polled mode.
65 * 4. Need to add support for target mode commands, cf. CAM XPT.
66 * 5. check DMA mapping functions for failure
67 * 6. Use scsi_transport_spi
68 * 7. advansys_info is not safe against multiple simultaneous callers
69 * 8. Kill boardp->id
70 * 9. Add module_param to override ISA/VLB ioport array
72 #warning this driver is still not properly converted to the DMA API
74 /* Enable driver /proc statistics. */
75 #define ADVANSYS_STATS
77 /* Enable driver tracing. */
78 /* #define ADVANSYS_DEBUG */
80 #define ASC_LIB_VERSION_MAJOR 1
81 #define ASC_LIB_VERSION_MINOR 24
82 #define ASC_LIB_SERIAL_NUMBER 123
85 * Portable Data Types
87 * Any instance where a 32-bit long or pointer type is assumed
88 * for precision or HW defined structures, the following define
89 * types must be used. In Linux the char, short, and int types
90 * are all consistent at 8, 16, and 32 bits respectively. Pointers
91 * and long types are 64 bits on Alpha and UltraSPARC.
93 #define ASC_PADDR __u32 /* Physical/Bus address data type. */
94 #define ASC_VADDR __u32 /* Virtual address data type. */
95 #define ASC_DCNT __u32 /* Unsigned Data count type. */
96 #define ASC_SDCNT __s32 /* Signed Data count type. */
99 * These macros are used to convert a virtual address to a
100 * 32-bit value. This currently can be used on Linux Alpha
101 * which uses 64-bit virtual address but a 32-bit bus address.
102 * This is likely to break in the future, but doing this now
103 * will give us time to change the HW and FW to handle 64-bit
104 * addresses.
106 #define ASC_VADDR_TO_U32 virt_to_bus
107 #define ASC_U32_TO_VADDR bus_to_virt
109 typedef unsigned char uchar;
111 #ifndef TRUE
112 #define TRUE (1)
113 #endif
114 #ifndef FALSE
115 #define FALSE (0)
116 #endif
118 #define ERR (-1)
119 #define UW_ERR (uint)(0xFFFF)
120 #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
122 #define PCI_VENDOR_ID_ASP 0x10cd
123 #define PCI_DEVICE_ID_ASP_1200A 0x1100
124 #define PCI_DEVICE_ID_ASP_ABP940 0x1200
125 #define PCI_DEVICE_ID_ASP_ABP940U 0x1300
126 #define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
127 #define PCI_DEVICE_ID_38C0800_REV1 0x2500
128 #define PCI_DEVICE_ID_38C1600_REV1 0x2700
131 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
132 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
133 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
134 * SRB structure.
136 #define CC_VERY_LONG_SG_LIST 0
137 #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
139 #define PortAddr unsigned short /* port address size */
140 #define inp(port) inb(port)
141 #define outp(port, byte) outb((byte), (port))
143 #define inpw(port) inw(port)
144 #define outpw(port, word) outw((word), (port))
146 #define ASC_MAX_SG_QUEUE 7
147 #define ASC_MAX_SG_LIST 255
149 #define ASC_CS_TYPE unsigned short
151 #define ASC_IS_ISA (0x0001)
152 #define ASC_IS_ISAPNP (0x0081)
153 #define ASC_IS_EISA (0x0002)
154 #define ASC_IS_PCI (0x0004)
155 #define ASC_IS_PCI_ULTRA (0x0104)
156 #define ASC_IS_PCMCIA (0x0008)
157 #define ASC_IS_MCA (0x0020)
158 #define ASC_IS_VL (0x0040)
159 #define ASC_IS_WIDESCSI_16 (0x0100)
160 #define ASC_IS_WIDESCSI_32 (0x0200)
161 #define ASC_IS_BIG_ENDIAN (0x8000)
163 #define ASC_CHIP_MIN_VER_VL (0x01)
164 #define ASC_CHIP_MAX_VER_VL (0x07)
165 #define ASC_CHIP_MIN_VER_PCI (0x09)
166 #define ASC_CHIP_MAX_VER_PCI (0x0F)
167 #define ASC_CHIP_VER_PCI_BIT (0x08)
168 #define ASC_CHIP_MIN_VER_ISA (0x11)
169 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
170 #define ASC_CHIP_MAX_VER_ISA (0x27)
171 #define ASC_CHIP_VER_ISA_BIT (0x30)
172 #define ASC_CHIP_VER_ISAPNP_BIT (0x20)
173 #define ASC_CHIP_VER_ASYN_BUG (0x21)
174 #define ASC_CHIP_VER_PCI 0x08
175 #define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
176 #define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
177 #define ASC_CHIP_MIN_VER_EISA (0x41)
178 #define ASC_CHIP_MAX_VER_EISA (0x47)
179 #define ASC_CHIP_VER_EISA_BIT (0x40)
180 #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
181 #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
182 #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
183 #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
185 #define ASC_SCSI_ID_BITS 3
186 #define ASC_SCSI_TIX_TYPE uchar
187 #define ASC_ALL_DEVICE_BIT_SET 0xFF
188 #define ASC_SCSI_BIT_ID_TYPE uchar
189 #define ASC_MAX_TID 7
190 #define ASC_MAX_LUN 7
191 #define ASC_SCSI_WIDTH_BIT_SET 0xFF
192 #define ASC_MAX_SENSE_LEN 32
193 #define ASC_MIN_SENSE_LEN 14
194 #define ASC_SCSI_RESET_HOLD_TIME_US 60
197 * Narrow boards only support 12-byte commands, while wide boards
198 * extend to 16-byte commands.
200 #define ASC_MAX_CDB_LEN 12
201 #define ADV_MAX_CDB_LEN 16
203 #define MS_SDTR_LEN 0x03
204 #define MS_WDTR_LEN 0x02
206 #define ASC_SG_LIST_PER_Q 7
207 #define QS_FREE 0x00
208 #define QS_READY 0x01
209 #define QS_DISC1 0x02
210 #define QS_DISC2 0x04
211 #define QS_BUSY 0x08
212 #define QS_ABORTED 0x40
213 #define QS_DONE 0x80
214 #define QC_NO_CALLBACK 0x01
215 #define QC_SG_SWAP_QUEUE 0x02
216 #define QC_SG_HEAD 0x04
217 #define QC_DATA_IN 0x08
218 #define QC_DATA_OUT 0x10
219 #define QC_URGENT 0x20
220 #define QC_MSG_OUT 0x40
221 #define QC_REQ_SENSE 0x80
222 #define QCSG_SG_XFER_LIST 0x02
223 #define QCSG_SG_XFER_MORE 0x04
224 #define QCSG_SG_XFER_END 0x08
225 #define QD_IN_PROGRESS 0x00
226 #define QD_NO_ERROR 0x01
227 #define QD_ABORTED_BY_HOST 0x02
228 #define QD_WITH_ERROR 0x04
229 #define QD_INVALID_REQUEST 0x80
230 #define QD_INVALID_HOST_NUM 0x81
231 #define QD_INVALID_DEVICE 0x82
232 #define QD_ERR_INTERNAL 0xFF
233 #define QHSTA_NO_ERROR 0x00
234 #define QHSTA_M_SEL_TIMEOUT 0x11
235 #define QHSTA_M_DATA_OVER_RUN 0x12
236 #define QHSTA_M_DATA_UNDER_RUN 0x12
237 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
238 #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
239 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
240 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
241 #define QHSTA_D_HOST_ABORT_FAILED 0x23
242 #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
243 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
244 #define QHSTA_D_ASPI_NO_BUF_POOL 0x26
245 #define QHSTA_M_WTM_TIMEOUT 0x41
246 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
247 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
248 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
249 #define QHSTA_M_TARGET_STATUS_BUSY 0x45
250 #define QHSTA_M_BAD_TAG_CODE 0x46
251 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
252 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
253 #define QHSTA_D_LRAM_CMP_ERROR 0x81
254 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
255 #define ASC_FLAG_SCSIQ_REQ 0x01
256 #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
257 #define ASC_FLAG_BIOS_ASYNC_IO 0x04
258 #define ASC_FLAG_SRB_LINEAR_ADDR 0x08
259 #define ASC_FLAG_WIN16 0x10
260 #define ASC_FLAG_WIN32 0x20
261 #define ASC_FLAG_ISA_OVER_16MB 0x40
262 #define ASC_FLAG_DOS_VM_CALLBACK 0x80
263 #define ASC_TAG_FLAG_EXTRA_BYTES 0x10
264 #define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
265 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
266 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
267 #define ASC_SCSIQ_CPY_BEG 4
268 #define ASC_SCSIQ_SGHD_CPY_BEG 2
269 #define ASC_SCSIQ_B_FWD 0
270 #define ASC_SCSIQ_B_BWD 1
271 #define ASC_SCSIQ_B_STATUS 2
272 #define ASC_SCSIQ_B_QNO 3
273 #define ASC_SCSIQ_B_CNTL 4
274 #define ASC_SCSIQ_B_SG_QUEUE_CNT 5
275 #define ASC_SCSIQ_D_DATA_ADDR 8
276 #define ASC_SCSIQ_D_DATA_CNT 12
277 #define ASC_SCSIQ_B_SENSE_LEN 20
278 #define ASC_SCSIQ_DONE_INFO_BEG 22
279 #define ASC_SCSIQ_D_SRBPTR 22
280 #define ASC_SCSIQ_B_TARGET_IX 26
281 #define ASC_SCSIQ_B_CDB_LEN 28
282 #define ASC_SCSIQ_B_TAG_CODE 29
283 #define ASC_SCSIQ_W_VM_ID 30
284 #define ASC_SCSIQ_DONE_STATUS 32
285 #define ASC_SCSIQ_HOST_STATUS 33
286 #define ASC_SCSIQ_SCSI_STATUS 34
287 #define ASC_SCSIQ_CDB_BEG 36
288 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
289 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
290 #define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
291 #define ASC_SCSIQ_B_SG_WK_QP 49
292 #define ASC_SCSIQ_B_SG_WK_IX 50
293 #define ASC_SCSIQ_W_ALT_DC1 52
294 #define ASC_SCSIQ_B_LIST_CNT 6
295 #define ASC_SCSIQ_B_CUR_LIST_CNT 7
296 #define ASC_SGQ_B_SG_CNTL 4
297 #define ASC_SGQ_B_SG_HEAD_QP 5
298 #define ASC_SGQ_B_SG_LIST_CNT 6
299 #define ASC_SGQ_B_SG_CUR_LIST_CNT 7
300 #define ASC_SGQ_LIST_BEG 8
301 #define ASC_DEF_SCSI1_QNG 4
302 #define ASC_MAX_SCSI1_QNG 4
303 #define ASC_DEF_SCSI2_QNG 16
304 #define ASC_MAX_SCSI2_QNG 32
305 #define ASC_TAG_CODE_MASK 0x23
306 #define ASC_STOP_REQ_RISC_STOP 0x01
307 #define ASC_STOP_ACK_RISC_STOP 0x03
308 #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
309 #define ASC_STOP_CLEAN_UP_DISC_Q 0x20
310 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
311 #define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
312 #define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
313 #define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
314 #define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
315 #define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
316 #define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
317 #define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
319 typedef struct asc_scsiq_1 {
320 uchar status;
321 uchar q_no;
322 uchar cntl;
323 uchar sg_queue_cnt;
324 uchar target_id;
325 uchar target_lun;
326 ASC_PADDR data_addr;
327 ASC_DCNT data_cnt;
328 ASC_PADDR sense_addr;
329 uchar sense_len;
330 uchar extra_bytes;
331 } ASC_SCSIQ_1;
333 typedef struct asc_scsiq_2 {
334 ASC_VADDR srb_ptr;
335 uchar target_ix;
336 uchar flag;
337 uchar cdb_len;
338 uchar tag_code;
339 ushort vm_id;
340 } ASC_SCSIQ_2;
342 typedef struct asc_scsiq_3 {
343 uchar done_stat;
344 uchar host_stat;
345 uchar scsi_stat;
346 uchar scsi_msg;
347 } ASC_SCSIQ_3;
349 typedef struct asc_scsiq_4 {
350 uchar cdb[ASC_MAX_CDB_LEN];
351 uchar y_first_sg_list_qp;
352 uchar y_working_sg_qp;
353 uchar y_working_sg_ix;
354 uchar y_res;
355 ushort x_req_count;
356 ushort x_reconnect_rtn;
357 ASC_PADDR x_saved_data_addr;
358 ASC_DCNT x_saved_data_cnt;
359 } ASC_SCSIQ_4;
361 typedef struct asc_q_done_info {
362 ASC_SCSIQ_2 d2;
363 ASC_SCSIQ_3 d3;
364 uchar q_status;
365 uchar q_no;
366 uchar cntl;
367 uchar sense_len;
368 uchar extra_bytes;
369 uchar res;
370 ASC_DCNT remain_bytes;
371 } ASC_QDONE_INFO;
373 typedef struct asc_sg_list {
374 ASC_PADDR addr;
375 ASC_DCNT bytes;
376 } ASC_SG_LIST;
378 typedef struct asc_sg_head {
379 ushort entry_cnt;
380 ushort queue_cnt;
381 ushort entry_to_copy;
382 ushort res;
383 ASC_SG_LIST sg_list[0];
384 } ASC_SG_HEAD;
386 typedef struct asc_scsi_q {
387 ASC_SCSIQ_1 q1;
388 ASC_SCSIQ_2 q2;
389 uchar *cdbptr;
390 ASC_SG_HEAD *sg_head;
391 ushort remain_sg_entry_cnt;
392 ushort next_sg_index;
393 } ASC_SCSI_Q;
395 typedef struct asc_scsi_req_q {
396 ASC_SCSIQ_1 r1;
397 ASC_SCSIQ_2 r2;
398 uchar *cdbptr;
399 ASC_SG_HEAD *sg_head;
400 uchar *sense_ptr;
401 ASC_SCSIQ_3 r3;
402 uchar cdb[ASC_MAX_CDB_LEN];
403 uchar sense[ASC_MIN_SENSE_LEN];
404 } ASC_SCSI_REQ_Q;
406 typedef struct asc_scsi_bios_req_q {
407 ASC_SCSIQ_1 r1;
408 ASC_SCSIQ_2 r2;
409 uchar *cdbptr;
410 ASC_SG_HEAD *sg_head;
411 uchar *sense_ptr;
412 ASC_SCSIQ_3 r3;
413 uchar cdb[ASC_MAX_CDB_LEN];
414 uchar sense[ASC_MIN_SENSE_LEN];
415 } ASC_SCSI_BIOS_REQ_Q;
417 typedef struct asc_risc_q {
418 uchar fwd;
419 uchar bwd;
420 ASC_SCSIQ_1 i1;
421 ASC_SCSIQ_2 i2;
422 ASC_SCSIQ_3 i3;
423 ASC_SCSIQ_4 i4;
424 } ASC_RISC_Q;
426 typedef struct asc_sg_list_q {
427 uchar seq_no;
428 uchar q_no;
429 uchar cntl;
430 uchar sg_head_qp;
431 uchar sg_list_cnt;
432 uchar sg_cur_list_cnt;
433 } ASC_SG_LIST_Q;
435 typedef struct asc_risc_sg_list_q {
436 uchar fwd;
437 uchar bwd;
438 ASC_SG_LIST_Q sg;
439 ASC_SG_LIST sg_list[7];
440 } ASC_RISC_SG_LIST_Q;
442 #define ASCQ_ERR_Q_STATUS 0x0D
443 #define ASCQ_ERR_CUR_QNG 0x17
444 #define ASCQ_ERR_SG_Q_LINKS 0x18
445 #define ASCQ_ERR_ISR_RE_ENTRY 0x1A
446 #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
447 #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
450 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
452 #define ASC_WARN_NO_ERROR 0x0000
453 #define ASC_WARN_IO_PORT_ROTATE 0x0001
454 #define ASC_WARN_EEPROM_CHKSUM 0x0002
455 #define ASC_WARN_IRQ_MODIFIED 0x0004
456 #define ASC_WARN_AUTO_CONFIG 0x0008
457 #define ASC_WARN_CMD_QNG_CONFLICT 0x0010
458 #define ASC_WARN_EEPROM_RECOVER 0x0020
459 #define ASC_WARN_CFG_MSW_RECOVER 0x0040
462 * Error code values are set in {ASC/ADV}_DVC_VAR 'err_code'.
464 #define ASC_IERR_NO_CARRIER 0x0001 /* No more carrier memory */
465 #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
466 #define ASC_IERR_SET_PC_ADDR 0x0004
467 #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
468 #define ASC_IERR_ILLEGAL_CONNECTION 0x0010 /* Illegal cable connection */
469 #define ASC_IERR_SINGLE_END_DEVICE 0x0020 /* SE device on DIFF bus */
470 #define ASC_IERR_REVERSED_CABLE 0x0040 /* Narrow flat cable reversed */
471 #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
472 #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD device on LVD port */
473 #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
474 #define ASC_IERR_NO_BUS_TYPE 0x0400
475 #define ASC_IERR_BIST_PRE_TEST 0x0800 /* BIST pre-test error */
476 #define ASC_IERR_BIST_RAM_TEST 0x1000 /* BIST RAM test error */
477 #define ASC_IERR_BAD_CHIPTYPE 0x2000 /* Invalid chip_type setting */
479 #define ASC_DEF_MAX_TOTAL_QNG (0xF0)
480 #define ASC_MIN_TAG_Q_PER_DVC (0x04)
481 #define ASC_MIN_FREE_Q (0x02)
482 #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
483 #define ASC_MAX_TOTAL_QNG 240
484 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
485 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
486 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
487 #define ASC_MAX_INRAM_TAG_QNG 16
488 #define ASC_IOADR_GAP 0x10
489 #define ASC_MAX_SYN_XFER_NO 16
490 #define ASC_SYN_MAX_OFFSET 0x0F
491 #define ASC_DEF_SDTR_OFFSET 0x0F
492 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
493 #define SYN_XFER_NS_0 25
494 #define SYN_XFER_NS_1 30
495 #define SYN_XFER_NS_2 35
496 #define SYN_XFER_NS_3 40
497 #define SYN_XFER_NS_4 50
498 #define SYN_XFER_NS_5 60
499 #define SYN_XFER_NS_6 70
500 #define SYN_XFER_NS_7 85
501 #define SYN_ULTRA_XFER_NS_0 12
502 #define SYN_ULTRA_XFER_NS_1 19
503 #define SYN_ULTRA_XFER_NS_2 25
504 #define SYN_ULTRA_XFER_NS_3 32
505 #define SYN_ULTRA_XFER_NS_4 38
506 #define SYN_ULTRA_XFER_NS_5 44
507 #define SYN_ULTRA_XFER_NS_6 50
508 #define SYN_ULTRA_XFER_NS_7 57
509 #define SYN_ULTRA_XFER_NS_8 63
510 #define SYN_ULTRA_XFER_NS_9 69
511 #define SYN_ULTRA_XFER_NS_10 75
512 #define SYN_ULTRA_XFER_NS_11 82
513 #define SYN_ULTRA_XFER_NS_12 88
514 #define SYN_ULTRA_XFER_NS_13 94
515 #define SYN_ULTRA_XFER_NS_14 100
516 #define SYN_ULTRA_XFER_NS_15 107
518 typedef struct ext_msg {
519 uchar msg_type;
520 uchar msg_len;
521 uchar msg_req;
522 union {
523 struct {
524 uchar sdtr_xfer_period;
525 uchar sdtr_req_ack_offset;
526 } sdtr;
527 struct {
528 uchar wdtr_width;
529 } wdtr;
530 struct {
531 uchar mdp_b3;
532 uchar mdp_b2;
533 uchar mdp_b1;
534 uchar mdp_b0;
535 } mdp;
536 } u_ext_msg;
537 uchar res;
538 } EXT_MSG;
540 #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
541 #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
542 #define wdtr_width u_ext_msg.wdtr.wdtr_width
543 #define mdp_b3 u_ext_msg.mdp_b3
544 #define mdp_b2 u_ext_msg.mdp_b2
545 #define mdp_b1 u_ext_msg.mdp_b1
546 #define mdp_b0 u_ext_msg.mdp_b0
548 typedef struct asc_dvc_cfg {
549 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
550 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
551 ASC_SCSI_BIT_ID_TYPE disc_enable;
552 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
553 uchar chip_scsi_id;
554 uchar isa_dma_speed;
555 uchar isa_dma_channel;
556 uchar chip_version;
557 ushort lib_serial_no;
558 ushort lib_version;
559 ushort mcode_date;
560 ushort mcode_version;
561 uchar max_tag_qng[ASC_MAX_TID + 1];
562 uchar *overrun_buf;
563 uchar sdtr_period_offset[ASC_MAX_TID + 1];
564 uchar adapter_info[6];
565 } ASC_DVC_CFG;
567 #define ASC_DEF_DVC_CNTL 0xFFFF
568 #define ASC_DEF_CHIP_SCSI_ID 7
569 #define ASC_DEF_ISA_DMA_SPEED 4
570 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001
571 #define ASC_INIT_STATE_END_GET_CFG 0x0002
572 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004
573 #define ASC_INIT_STATE_END_SET_CFG 0x0008
574 #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
575 #define ASC_INIT_STATE_END_LOAD_MC 0x0020
576 #define ASC_INIT_STATE_BEG_INQUIRY 0x0040
577 #define ASC_INIT_STATE_END_INQUIRY 0x0080
578 #define ASC_INIT_RESET_SCSI_DONE 0x0100
579 #define ASC_INIT_STATE_WITHOUT_EEP 0x8000
580 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001
581 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
582 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
583 #define ASC_MIN_TAGGED_CMD 7
584 #define ASC_MAX_SCSI_RESET_WAIT 30
586 struct asc_dvc_var; /* Forward Declaration. */
588 typedef struct asc_dvc_var {
589 PortAddr iop_base;
590 ushort err_code;
591 ushort dvc_cntl;
592 ushort bug_fix_cntl;
593 ushort bus_type;
594 ASC_SCSI_BIT_ID_TYPE init_sdtr;
595 ASC_SCSI_BIT_ID_TYPE sdtr_done;
596 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
597 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
598 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
599 ASC_SCSI_BIT_ID_TYPE start_motor;
600 uchar scsi_reset_wait;
601 uchar chip_no;
602 char is_in_int;
603 uchar max_total_qng;
604 uchar cur_total_qng;
605 uchar in_critical_cnt;
606 uchar last_q_shortage;
607 ushort init_state;
608 uchar cur_dvc_qng[ASC_MAX_TID + 1];
609 uchar max_dvc_qng[ASC_MAX_TID + 1];
610 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
611 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
612 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
613 ASC_DVC_CFG *cfg;
614 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
615 char redo_scam;
616 ushort res2;
617 uchar dos_int13_table[ASC_MAX_TID + 1];
618 ASC_DCNT max_dma_count;
619 ASC_SCSI_BIT_ID_TYPE no_scam;
620 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
621 uchar max_sdtr_index;
622 uchar host_init_sdtr_index;
623 struct asc_board *drv_ptr;
624 ASC_DCNT uc_break;
625 } ASC_DVC_VAR;
627 typedef struct asc_dvc_inq_info {
628 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
629 } ASC_DVC_INQ_INFO;
631 typedef struct asc_cap_info {
632 ASC_DCNT lba;
633 ASC_DCNT blk_size;
634 } ASC_CAP_INFO;
636 typedef struct asc_cap_info_array {
637 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
638 } ASC_CAP_INFO_ARRAY;
640 #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
641 #define ASC_MCNTL_NULL_TARGET (ushort)0x0002
642 #define ASC_CNTL_INITIATOR (ushort)0x0001
643 #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
644 #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
645 #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
646 #define ASC_CNTL_NO_SCAM (ushort)0x0010
647 #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
648 #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
649 #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
650 #define ASC_CNTL_RESET_SCSI (ushort)0x0200
651 #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
652 #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
653 #define ASC_CNTL_SCSI_PARITY (ushort)0x1000
654 #define ASC_CNTL_BURST_MODE (ushort)0x2000
655 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
656 #define ASC_EEP_DVC_CFG_BEG_VL 2
657 #define ASC_EEP_MAX_DVC_ADDR_VL 15
658 #define ASC_EEP_DVC_CFG_BEG 32
659 #define ASC_EEP_MAX_DVC_ADDR 45
660 #define ASC_EEP_MAX_RETRY 20
663 * These macros keep the chip SCSI id and ISA DMA speed
664 * bitfields in board order. C bitfields aren't portable
665 * between big and little-endian platforms so they are
666 * not used.
669 #define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
670 #define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
671 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
672 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
673 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
674 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
676 typedef struct asceep_config {
677 ushort cfg_lsw;
678 ushort cfg_msw;
679 uchar init_sdtr;
680 uchar disc_enable;
681 uchar use_cmd_qng;
682 uchar start_motor;
683 uchar max_total_qng;
684 uchar max_tag_qng;
685 uchar bios_scan;
686 uchar power_up_wait;
687 uchar no_scam;
688 uchar id_speed; /* low order 4 bits is chip scsi id */
689 /* high order 4 bits is isa dma speed */
690 uchar dos_int13_table[ASC_MAX_TID + 1];
691 uchar adapter_info[6];
692 ushort cntl;
693 ushort chksum;
694 } ASCEEP_CONFIG;
696 #define ASC_EEP_CMD_READ 0x80
697 #define ASC_EEP_CMD_WRITE 0x40
698 #define ASC_EEP_CMD_WRITE_ABLE 0x30
699 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
700 #define ASC_OVERRUN_BSIZE 0x00000048UL
701 #define ASCV_MSGOUT_BEG 0x0000
702 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
703 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
704 #define ASCV_BREAK_SAVED_CODE (ushort)0x0006
705 #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
706 #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
707 #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
708 #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
709 #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
710 #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
711 #define ASCV_BREAK_ADDR (ushort)0x0028
712 #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
713 #define ASCV_BREAK_CONTROL (ushort)0x002C
714 #define ASCV_BREAK_HIT_COUNT (ushort)0x002E
716 #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
717 #define ASCV_MCODE_CHKSUM_W (ushort)0x0032
718 #define ASCV_MCODE_SIZE_W (ushort)0x0034
719 #define ASCV_STOP_CODE_B (ushort)0x0036
720 #define ASCV_DVC_ERR_CODE_B (ushort)0x0037
721 #define ASCV_OVERRUN_PADDR_D (ushort)0x0038
722 #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
723 #define ASCV_HALTCODE_W (ushort)0x0040
724 #define ASCV_CHKSUM_W (ushort)0x0042
725 #define ASCV_MC_DATE_W (ushort)0x0044
726 #define ASCV_MC_VER_W (ushort)0x0046
727 #define ASCV_NEXTRDY_B (ushort)0x0048
728 #define ASCV_DONENEXT_B (ushort)0x0049
729 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
730 #define ASCV_SCSIBUSY_B (ushort)0x004B
731 #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
732 #define ASCV_CURCDB_B (ushort)0x004D
733 #define ASCV_RCLUN_B (ushort)0x004E
734 #define ASCV_BUSY_QHEAD_B (ushort)0x004F
735 #define ASCV_DISC1_QHEAD_B (ushort)0x0050
736 #define ASCV_DISC_ENABLE_B (ushort)0x0052
737 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
738 #define ASCV_HOSTSCSI_ID_B (ushort)0x0055
739 #define ASCV_MCODE_CNTL_B (ushort)0x0056
740 #define ASCV_NULL_TARGET_B (ushort)0x0057
741 #define ASCV_FREE_Q_HEAD_W (ushort)0x0058
742 #define ASCV_DONE_Q_TAIL_W (ushort)0x005A
743 #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
744 #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
745 #define ASCV_HOST_FLAG_B (ushort)0x005D
746 #define ASCV_TOTAL_READY_Q_B (ushort)0x0064
747 #define ASCV_VER_SERIAL_B (ushort)0x0065
748 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
749 #define ASCV_WTM_FLAG_B (ushort)0x0068
750 #define ASCV_RISC_FLAG_B (ushort)0x006A
751 #define ASCV_REQ_SG_LIST_QP (ushort)0x006B
752 #define ASC_HOST_FLAG_IN_ISR 0x01
753 #define ASC_HOST_FLAG_ACK_INT 0x02
754 #define ASC_RISC_FLAG_GEN_INT 0x01
755 #define ASC_RISC_FLAG_REQ_SG_LIST 0x02
756 #define IOP_CTRL (0x0F)
757 #define IOP_STATUS (0x0E)
758 #define IOP_INT_ACK IOP_STATUS
759 #define IOP_REG_IFC (0x0D)
760 #define IOP_SYN_OFFSET (0x0B)
761 #define IOP_EXTRA_CONTROL (0x0D)
762 #define IOP_REG_PC (0x0C)
763 #define IOP_RAM_ADDR (0x0A)
764 #define IOP_RAM_DATA (0x08)
765 #define IOP_EEP_DATA (0x06)
766 #define IOP_EEP_CMD (0x07)
767 #define IOP_VERSION (0x03)
768 #define IOP_CONFIG_HIGH (0x04)
769 #define IOP_CONFIG_LOW (0x02)
770 #define IOP_SIG_BYTE (0x01)
771 #define IOP_SIG_WORD (0x00)
772 #define IOP_REG_DC1 (0x0E)
773 #define IOP_REG_DC0 (0x0C)
774 #define IOP_REG_SB (0x0B)
775 #define IOP_REG_DA1 (0x0A)
776 #define IOP_REG_DA0 (0x08)
777 #define IOP_REG_SC (0x09)
778 #define IOP_DMA_SPEED (0x07)
779 #define IOP_REG_FLAG (0x07)
780 #define IOP_FIFO_H (0x06)
781 #define IOP_FIFO_L (0x04)
782 #define IOP_REG_ID (0x05)
783 #define IOP_REG_QP (0x03)
784 #define IOP_REG_IH (0x02)
785 #define IOP_REG_IX (0x01)
786 #define IOP_REG_AX (0x00)
787 #define IFC_REG_LOCK (0x00)
788 #define IFC_REG_UNLOCK (0x09)
789 #define IFC_WR_EN_FILTER (0x10)
790 #define IFC_RD_NO_EEPROM (0x10)
791 #define IFC_SLEW_RATE (0x20)
792 #define IFC_ACT_NEG (0x40)
793 #define IFC_INP_FILTER (0x80)
794 #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
795 #define SC_SEL (uchar)(0x80)
796 #define SC_BSY (uchar)(0x40)
797 #define SC_ACK (uchar)(0x20)
798 #define SC_REQ (uchar)(0x10)
799 #define SC_ATN (uchar)(0x08)
800 #define SC_IO (uchar)(0x04)
801 #define SC_CD (uchar)(0x02)
802 #define SC_MSG (uchar)(0x01)
803 #define SEC_SCSI_CTL (uchar)(0x80)
804 #define SEC_ACTIVE_NEGATE (uchar)(0x40)
805 #define SEC_SLEW_RATE (uchar)(0x20)
806 #define SEC_ENABLE_FILTER (uchar)(0x10)
807 #define ASC_HALT_EXTMSG_IN (ushort)0x8000
808 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
809 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
810 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
811 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
812 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
813 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
814 #define ASC_MAX_QNO 0xF8
815 #define ASC_DATA_SEC_BEG (ushort)0x0080
816 #define ASC_DATA_SEC_END (ushort)0x0080
817 #define ASC_CODE_SEC_BEG (ushort)0x0080
818 #define ASC_CODE_SEC_END (ushort)0x0080
819 #define ASC_QADR_BEG (0x4000)
820 #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
821 #define ASC_QADR_END (ushort)0x7FFF
822 #define ASC_QLAST_ADR (ushort)0x7FC0
823 #define ASC_QBLK_SIZE 0x40
824 #define ASC_BIOS_DATA_QBEG 0xF8
825 #define ASC_MIN_ACTIVE_QNO 0x01
826 #define ASC_QLINK_END 0xFF
827 #define ASC_EEPROM_WORDS 0x10
828 #define ASC_MAX_MGS_LEN 0x10
829 #define ASC_BIOS_ADDR_DEF 0xDC00
830 #define ASC_BIOS_SIZE 0x3800
831 #define ASC_BIOS_RAM_OFF 0x3800
832 #define ASC_BIOS_RAM_SIZE 0x800
833 #define ASC_BIOS_MIN_ADDR 0xC000
834 #define ASC_BIOS_MAX_ADDR 0xEC00
835 #define ASC_BIOS_BANK_SIZE 0x0400
836 #define ASC_MCODE_START_ADDR 0x0080
837 #define ASC_CFG0_HOST_INT_ON 0x0020
838 #define ASC_CFG0_BIOS_ON 0x0040
839 #define ASC_CFG0_VERA_BURST_ON 0x0080
840 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
841 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
842 #define ASC_CFG1_LRAM_8BITS_ON 0x0800
843 #define ASC_CFG_MSW_CLR_MASK 0x3080
844 #define CSW_TEST1 (ASC_CS_TYPE)0x8000
845 #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
846 #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
847 #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
848 #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
849 #define CSW_TEST2 (ASC_CS_TYPE)0x0400
850 #define CSW_TEST3 (ASC_CS_TYPE)0x0200
851 #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
852 #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
853 #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
854 #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
855 #define CSW_HALTED (ASC_CS_TYPE)0x0010
856 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
857 #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
858 #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
859 #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
860 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
861 #define CIW_INT_ACK (ASC_CS_TYPE)0x0100
862 #define CIW_TEST1 (ASC_CS_TYPE)0x0200
863 #define CIW_TEST2 (ASC_CS_TYPE)0x0400
864 #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
865 #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
866 #define CC_CHIP_RESET (uchar)0x80
867 #define CC_SCSI_RESET (uchar)0x40
868 #define CC_HALT (uchar)0x20
869 #define CC_SINGLE_STEP (uchar)0x10
870 #define CC_DMA_ABLE (uchar)0x08
871 #define CC_TEST (uchar)0x04
872 #define CC_BANK_ONE (uchar)0x02
873 #define CC_DIAG (uchar)0x01
874 #define ASC_1000_ID0W 0x04C1
875 #define ASC_1000_ID0W_FIX 0x00C1
876 #define ASC_1000_ID1B 0x25
877 #define ASC_EISA_REV_IOP_MASK (0x0C83)
878 #define ASC_EISA_CFG_IOP_MASK (0x0C86)
879 #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
880 #define INS_HALTINT (ushort)0x6281
881 #define INS_HALT (ushort)0x6280
882 #define INS_SINT (ushort)0x6200
883 #define INS_RFLAG_WTM (ushort)0x7380
884 #define ASC_MC_SAVE_CODE_WSIZE 0x500
885 #define ASC_MC_SAVE_DATA_WSIZE 0x40
887 typedef struct asc_mc_saved {
888 ushort data[ASC_MC_SAVE_DATA_WSIZE];
889 ushort code[ASC_MC_SAVE_CODE_WSIZE];
890 } ASC_MC_SAVED;
892 #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
893 #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
894 #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
895 #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
896 #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
897 #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
898 #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
899 #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
900 #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
901 #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
902 #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data))
903 #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id))
904 #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data)
905 #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id))
906 #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
907 #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
908 #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
909 #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
910 #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
911 #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
912 #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
913 #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
914 #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
915 #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
916 #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
917 #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
918 #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
919 #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
920 #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
921 #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
922 #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
923 #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
924 #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
925 #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
926 #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
927 #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
928 #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
929 #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
930 #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
931 #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
932 #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
933 #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
934 #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
935 #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
936 #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
937 #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
938 #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
939 #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
940 #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
941 #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
942 #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
943 #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
944 #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
945 #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
946 #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
947 #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
948 #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
949 #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
950 #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
951 #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
952 #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
953 #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
954 #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
955 #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
956 #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
957 #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
958 #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
959 #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
961 #define ADV_LIB_VERSION_MAJOR 5
962 #define ADV_LIB_VERSION_MINOR 14
965 * Define Adv Library required special types.
969 * Portable Data Types
971 * Any instance where a 32-bit long or pointer type is assumed
972 * for precision or HW defined structures, the following define
973 * types must be used. In Linux the char, short, and int types
974 * are all consistent at 8, 16, and 32 bits respectively. Pointers
975 * and long types are 64 bits on Alpha and UltraSPARC.
977 #define ADV_PADDR __u32 /* Physical address data type. */
978 #define ADV_VADDR __u32 /* Virtual address data type. */
979 #define ADV_DCNT __u32 /* Unsigned Data count type. */
980 #define ADV_SDCNT __s32 /* Signed Data count type. */
983 * These macros are used to convert a virtual address to a
984 * 32-bit value. This currently can be used on Linux Alpha
985 * which uses 64-bit virtual address but a 32-bit bus address.
986 * This is likely to break in the future, but doing this now
987 * will give us time to change the HW and FW to handle 64-bit
988 * addresses.
990 #define ADV_VADDR_TO_U32 virt_to_bus
991 #define ADV_U32_TO_VADDR bus_to_virt
993 #define AdvPortAddr void __iomem * /* Virtual memory address size */
996 * Define Adv Library required memory access macros.
998 #define ADV_MEM_READB(addr) readb(addr)
999 #define ADV_MEM_READW(addr) readw(addr)
1000 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
1001 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
1002 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
1004 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
1007 * Define total number of simultaneous maximum element scatter-gather
1008 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
1009 * maximum number of outstanding commands per wide host adapter. Each
1010 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
1011 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
1012 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
1013 * structures or 255 scatter-gather elements.
1016 #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
1019 * Define Adv Library required maximum number of scatter-gather
1020 * elements per request.
1022 #define ADV_MAX_SG_LIST 255
1024 /* Number of SG blocks needed. */
1025 #define ADV_NUM_SG_BLOCK \
1026 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1028 /* Total contiguous memory needed for SG blocks. */
1029 #define ADV_SG_TOTAL_MEM_SIZE \
1030 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
1032 #define ADV_PAGE_SIZE PAGE_SIZE
1034 #define ADV_NUM_PAGE_CROSSING \
1035 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1037 #define ADV_EEP_DVC_CFG_BEGIN (0x00)
1038 #define ADV_EEP_DVC_CFG_END (0x15)
1039 #define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1040 #define ADV_EEP_MAX_WORD_ADDR (0x1E)
1042 #define ADV_EEP_DELAY_MS 100
1044 #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
1045 #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1047 * For the ASC3550 Bit 13 is Termination Polarity control bit.
1048 * For later ICs Bit 13 controls whether the CIS (Card Information
1049 * Service Section) is loaded from EEPROM.
1051 #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
1052 #define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1054 * ASC38C1600 Bit 11
1056 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1057 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1058 * Function 0 will specify INT B.
1060 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1061 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1062 * Function 1 will specify INT A.
1064 #define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
1066 typedef struct adveep_3550_config {
1067 /* Word Offset, Description */
1069 ushort cfg_lsw; /* 00 power up initialization */
1070 /* bit 13 set - Term Polarity Control */
1071 /* bit 14 set - BIOS Enable */
1072 /* bit 15 set - Big Endian Mode */
1073 ushort cfg_msw; /* 01 unused */
1074 ushort disc_enable; /* 02 disconnect enable */
1075 ushort wdtr_able; /* 03 Wide DTR able */
1076 ushort sdtr_able; /* 04 Synchronous DTR able */
1077 ushort start_motor; /* 05 send start up motor */
1078 ushort tagqng_able; /* 06 tag queuing able */
1079 ushort bios_scan; /* 07 BIOS device control */
1080 ushort scam_tolerant; /* 08 no scam */
1082 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1083 uchar bios_boot_delay; /* power up wait */
1085 uchar scsi_reset_delay; /* 10 reset delay */
1086 uchar bios_id_lun; /* first boot device scsi id & lun */
1087 /* high nibble is lun */
1088 /* low nibble is scsi id */
1090 uchar termination; /* 11 0 - automatic */
1091 /* 1 - low off / high off */
1092 /* 2 - low off / high on */
1093 /* 3 - low on / high on */
1094 /* There is no low on / high off */
1096 uchar reserved1; /* reserved byte (not used) */
1098 ushort bios_ctrl; /* 12 BIOS control bits */
1099 /* bit 0 BIOS don't act as initiator. */
1100 /* bit 1 BIOS > 1 GB support */
1101 /* bit 2 BIOS > 2 Disk Support */
1102 /* bit 3 BIOS don't support removables */
1103 /* bit 4 BIOS support bootable CD */
1104 /* bit 5 BIOS scan enabled */
1105 /* bit 6 BIOS support multiple LUNs */
1106 /* bit 7 BIOS display of message */
1107 /* bit 8 SCAM disabled */
1108 /* bit 9 Reset SCSI bus during init. */
1109 /* bit 10 */
1110 /* bit 11 No verbose initialization. */
1111 /* bit 12 SCSI parity enabled */
1112 /* bit 13 */
1113 /* bit 14 */
1114 /* bit 15 */
1115 ushort ultra_able; /* 13 ULTRA speed able */
1116 ushort reserved2; /* 14 reserved */
1117 uchar max_host_qng; /* 15 maximum host queuing */
1118 uchar max_dvc_qng; /* maximum per device queuing */
1119 ushort dvc_cntl; /* 16 control bit for driver */
1120 ushort bug_fix; /* 17 control bit for bug fix */
1121 ushort serial_number_word1; /* 18 Board serial number word 1 */
1122 ushort serial_number_word2; /* 19 Board serial number word 2 */
1123 ushort serial_number_word3; /* 20 Board serial number word 3 */
1124 ushort check_sum; /* 21 EEP check sum */
1125 uchar oem_name[16]; /* 22 OEM name */
1126 ushort dvc_err_code; /* 30 last device driver error code */
1127 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1128 ushort adv_err_addr; /* 32 last uc error address */
1129 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1130 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1131 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1132 ushort num_of_err; /* 36 number of error */
1133 } ADVEEP_3550_CONFIG;
1135 typedef struct adveep_38C0800_config {
1136 /* Word Offset, Description */
1138 ushort cfg_lsw; /* 00 power up initialization */
1139 /* bit 13 set - Load CIS */
1140 /* bit 14 set - BIOS Enable */
1141 /* bit 15 set - Big Endian Mode */
1142 ushort cfg_msw; /* 01 unused */
1143 ushort disc_enable; /* 02 disconnect enable */
1144 ushort wdtr_able; /* 03 Wide DTR able */
1145 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1146 ushort start_motor; /* 05 send start up motor */
1147 ushort tagqng_able; /* 06 tag queuing able */
1148 ushort bios_scan; /* 07 BIOS device control */
1149 ushort scam_tolerant; /* 08 no scam */
1151 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1152 uchar bios_boot_delay; /* power up wait */
1154 uchar scsi_reset_delay; /* 10 reset delay */
1155 uchar bios_id_lun; /* first boot device scsi id & lun */
1156 /* high nibble is lun */
1157 /* low nibble is scsi id */
1159 uchar termination_se; /* 11 0 - automatic */
1160 /* 1 - low off / high off */
1161 /* 2 - low off / high on */
1162 /* 3 - low on / high on */
1163 /* There is no low on / high off */
1165 uchar termination_lvd; /* 11 0 - automatic */
1166 /* 1 - low off / high off */
1167 /* 2 - low off / high on */
1168 /* 3 - low on / high on */
1169 /* There is no low on / high off */
1171 ushort bios_ctrl; /* 12 BIOS control bits */
1172 /* bit 0 BIOS don't act as initiator. */
1173 /* bit 1 BIOS > 1 GB support */
1174 /* bit 2 BIOS > 2 Disk Support */
1175 /* bit 3 BIOS don't support removables */
1176 /* bit 4 BIOS support bootable CD */
1177 /* bit 5 BIOS scan enabled */
1178 /* bit 6 BIOS support multiple LUNs */
1179 /* bit 7 BIOS display of message */
1180 /* bit 8 SCAM disabled */
1181 /* bit 9 Reset SCSI bus during init. */
1182 /* bit 10 */
1183 /* bit 11 No verbose initialization. */
1184 /* bit 12 SCSI parity enabled */
1185 /* bit 13 */
1186 /* bit 14 */
1187 /* bit 15 */
1188 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1189 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1190 uchar max_host_qng; /* 15 maximum host queueing */
1191 uchar max_dvc_qng; /* maximum per device queuing */
1192 ushort dvc_cntl; /* 16 control bit for driver */
1193 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1194 ushort serial_number_word1; /* 18 Board serial number word 1 */
1195 ushort serial_number_word2; /* 19 Board serial number word 2 */
1196 ushort serial_number_word3; /* 20 Board serial number word 3 */
1197 ushort check_sum; /* 21 EEP check sum */
1198 uchar oem_name[16]; /* 22 OEM name */
1199 ushort dvc_err_code; /* 30 last device driver error code */
1200 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1201 ushort adv_err_addr; /* 32 last uc error address */
1202 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1203 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1204 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1205 ushort reserved36; /* 36 reserved */
1206 ushort reserved37; /* 37 reserved */
1207 ushort reserved38; /* 38 reserved */
1208 ushort reserved39; /* 39 reserved */
1209 ushort reserved40; /* 40 reserved */
1210 ushort reserved41; /* 41 reserved */
1211 ushort reserved42; /* 42 reserved */
1212 ushort reserved43; /* 43 reserved */
1213 ushort reserved44; /* 44 reserved */
1214 ushort reserved45; /* 45 reserved */
1215 ushort reserved46; /* 46 reserved */
1216 ushort reserved47; /* 47 reserved */
1217 ushort reserved48; /* 48 reserved */
1218 ushort reserved49; /* 49 reserved */
1219 ushort reserved50; /* 50 reserved */
1220 ushort reserved51; /* 51 reserved */
1221 ushort reserved52; /* 52 reserved */
1222 ushort reserved53; /* 53 reserved */
1223 ushort reserved54; /* 54 reserved */
1224 ushort reserved55; /* 55 reserved */
1225 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1226 ushort cisprt_msw; /* 57 CIS PTR MSW */
1227 ushort subsysvid; /* 58 SubSystem Vendor ID */
1228 ushort subsysid; /* 59 SubSystem ID */
1229 ushort reserved60; /* 60 reserved */
1230 ushort reserved61; /* 61 reserved */
1231 ushort reserved62; /* 62 reserved */
1232 ushort reserved63; /* 63 reserved */
1233 } ADVEEP_38C0800_CONFIG;
1235 typedef struct adveep_38C1600_config {
1236 /* Word Offset, Description */
1238 ushort cfg_lsw; /* 00 power up initialization */
1239 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
1240 /* clear - Func. 0 INTA, Func. 1 INTB */
1241 /* bit 13 set - Load CIS */
1242 /* bit 14 set - BIOS Enable */
1243 /* bit 15 set - Big Endian Mode */
1244 ushort cfg_msw; /* 01 unused */
1245 ushort disc_enable; /* 02 disconnect enable */
1246 ushort wdtr_able; /* 03 Wide DTR able */
1247 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1248 ushort start_motor; /* 05 send start up motor */
1249 ushort tagqng_able; /* 06 tag queuing able */
1250 ushort bios_scan; /* 07 BIOS device control */
1251 ushort scam_tolerant; /* 08 no scam */
1253 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1254 uchar bios_boot_delay; /* power up wait */
1256 uchar scsi_reset_delay; /* 10 reset delay */
1257 uchar bios_id_lun; /* first boot device scsi id & lun */
1258 /* high nibble is lun */
1259 /* low nibble is scsi id */
1261 uchar termination_se; /* 11 0 - automatic */
1262 /* 1 - low off / high off */
1263 /* 2 - low off / high on */
1264 /* 3 - low on / high on */
1265 /* There is no low on / high off */
1267 uchar termination_lvd; /* 11 0 - automatic */
1268 /* 1 - low off / high off */
1269 /* 2 - low off / high on */
1270 /* 3 - low on / high on */
1271 /* There is no low on / high off */
1273 ushort bios_ctrl; /* 12 BIOS control bits */
1274 /* bit 0 BIOS don't act as initiator. */
1275 /* bit 1 BIOS > 1 GB support */
1276 /* bit 2 BIOS > 2 Disk Support */
1277 /* bit 3 BIOS don't support removables */
1278 /* bit 4 BIOS support bootable CD */
1279 /* bit 5 BIOS scan enabled */
1280 /* bit 6 BIOS support multiple LUNs */
1281 /* bit 7 BIOS display of message */
1282 /* bit 8 SCAM disabled */
1283 /* bit 9 Reset SCSI bus during init. */
1284 /* bit 10 Basic Integrity Checking disabled */
1285 /* bit 11 No verbose initialization. */
1286 /* bit 12 SCSI parity enabled */
1287 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
1288 /* bit 14 */
1289 /* bit 15 */
1290 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1291 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1292 uchar max_host_qng; /* 15 maximum host queueing */
1293 uchar max_dvc_qng; /* maximum per device queuing */
1294 ushort dvc_cntl; /* 16 control bit for driver */
1295 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1296 ushort serial_number_word1; /* 18 Board serial number word 1 */
1297 ushort serial_number_word2; /* 19 Board serial number word 2 */
1298 ushort serial_number_word3; /* 20 Board serial number word 3 */
1299 ushort check_sum; /* 21 EEP check sum */
1300 uchar oem_name[16]; /* 22 OEM name */
1301 ushort dvc_err_code; /* 30 last device driver error code */
1302 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1303 ushort adv_err_addr; /* 32 last uc error address */
1304 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1305 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1306 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1307 ushort reserved36; /* 36 reserved */
1308 ushort reserved37; /* 37 reserved */
1309 ushort reserved38; /* 38 reserved */
1310 ushort reserved39; /* 39 reserved */
1311 ushort reserved40; /* 40 reserved */
1312 ushort reserved41; /* 41 reserved */
1313 ushort reserved42; /* 42 reserved */
1314 ushort reserved43; /* 43 reserved */
1315 ushort reserved44; /* 44 reserved */
1316 ushort reserved45; /* 45 reserved */
1317 ushort reserved46; /* 46 reserved */
1318 ushort reserved47; /* 47 reserved */
1319 ushort reserved48; /* 48 reserved */
1320 ushort reserved49; /* 49 reserved */
1321 ushort reserved50; /* 50 reserved */
1322 ushort reserved51; /* 51 reserved */
1323 ushort reserved52; /* 52 reserved */
1324 ushort reserved53; /* 53 reserved */
1325 ushort reserved54; /* 54 reserved */
1326 ushort reserved55; /* 55 reserved */
1327 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1328 ushort cisprt_msw; /* 57 CIS PTR MSW */
1329 ushort subsysvid; /* 58 SubSystem Vendor ID */
1330 ushort subsysid; /* 59 SubSystem ID */
1331 ushort reserved60; /* 60 reserved */
1332 ushort reserved61; /* 61 reserved */
1333 ushort reserved62; /* 62 reserved */
1334 ushort reserved63; /* 63 reserved */
1335 } ADVEEP_38C1600_CONFIG;
1338 * EEPROM Commands
1340 #define ASC_EEP_CMD_DONE 0x0200
1342 /* bios_ctrl */
1343 #define BIOS_CTRL_BIOS 0x0001
1344 #define BIOS_CTRL_EXTENDED_XLAT 0x0002
1345 #define BIOS_CTRL_GT_2_DISK 0x0004
1346 #define BIOS_CTRL_BIOS_REMOVABLE 0x0008
1347 #define BIOS_CTRL_BOOTABLE_CD 0x0010
1348 #define BIOS_CTRL_MULTIPLE_LUN 0x0040
1349 #define BIOS_CTRL_DISPLAY_MSG 0x0080
1350 #define BIOS_CTRL_NO_SCAM 0x0100
1351 #define BIOS_CTRL_RESET_SCSI_BUS 0x0200
1352 #define BIOS_CTRL_INIT_VERBOSE 0x0800
1353 #define BIOS_CTRL_SCSI_PARITY 0x1000
1354 #define BIOS_CTRL_AIPP_DIS 0x2000
1356 #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
1358 #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1361 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
1362 * a special 16K Adv Library and Microcode version. After the issue is
1363 * resolved, should restore 32K support.
1365 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
1367 #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1370 * Byte I/O register address from base of 'iop_base'.
1372 #define IOPB_INTR_STATUS_REG 0x00
1373 #define IOPB_CHIP_ID_1 0x01
1374 #define IOPB_INTR_ENABLES 0x02
1375 #define IOPB_CHIP_TYPE_REV 0x03
1376 #define IOPB_RES_ADDR_4 0x04
1377 #define IOPB_RES_ADDR_5 0x05
1378 #define IOPB_RAM_DATA 0x06
1379 #define IOPB_RES_ADDR_7 0x07
1380 #define IOPB_FLAG_REG 0x08
1381 #define IOPB_RES_ADDR_9 0x09
1382 #define IOPB_RISC_CSR 0x0A
1383 #define IOPB_RES_ADDR_B 0x0B
1384 #define IOPB_RES_ADDR_C 0x0C
1385 #define IOPB_RES_ADDR_D 0x0D
1386 #define IOPB_SOFT_OVER_WR 0x0E
1387 #define IOPB_RES_ADDR_F 0x0F
1388 #define IOPB_MEM_CFG 0x10
1389 #define IOPB_RES_ADDR_11 0x11
1390 #define IOPB_GPIO_DATA 0x12
1391 #define IOPB_RES_ADDR_13 0x13
1392 #define IOPB_FLASH_PAGE 0x14
1393 #define IOPB_RES_ADDR_15 0x15
1394 #define IOPB_GPIO_CNTL 0x16
1395 #define IOPB_RES_ADDR_17 0x17
1396 #define IOPB_FLASH_DATA 0x18
1397 #define IOPB_RES_ADDR_19 0x19
1398 #define IOPB_RES_ADDR_1A 0x1A
1399 #define IOPB_RES_ADDR_1B 0x1B
1400 #define IOPB_RES_ADDR_1C 0x1C
1401 #define IOPB_RES_ADDR_1D 0x1D
1402 #define IOPB_RES_ADDR_1E 0x1E
1403 #define IOPB_RES_ADDR_1F 0x1F
1404 #define IOPB_DMA_CFG0 0x20
1405 #define IOPB_DMA_CFG1 0x21
1406 #define IOPB_TICKLE 0x22
1407 #define IOPB_DMA_REG_WR 0x23
1408 #define IOPB_SDMA_STATUS 0x24
1409 #define IOPB_SCSI_BYTE_CNT 0x25
1410 #define IOPB_HOST_BYTE_CNT 0x26
1411 #define IOPB_BYTE_LEFT_TO_XFER 0x27
1412 #define IOPB_BYTE_TO_XFER_0 0x28
1413 #define IOPB_BYTE_TO_XFER_1 0x29
1414 #define IOPB_BYTE_TO_XFER_2 0x2A
1415 #define IOPB_BYTE_TO_XFER_3 0x2B
1416 #define IOPB_ACC_GRP 0x2C
1417 #define IOPB_RES_ADDR_2D 0x2D
1418 #define IOPB_DEV_ID 0x2E
1419 #define IOPB_RES_ADDR_2F 0x2F
1420 #define IOPB_SCSI_DATA 0x30
1421 #define IOPB_RES_ADDR_31 0x31
1422 #define IOPB_RES_ADDR_32 0x32
1423 #define IOPB_SCSI_DATA_HSHK 0x33
1424 #define IOPB_SCSI_CTRL 0x34
1425 #define IOPB_RES_ADDR_35 0x35
1426 #define IOPB_RES_ADDR_36 0x36
1427 #define IOPB_RES_ADDR_37 0x37
1428 #define IOPB_RAM_BIST 0x38
1429 #define IOPB_PLL_TEST 0x39
1430 #define IOPB_PCI_INT_CFG 0x3A
1431 #define IOPB_RES_ADDR_3B 0x3B
1432 #define IOPB_RFIFO_CNT 0x3C
1433 #define IOPB_RES_ADDR_3D 0x3D
1434 #define IOPB_RES_ADDR_3E 0x3E
1435 #define IOPB_RES_ADDR_3F 0x3F
1438 * Word I/O register address from base of 'iop_base'.
1440 #define IOPW_CHIP_ID_0 0x00 /* CID0 */
1441 #define IOPW_CTRL_REG 0x02 /* CC */
1442 #define IOPW_RAM_ADDR 0x04 /* LA */
1443 #define IOPW_RAM_DATA 0x06 /* LD */
1444 #define IOPW_RES_ADDR_08 0x08
1445 #define IOPW_RISC_CSR 0x0A /* CSR */
1446 #define IOPW_SCSI_CFG0 0x0C /* CFG0 */
1447 #define IOPW_SCSI_CFG1 0x0E /* CFG1 */
1448 #define IOPW_RES_ADDR_10 0x10
1449 #define IOPW_SEL_MASK 0x12 /* SM */
1450 #define IOPW_RES_ADDR_14 0x14
1451 #define IOPW_FLASH_ADDR 0x16 /* FA */
1452 #define IOPW_RES_ADDR_18 0x18
1453 #define IOPW_EE_CMD 0x1A /* EC */
1454 #define IOPW_EE_DATA 0x1C /* ED */
1455 #define IOPW_SFIFO_CNT 0x1E /* SFC */
1456 #define IOPW_RES_ADDR_20 0x20
1457 #define IOPW_Q_BASE 0x22 /* QB */
1458 #define IOPW_QP 0x24 /* QP */
1459 #define IOPW_IX 0x26 /* IX */
1460 #define IOPW_SP 0x28 /* SP */
1461 #define IOPW_PC 0x2A /* PC */
1462 #define IOPW_RES_ADDR_2C 0x2C
1463 #define IOPW_RES_ADDR_2E 0x2E
1464 #define IOPW_SCSI_DATA 0x30 /* SD */
1465 #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
1466 #define IOPW_SCSI_CTRL 0x34 /* SC */
1467 #define IOPW_HSHK_CFG 0x36 /* HCFG */
1468 #define IOPW_SXFR_STATUS 0x36 /* SXS */
1469 #define IOPW_SXFR_CNTL 0x38 /* SXL */
1470 #define IOPW_SXFR_CNTH 0x3A /* SXH */
1471 #define IOPW_RES_ADDR_3C 0x3C
1472 #define IOPW_RFIFO_DATA 0x3E /* RFD */
1475 * Doubleword I/O register address from base of 'iop_base'.
1477 #define IOPDW_RES_ADDR_0 0x00
1478 #define IOPDW_RAM_DATA 0x04
1479 #define IOPDW_RES_ADDR_8 0x08
1480 #define IOPDW_RES_ADDR_C 0x0C
1481 #define IOPDW_RES_ADDR_10 0x10
1482 #define IOPDW_COMMA 0x14
1483 #define IOPDW_COMMB 0x18
1484 #define IOPDW_RES_ADDR_1C 0x1C
1485 #define IOPDW_SDMA_ADDR0 0x20
1486 #define IOPDW_SDMA_ADDR1 0x24
1487 #define IOPDW_SDMA_COUNT 0x28
1488 #define IOPDW_SDMA_ERROR 0x2C
1489 #define IOPDW_RDMA_ADDR0 0x30
1490 #define IOPDW_RDMA_ADDR1 0x34
1491 #define IOPDW_RDMA_COUNT 0x38
1492 #define IOPDW_RDMA_ERROR 0x3C
1494 #define ADV_CHIP_ID_BYTE 0x25
1495 #define ADV_CHIP_ID_WORD 0x04C1
1497 #define ADV_INTR_ENABLE_HOST_INTR 0x01
1498 #define ADV_INTR_ENABLE_SEL_INTR 0x02
1499 #define ADV_INTR_ENABLE_DPR_INTR 0x04
1500 #define ADV_INTR_ENABLE_RTA_INTR 0x08
1501 #define ADV_INTR_ENABLE_RMA_INTR 0x10
1502 #define ADV_INTR_ENABLE_RST_INTR 0x20
1503 #define ADV_INTR_ENABLE_DPE_INTR 0x40
1504 #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
1506 #define ADV_INTR_STATUS_INTRA 0x01
1507 #define ADV_INTR_STATUS_INTRB 0x02
1508 #define ADV_INTR_STATUS_INTRC 0x04
1510 #define ADV_RISC_CSR_STOP (0x0000)
1511 #define ADV_RISC_TEST_COND (0x2000)
1512 #define ADV_RISC_CSR_RUN (0x4000)
1513 #define ADV_RISC_CSR_SINGLE_STEP (0x8000)
1515 #define ADV_CTRL_REG_HOST_INTR 0x0100
1516 #define ADV_CTRL_REG_SEL_INTR 0x0200
1517 #define ADV_CTRL_REG_DPR_INTR 0x0400
1518 #define ADV_CTRL_REG_RTA_INTR 0x0800
1519 #define ADV_CTRL_REG_RMA_INTR 0x1000
1520 #define ADV_CTRL_REG_RES_BIT14 0x2000
1521 #define ADV_CTRL_REG_DPE_INTR 0x4000
1522 #define ADV_CTRL_REG_POWER_DONE 0x8000
1523 #define ADV_CTRL_REG_ANY_INTR 0xFF00
1525 #define ADV_CTRL_REG_CMD_RESET 0x00C6
1526 #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
1527 #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
1528 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
1529 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
1531 #define ADV_TICKLE_NOP 0x00
1532 #define ADV_TICKLE_A 0x01
1533 #define ADV_TICKLE_B 0x02
1534 #define ADV_TICKLE_C 0x03
1536 #define AdvIsIntPending(port) \
1537 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
1540 * SCSI_CFG0 Register bit definitions
1542 #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
1543 #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
1544 #define EVEN_PARITY 0x1000 /* Select Even Parity */
1545 #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
1546 #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
1547 #define PRIM_MODE 0x0100 /* Primitive SCSI mode */
1548 #define SCAM_EN 0x0080 /* Enable SCAM selection */
1549 #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
1550 #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
1551 #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
1552 #define OUR_ID 0x000F /* SCSI ID */
1555 * SCSI_CFG1 Register bit definitions
1557 #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
1558 #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
1559 #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
1560 #define FILTER_SEL 0x0C00 /* Filter Period Selection */
1561 #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
1562 #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
1563 #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
1564 #define ACTIVE_DBL 0x0200 /* Disable Active Negation */
1565 #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
1566 #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
1567 #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
1568 #define TERM_CTL 0x0030 /* External SCSI Termination Bits */
1569 #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
1570 #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
1571 #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
1574 * Addendum for ASC-38C0800 Chip
1576 * The ASC-38C1600 Chip uses the same definitions except that the
1577 * bus mode override bits [12:10] have been moved to byte register
1578 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
1579 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
1580 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
1581 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
1582 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
1584 #define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
1585 #define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
1586 #define HVD 0x1000 /* HVD Device Detect */
1587 #define LVD 0x0800 /* LVD Device Detect */
1588 #define SE 0x0400 /* SE Device Detect */
1589 #define TERM_LVD 0x00C0 /* LVD Termination Bits */
1590 #define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
1591 #define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
1592 #define TERM_SE 0x0030 /* SE Termination Bits */
1593 #define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
1594 #define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
1595 #define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
1596 #define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
1597 #define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
1598 #define C_DET_SE 0x0003 /* SE Cable Detect Bits */
1599 #define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
1600 #define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
1602 #define CABLE_ILLEGAL_A 0x7
1603 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
1605 #define CABLE_ILLEGAL_B 0xB
1606 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
1609 * MEM_CFG Register bit definitions
1611 #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
1612 #define FAST_EE_CLK 0x20 /* Diagnostic Bit */
1613 #define RAM_SZ 0x1C /* Specify size of RAM to RISC */
1614 #define RAM_SZ_2KB 0x00 /* 2 KB */
1615 #define RAM_SZ_4KB 0x04 /* 4 KB */
1616 #define RAM_SZ_8KB 0x08 /* 8 KB */
1617 #define RAM_SZ_16KB 0x0C /* 16 KB */
1618 #define RAM_SZ_32KB 0x10 /* 32 KB */
1619 #define RAM_SZ_64KB 0x14 /* 64 KB */
1622 * DMA_CFG0 Register bit definitions
1624 * This register is only accessible to the host.
1626 #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
1627 #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
1628 #define FIFO_THRESH_16B 0x00 /* 16 bytes */
1629 #define FIFO_THRESH_32B 0x20 /* 32 bytes */
1630 #define FIFO_THRESH_48B 0x30 /* 48 bytes */
1631 #define FIFO_THRESH_64B 0x40 /* 64 bytes */
1632 #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
1633 #define FIFO_THRESH_96B 0x60 /* 96 bytes */
1634 #define FIFO_THRESH_112B 0x70 /* 112 bytes */
1635 #define START_CTL 0x0C /* DMA start conditions */
1636 #define START_CTL_TH 0x00 /* Wait threshold level (default) */
1637 #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
1638 #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
1639 #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
1640 #define READ_CMD 0x03 /* Memory Read Method */
1641 #define READ_CMD_MR 0x00 /* Memory Read */
1642 #define READ_CMD_MRL 0x02 /* Memory Read Long */
1643 #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
1646 * ASC-38C0800 RAM BIST Register bit definitions
1648 #define RAM_TEST_MODE 0x80
1649 #define PRE_TEST_MODE 0x40
1650 #define NORMAL_MODE 0x00
1651 #define RAM_TEST_DONE 0x10
1652 #define RAM_TEST_STATUS 0x0F
1653 #define RAM_TEST_HOST_ERROR 0x08
1654 #define RAM_TEST_INTRAM_ERROR 0x04
1655 #define RAM_TEST_RISC_ERROR 0x02
1656 #define RAM_TEST_SCSI_ERROR 0x01
1657 #define RAM_TEST_SUCCESS 0x00
1658 #define PRE_TEST_VALUE 0x05
1659 #define NORMAL_VALUE 0x00
1662 * ASC38C1600 Definitions
1664 * IOPB_PCI_INT_CFG Bit Field Definitions
1667 #define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
1670 * Bit 1 can be set to change the interrupt for the Function to operate in
1671 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
1672 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
1673 * mode, otherwise the operating mode is undefined.
1675 #define TOTEMPOLE 0x02
1678 * Bit 0 can be used to change the Int Pin for the Function. The value is
1679 * 0 by default for both Functions with Function 0 using INT A and Function
1680 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
1681 * INT A is used.
1683 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
1684 * value specified in the PCI Configuration Space.
1686 #define INTAB 0x01
1689 * Adv Library Status Definitions
1691 #define ADV_TRUE 1
1692 #define ADV_FALSE 0
1693 #define ADV_SUCCESS 1
1694 #define ADV_BUSY 0
1695 #define ADV_ERROR (-1)
1698 * ADV_DVC_VAR 'warn_code' values
1700 #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
1701 #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
1702 #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
1703 #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
1705 #define ADV_MAX_TID 15 /* max. target identifier */
1706 #define ADV_MAX_LUN 7 /* max. logical unit number */
1709 * Fixed locations of microcode operating variables.
1711 #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
1712 #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
1713 #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
1714 #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
1715 #define ASC_MC_VERSION_NUM 0x003A /* microcode number */
1716 #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
1717 #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
1718 #define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
1719 #define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
1720 #define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
1721 #define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
1722 #define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
1723 #define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
1724 #define ASC_MC_CHIP_TYPE 0x009A
1725 #define ASC_MC_INTRB_CODE 0x009B
1726 #define ASC_MC_WDTR_ABLE 0x009C
1727 #define ASC_MC_SDTR_ABLE 0x009E
1728 #define ASC_MC_TAGQNG_ABLE 0x00A0
1729 #define ASC_MC_DISC_ENABLE 0x00A2
1730 #define ASC_MC_IDLE_CMD_STATUS 0x00A4
1731 #define ASC_MC_IDLE_CMD 0x00A6
1732 #define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
1733 #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
1734 #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
1735 #define ASC_MC_DEFAULT_MEM_CFG 0x00B0
1736 #define ASC_MC_DEFAULT_SEL_MASK 0x00B2
1737 #define ASC_MC_SDTR_DONE 0x00B6
1738 #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
1739 #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
1740 #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
1741 #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
1742 #define ASC_MC_WDTR_DONE 0x0124
1743 #define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
1744 #define ASC_MC_ICQ 0x0160
1745 #define ASC_MC_IRQ 0x0164
1746 #define ASC_MC_PPR_ABLE 0x017A
1749 * BIOS LRAM variable absolute offsets.
1751 #define BIOS_CODESEG 0x54
1752 #define BIOS_CODELEN 0x56
1753 #define BIOS_SIGNATURE 0x58
1754 #define BIOS_VERSION 0x5A
1757 * Microcode Control Flags
1759 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
1760 * and handled by the microcode.
1762 #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
1763 #define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
1766 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
1768 #define HSHK_CFG_WIDE_XFR 0x8000
1769 #define HSHK_CFG_RATE 0x0F00
1770 #define HSHK_CFG_OFFSET 0x001F
1772 #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
1773 #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
1774 #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
1775 #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
1777 #define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
1778 #define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
1779 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
1780 #define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
1781 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
1783 #define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
1784 #define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
1785 #define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
1786 #define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
1787 #define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
1789 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
1790 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
1792 #define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
1793 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
1796 * All fields here are accessed by the board microcode and need to be
1797 * little-endian.
1799 typedef struct adv_carr_t {
1800 ADV_VADDR carr_va; /* Carrier Virtual Address */
1801 ADV_PADDR carr_pa; /* Carrier Physical Address */
1802 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
1804 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
1806 * next_vpa [3:1] Reserved Bits
1807 * next_vpa [0] Done Flag set in Response Queue.
1809 ADV_VADDR next_vpa;
1810 } ADV_CARR_T;
1813 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
1815 #define ASC_NEXT_VPA_MASK 0xFFFFFFF0
1817 #define ASC_RQ_DONE 0x00000001
1818 #define ASC_RQ_GOOD 0x00000002
1819 #define ASC_CQ_STOPPER 0x00000000
1821 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
1823 #define ADV_CARRIER_NUM_PAGE_CROSSING \
1824 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
1825 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1827 #define ADV_CARRIER_BUFSIZE \
1828 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
1831 * ASC_SCSI_REQ_Q 'a_flag' definitions
1833 * The Adv Library should limit use to the lower nibble (4 bits) of
1834 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
1836 #define ADV_POLL_REQUEST 0x01 /* poll for request completion */
1837 #define ADV_SCSIQ_DONE 0x02 /* request done */
1838 #define ADV_DONT_RETRY 0x08 /* don't do retry */
1840 #define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
1841 #define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
1842 #define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
1845 * Adapter temporary configuration structure
1847 * This structure can be discarded after initialization. Don't add
1848 * fields here needed after initialization.
1850 * Field naming convention:
1852 * *_enable indicates the field enables or disables a feature. The
1853 * value of the field is never reset.
1855 typedef struct adv_dvc_cfg {
1856 ushort disc_enable; /* enable disconnection */
1857 uchar chip_version; /* chip version */
1858 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
1859 ushort lib_version; /* Adv Library version number */
1860 ushort control_flag; /* Microcode Control Flag */
1861 ushort mcode_date; /* Microcode date */
1862 ushort mcode_version; /* Microcode version */
1863 ushort serial1; /* EEPROM serial number word 1 */
1864 ushort serial2; /* EEPROM serial number word 2 */
1865 ushort serial3; /* EEPROM serial number word 3 */
1866 } ADV_DVC_CFG;
1868 struct adv_dvc_var;
1869 struct adv_scsi_req_q;
1872 * Adapter operation variable structure.
1874 * One structure is required per host adapter.
1876 * Field naming convention:
1878 * *_able indicates both whether a feature should be enabled or disabled
1879 * and whether a device isi capable of the feature. At initialization
1880 * this field may be set, but later if a device is found to be incapable
1881 * of the feature, the field is cleared.
1883 typedef struct adv_dvc_var {
1884 AdvPortAddr iop_base; /* I/O port address */
1885 ushort err_code; /* fatal error code */
1886 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
1887 ushort wdtr_able; /* try WDTR for a device */
1888 ushort sdtr_able; /* try SDTR for a device */
1889 ushort ultra_able; /* try SDTR Ultra speed for a device */
1890 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
1891 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
1892 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
1893 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
1894 ushort tagqng_able; /* try tagged queuing with a device */
1895 ushort ppr_able; /* PPR message capable per TID bitmask. */
1896 uchar max_dvc_qng; /* maximum number of tagged commands per device */
1897 ushort start_motor; /* start motor command allowed */
1898 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
1899 uchar chip_no; /* should be assigned by caller */
1900 uchar max_host_qng; /* maximum number of Q'ed command allowed */
1901 ushort no_scam; /* scam_tolerant of EEPROM */
1902 struct asc_board *drv_ptr; /* driver pointer to private structure */
1903 uchar chip_scsi_id; /* chip SCSI target ID */
1904 uchar chip_type;
1905 uchar bist_err_code;
1906 ADV_CARR_T *carrier_buf;
1907 ADV_CARR_T *carr_freelist; /* Carrier free list. */
1908 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
1909 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
1910 ushort carr_pending_cnt; /* Count of pending carriers. */
1912 * Note: The following fields will not be used after initialization. The
1913 * driver may discard the buffer after initialization is done.
1915 ADV_DVC_CFG *cfg; /* temporary configuration structure */
1916 } ADV_DVC_VAR;
1918 #define NO_OF_SG_PER_BLOCK 15
1920 typedef struct asc_sg_block {
1921 uchar reserved1;
1922 uchar reserved2;
1923 uchar reserved3;
1924 uchar sg_cnt; /* Valid entries in block. */
1925 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
1926 struct {
1927 ADV_PADDR sg_addr; /* SG element address. */
1928 ADV_DCNT sg_count; /* SG element count. */
1929 } sg_list[NO_OF_SG_PER_BLOCK];
1930 } ADV_SG_BLOCK;
1933 * ADV_SCSI_REQ_Q - microcode request structure
1935 * All fields in this structure up to byte 60 are used by the microcode.
1936 * The microcode makes assumptions about the size and ordering of fields
1937 * in this structure. Do not change the structure definition here without
1938 * coordinating the change with the microcode.
1940 * All fields accessed by microcode must be maintained in little_endian
1941 * order.
1943 typedef struct adv_scsi_req_q {
1944 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
1945 uchar target_cmd;
1946 uchar target_id; /* Device target identifier. */
1947 uchar target_lun; /* Device target logical unit number. */
1948 ADV_PADDR data_addr; /* Data buffer physical address. */
1949 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
1950 ADV_PADDR sense_addr;
1951 ADV_PADDR carr_pa;
1952 uchar mflag;
1953 uchar sense_len;
1954 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
1955 uchar scsi_cntl;
1956 uchar done_status; /* Completion status. */
1957 uchar scsi_status; /* SCSI status byte. */
1958 uchar host_status; /* Ucode host status. */
1959 uchar sg_working_ix;
1960 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
1961 ADV_PADDR sg_real_addr; /* SG list physical address. */
1962 ADV_PADDR scsiq_rptr;
1963 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
1964 ADV_VADDR scsiq_ptr;
1965 ADV_VADDR carr_va;
1967 * End of microcode structure - 60 bytes. The rest of the structure
1968 * is used by the Adv Library and ignored by the microcode.
1970 ADV_VADDR srb_ptr;
1971 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
1972 char *vdata_addr; /* Data buffer virtual address. */
1973 uchar a_flag;
1974 uchar pad[2]; /* Pad out to a word boundary. */
1975 } ADV_SCSI_REQ_Q;
1978 * Microcode idle loop commands
1980 #define IDLE_CMD_COMPLETED 0
1981 #define IDLE_CMD_STOP_CHIP 0x0001
1982 #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
1983 #define IDLE_CMD_SEND_INT 0x0004
1984 #define IDLE_CMD_ABORT 0x0008
1985 #define IDLE_CMD_DEVICE_RESET 0x0010
1986 #define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
1987 #define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
1988 #define IDLE_CMD_SCSIREQ 0x0080
1990 #define IDLE_CMD_STATUS_SUCCESS 0x0001
1991 #define IDLE_CMD_STATUS_FAILURE 0x0002
1994 * AdvSendIdleCmd() flag definitions.
1996 #define ADV_NOWAIT 0x01
1999 * Wait loop time out values.
2001 #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
2002 #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
2003 #define SCSI_MAX_RETRY 10 /* retry count */
2005 #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
2006 #define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
2007 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
2008 #define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
2010 #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
2012 /* Read byte from a register. */
2013 #define AdvReadByteRegister(iop_base, reg_off) \
2014 (ADV_MEM_READB((iop_base) + (reg_off)))
2016 /* Write byte to a register. */
2017 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
2018 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
2020 /* Read word (2 bytes) from a register. */
2021 #define AdvReadWordRegister(iop_base, reg_off) \
2022 (ADV_MEM_READW((iop_base) + (reg_off)))
2024 /* Write word (2 bytes) to a register. */
2025 #define AdvWriteWordRegister(iop_base, reg_off, word) \
2026 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
2028 /* Write dword (4 bytes) to a register. */
2029 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
2030 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
2032 /* Read byte from LRAM. */
2033 #define AdvReadByteLram(iop_base, addr, byte) \
2034 do { \
2035 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2036 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
2037 } while (0)
2039 /* Write byte to LRAM. */
2040 #define AdvWriteByteLram(iop_base, addr, byte) \
2041 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2042 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
2044 /* Read word (2 bytes) from LRAM. */
2045 #define AdvReadWordLram(iop_base, addr, word) \
2046 do { \
2047 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2048 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
2049 } while (0)
2051 /* Write word (2 bytes) to LRAM. */
2052 #define AdvWriteWordLram(iop_base, addr, word) \
2053 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2054 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2056 /* Write little-endian double word (4 bytes) to LRAM */
2057 /* Because of unspecified C language ordering don't use auto-increment. */
2058 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
2059 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2060 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2061 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
2062 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
2063 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2064 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
2066 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
2067 #define AdvReadWordAutoIncLram(iop_base) \
2068 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
2070 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
2071 #define AdvWriteWordAutoIncLram(iop_base, word) \
2072 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2075 * Define macro to check for Condor signature.
2077 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
2078 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
2080 #define AdvFindSignature(iop_base) \
2081 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
2082 ADV_CHIP_ID_BYTE) && \
2083 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
2084 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
2087 * Define macro to Return the version number of the chip at 'iop_base'.
2089 * The second parameter 'bus_type' is currently unused.
2091 #define AdvGetChipVersion(iop_base, bus_type) \
2092 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
2095 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
2096 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
2098 * If the request has not yet been sent to the device it will simply be
2099 * aborted from RISC memory. If the request is disconnected it will be
2100 * aborted on reselection by sending an Abort Message to the target ID.
2102 * Return value:
2103 * ADV_TRUE(1) - Queue was successfully aborted.
2104 * ADV_FALSE(0) - Queue was not found on the active queue list.
2106 #define AdvAbortQueue(asc_dvc, scsiq) \
2107 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
2108 (ADV_DCNT) (scsiq))
2111 * Send a Bus Device Reset Message to the specified target ID.
2113 * All outstanding commands will be purged if sending the
2114 * Bus Device Reset Message is successful.
2116 * Return Value:
2117 * ADV_TRUE(1) - All requests on the target are purged.
2118 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
2119 * are not purged.
2121 #define AdvResetDevice(asc_dvc, target_id) \
2122 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
2123 (ADV_DCNT) (target_id))
2126 * SCSI Wide Type definition.
2128 #define ADV_SCSI_BIT_ID_TYPE ushort
2131 * AdvInitScsiTarget() 'cntl_flag' options.
2133 #define ADV_SCAN_LUN 0x01
2134 #define ADV_CAPINFO_NOLUN 0x02
2137 * Convert target id to target id bit mask.
2139 #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
2142 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
2145 #define QD_NO_STATUS 0x00 /* Request not completed yet. */
2146 #define QD_NO_ERROR 0x01
2147 #define QD_ABORTED_BY_HOST 0x02
2148 #define QD_WITH_ERROR 0x04
2150 #define QHSTA_NO_ERROR 0x00
2151 #define QHSTA_M_SEL_TIMEOUT 0x11
2152 #define QHSTA_M_DATA_OVER_RUN 0x12
2153 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
2154 #define QHSTA_M_QUEUE_ABORTED 0x15
2155 #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
2156 #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
2157 #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
2158 #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
2159 #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
2160 #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
2161 #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
2162 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
2163 #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
2164 #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
2165 #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
2166 #define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
2167 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
2168 #define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
2169 #define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
2170 #define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
2171 #define QHSTA_M_WTM_TIMEOUT 0x41
2172 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
2173 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
2174 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
2175 #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
2176 #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
2177 #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
2180 * DvcGetPhyAddr() flag arguments
2182 #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
2183 #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
2184 #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
2185 #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
2186 #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
2187 #define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
2189 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
2190 #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
2191 #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
2192 #define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
2195 * Total contiguous memory needed for driver SG blocks.
2197 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
2198 * number of scatter-gather elements the driver supports in a
2199 * single request.
2202 #define ADV_SG_LIST_MAX_BYTE_SIZE \
2203 (sizeof(ADV_SG_BLOCK) * \
2204 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
2206 /* Reference Scsi_Host hostdata */
2207 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
2209 /* asc_board_t flags */
2210 #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
2212 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
2214 #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
2216 #define ASC_INFO_SIZE 128 /* advansys_info() line size */
2218 #ifdef CONFIG_PROC_FS
2219 /* /proc/scsi/advansys/[0...] related definitions */
2220 #define ASC_PRTBUF_SIZE 2048
2221 #define ASC_PRTLINE_SIZE 160
2223 #define ASC_PRT_NEXT() \
2224 if (cp) { \
2225 totlen += len; \
2226 leftlen -= len; \
2227 if (leftlen == 0) { \
2228 return totlen; \
2230 cp += len; \
2232 #endif /* CONFIG_PROC_FS */
2234 /* Asc Library return codes */
2235 #define ASC_TRUE 1
2236 #define ASC_FALSE 0
2237 #define ASC_NOERROR 1
2238 #define ASC_BUSY 0
2239 #define ASC_ERROR (-1)
2241 /* struct scsi_cmnd function return codes */
2242 #define STATUS_BYTE(byte) (byte)
2243 #define MSG_BYTE(byte) ((byte) << 8)
2244 #define HOST_BYTE(byte) ((byte) << 16)
2245 #define DRIVER_BYTE(byte) ((byte) << 24)
2247 #ifndef ADVANSYS_STATS
2248 #define ASC_STATS(shost, counter)
2249 #define ASC_STATS_ADD(shost, counter, count)
2250 #else /* ADVANSYS_STATS */
2251 #define ASC_STATS(shost, counter) \
2252 (ASC_BOARDP(shost)->asc_stats.counter++)
2254 #define ASC_STATS_ADD(shost, counter, count) \
2255 (ASC_BOARDP(shost)->asc_stats.counter += (count))
2256 #endif /* ADVANSYS_STATS */
2258 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
2260 /* If the result wraps when calculating tenths, return 0. */
2261 #define ASC_TENTHS(num, den) \
2262 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
2263 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
2266 * Display a message to the console.
2268 #define ASC_PRINT(s) \
2270 printk("advansys: "); \
2271 printk(s); \
2274 #define ASC_PRINT1(s, a1) \
2276 printk("advansys: "); \
2277 printk((s), (a1)); \
2280 #define ASC_PRINT2(s, a1, a2) \
2282 printk("advansys: "); \
2283 printk((s), (a1), (a2)); \
2286 #define ASC_PRINT3(s, a1, a2, a3) \
2288 printk("advansys: "); \
2289 printk((s), (a1), (a2), (a3)); \
2292 #define ASC_PRINT4(s, a1, a2, a3, a4) \
2294 printk("advansys: "); \
2295 printk((s), (a1), (a2), (a3), (a4)); \
2298 #ifndef ADVANSYS_DEBUG
2300 #define ASC_DBG(lvl, s)
2301 #define ASC_DBG1(lvl, s, a1)
2302 #define ASC_DBG2(lvl, s, a1, a2)
2303 #define ASC_DBG3(lvl, s, a1, a2, a3)
2304 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
2305 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2306 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
2307 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
2308 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2309 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
2310 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2311 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
2312 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
2313 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
2314 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2316 #else /* ADVANSYS_DEBUG */
2319 * Debugging Message Levels:
2320 * 0: Errors Only
2321 * 1: High-Level Tracing
2322 * 2-N: Verbose Tracing
2325 #define ASC_DBG(lvl, s) \
2327 if (asc_dbglvl >= (lvl)) { \
2328 printk(s); \
2332 #define ASC_DBG1(lvl, s, a1) \
2334 if (asc_dbglvl >= (lvl)) { \
2335 printk((s), (a1)); \
2339 #define ASC_DBG2(lvl, s, a1, a2) \
2341 if (asc_dbglvl >= (lvl)) { \
2342 printk((s), (a1), (a2)); \
2346 #define ASC_DBG3(lvl, s, a1, a2, a3) \
2348 if (asc_dbglvl >= (lvl)) { \
2349 printk((s), (a1), (a2), (a3)); \
2353 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
2355 if (asc_dbglvl >= (lvl)) { \
2356 printk((s), (a1), (a2), (a3), (a4)); \
2360 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2362 if (asc_dbglvl >= (lvl)) { \
2363 asc_prt_scsi_host(s); \
2367 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
2369 if (asc_dbglvl >= (lvl)) { \
2370 asc_prt_scsi_cmnd(s); \
2374 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
2376 if (asc_dbglvl >= (lvl)) { \
2377 asc_prt_asc_scsi_q(scsiqp); \
2381 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
2383 if (asc_dbglvl >= (lvl)) { \
2384 asc_prt_asc_qdone_info(qdone); \
2388 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
2390 if (asc_dbglvl >= (lvl)) { \
2391 asc_prt_adv_scsi_req_q(scsiqp); \
2395 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2397 if (asc_dbglvl >= (lvl)) { \
2398 asc_prt_hex((name), (start), (length)); \
2402 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2403 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2405 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2406 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2408 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2409 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2410 #endif /* ADVANSYS_DEBUG */
2412 #ifdef ADVANSYS_STATS
2414 /* Per board statistics structure */
2415 struct asc_stats {
2416 /* Driver Entrypoint Statistics */
2417 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
2418 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
2419 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
2420 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
2421 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
2422 ADV_DCNT done; /* # calls to request's scsi_done function */
2423 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
2424 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
2425 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
2426 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
2427 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
2428 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
2429 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
2430 ADV_DCNT exe_unknown; /* # unknown returns. */
2431 /* Data Transfer Statistics */
2432 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
2433 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
2434 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
2435 ADV_DCNT sg_elem; /* # scatter-gather elements */
2436 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
2438 #endif /* ADVANSYS_STATS */
2441 * Adv Library Request Structures
2443 * The following two structures are used to process Wide Board requests.
2445 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
2446 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
2447 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
2448 * Mid-Level SCSI request structure.
2450 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
2451 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
2452 * up to 255 scatter-gather elements may be used per request or
2453 * ADV_SCSI_REQ_Q.
2455 * Both structures must be 32 byte aligned.
2457 typedef struct adv_sgblk {
2458 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
2459 uchar align[32]; /* Sgblock structure padding. */
2460 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
2461 } adv_sgblk_t;
2463 typedef struct adv_req {
2464 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
2465 uchar align[32]; /* Request structure padding. */
2466 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
2467 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
2468 struct adv_req *next_reqp; /* Next Request Structure. */
2469 } adv_req_t;
2472 * Structure allocated for each board.
2474 * This structure is allocated by scsi_host_alloc() at the end
2475 * of the 'Scsi_Host' structure starting at the 'hostdata'
2476 * field. It is guaranteed to be allocated from DMA-able memory.
2478 typedef struct asc_board {
2479 struct device *dev;
2480 int id; /* Board Id */
2481 uint flags; /* Board flags */
2482 unsigned int irq;
2483 union {
2484 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
2485 ADV_DVC_VAR adv_dvc_var; /* Wide board */
2486 } dvc_var;
2487 union {
2488 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
2489 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
2490 } dvc_cfg;
2491 ushort asc_n_io_port; /* Number I/O ports. */
2492 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
2493 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
2494 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
2495 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
2496 union {
2497 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
2498 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
2499 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
2500 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
2501 } eep_config;
2502 ulong last_reset; /* Saved last reset time */
2503 spinlock_t lock; /* Board spinlock */
2504 /* /proc/scsi/advansys/[0...] */
2505 char *prtbuf; /* /proc print buffer */
2506 #ifdef ADVANSYS_STATS
2507 struct asc_stats asc_stats; /* Board statistics */
2508 #endif /* ADVANSYS_STATS */
2510 * The following fields are used only for Narrow Boards.
2512 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
2514 * The following fields are used only for Wide Boards.
2516 void __iomem *ioremap_addr; /* I/O Memory remap address. */
2517 ushort ioport; /* I/O Port address. */
2518 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
2519 adv_req_t *orig_reqp; /* adv_req_t memory block. */
2520 adv_req_t *adv_reqp; /* Request structures. */
2521 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
2522 ushort bios_signature; /* BIOS Signature. */
2523 ushort bios_version; /* BIOS Version. */
2524 ushort bios_codeseg; /* BIOS Code Segment. */
2525 ushort bios_codelen; /* BIOS Code Segment Length. */
2526 } asc_board_t;
2528 #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
2529 dvc_var.adv_dvc_var)
2530 #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
2532 /* Number of boards detected in system. */
2533 static int asc_board_count;
2535 /* Overrun buffer used by all narrow boards. */
2536 static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
2538 #ifdef ADVANSYS_DEBUG
2539 static int asc_dbglvl = 3;
2542 * asc_prt_scsi_host()
2544 static void asc_prt_scsi_host(struct Scsi_Host *s)
2546 asc_board_t *boardp;
2548 boardp = ASC_BOARDP(s);
2550 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
2551 printk(" host_busy %u, host_no %d, last_reset %d,\n",
2552 s->host_busy, s->host_no, (unsigned)s->last_reset);
2554 printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
2555 (ulong)s->base, (ulong)s->io_port, boardp->irq);
2557 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
2558 s->dma_channel, s->this_id, s->can_queue);
2560 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
2561 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
2563 if (ASC_NARROW_BOARD(boardp)) {
2564 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
2565 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
2566 } else {
2567 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
2568 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
2573 * asc_prt_scsi_cmnd()
2575 static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
2577 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
2579 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
2580 (ulong)s->device->host, (ulong)s->device, s->device->id,
2581 s->device->lun, s->device->channel);
2583 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
2585 printk("sc_data_direction %u, resid %d\n",
2586 s->sc_data_direction, s->resid);
2588 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
2590 printk(" serial_number 0x%x, retries %d, allowed %d\n",
2591 (unsigned)s->serial_number, s->retries, s->allowed);
2593 printk(" timeout_per_command %d\n", s->timeout_per_command);
2595 printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n",
2596 s->scsi_done, s->done, s->host_scribble, s->result);
2598 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
2602 * asc_prt_asc_dvc_var()
2604 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
2606 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
2608 printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
2609 "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
2611 printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
2612 (unsigned)h->init_sdtr);
2614 printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
2615 "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
2616 (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
2617 (unsigned)h->chip_no);
2619 printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
2620 "%u,\n", (unsigned)h->queue_full_or_busy,
2621 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2623 printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
2624 "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
2625 (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
2626 (unsigned)h->in_critical_cnt);
2628 printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
2629 "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
2630 (unsigned)h->init_state, (unsigned)h->no_scam,
2631 (unsigned)h->pci_fix_asyn_xfer);
2633 printk(" cfg 0x%lx\n", (ulong)h->cfg);
2637 * asc_prt_asc_dvc_cfg()
2639 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
2641 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
2643 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
2644 h->can_tagged_qng, h->cmd_qng_enabled);
2645 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
2646 h->disc_enable, h->sdtr_enable);
2648 printk
2649 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
2650 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
2651 h->chip_version);
2653 printk
2654 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
2655 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
2656 h->mcode_date);
2658 printk(" mcode_version %d, overrun_buf 0x%lx\n",
2659 h->mcode_version, (ulong)h->overrun_buf);
2663 * asc_prt_asc_scsi_q()
2665 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
2667 ASC_SG_HEAD *sgp;
2668 int i;
2670 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
2672 printk
2673 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
2674 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
2675 q->q2.tag_code);
2677 printk
2678 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2679 (ulong)le32_to_cpu(q->q1.data_addr),
2680 (ulong)le32_to_cpu(q->q1.data_cnt),
2681 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
2683 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
2684 (ulong)q->cdbptr, q->q2.cdb_len,
2685 (ulong)q->sg_head, q->q1.sg_queue_cnt);
2687 if (q->sg_head) {
2688 sgp = q->sg_head;
2689 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
2690 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
2691 sgp->queue_cnt);
2692 for (i = 0; i < sgp->entry_cnt; i++) {
2693 printk(" [%u]: addr 0x%lx, bytes %lu\n",
2694 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
2695 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
2702 * asc_prt_asc_qdone_info()
2704 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
2706 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
2707 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
2708 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
2709 q->d2.tag_code);
2710 printk
2711 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
2712 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
2716 * asc_prt_adv_dvc_var()
2718 * Display an ADV_DVC_VAR structure.
2720 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
2722 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
2724 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
2725 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
2727 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
2728 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
2729 (unsigned)h->wdtr_able);
2731 printk(" start_motor 0x%x, scsi_reset_wait 0x%x\n",
2732 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2734 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
2735 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
2736 (ulong)h->carr_freelist);
2738 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
2739 (ulong)h->icq_sp, (ulong)h->irq_sp);
2741 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
2742 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
2744 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
2745 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
2749 * asc_prt_adv_dvc_cfg()
2751 * Display an ADV_DVC_CFG structure.
2753 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
2755 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
2757 printk(" disc_enable 0x%x, termination 0x%x\n",
2758 h->disc_enable, h->termination);
2760 printk(" chip_version 0x%x, mcode_date 0x%x\n",
2761 h->chip_version, h->mcode_date);
2763 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
2764 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
2766 printk(" control_flag 0x%x\n", h->control_flag);
2770 * asc_prt_adv_scsi_req_q()
2772 * Display an ADV_SCSI_REQ_Q structure.
2774 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
2776 int sg_blk_cnt;
2777 struct asc_sg_block *sg_ptr;
2779 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
2781 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
2782 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
2784 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
2785 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
2787 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2788 (ulong)le32_to_cpu(q->data_cnt),
2789 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
2791 printk
2792 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
2793 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
2795 printk(" sg_working_ix 0x%x, target_cmd %u\n",
2796 q->sg_working_ix, q->target_cmd);
2798 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
2799 (ulong)le32_to_cpu(q->scsiq_rptr),
2800 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
2802 /* Display the request's ADV_SG_BLOCK structures. */
2803 if (q->sg_list_ptr != NULL) {
2804 sg_blk_cnt = 0;
2805 while (1) {
2807 * 'sg_ptr' is a physical address. Convert it to a virtual
2808 * address by indexing 'sg_blk_cnt' into the virtual address
2809 * array 'sg_list_ptr'.
2811 * XXX - Assumes all SG physical blocks are virtually contiguous.
2813 sg_ptr =
2814 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
2815 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
2816 if (sg_ptr->sg_ptr == 0) {
2817 break;
2819 sg_blk_cnt++;
2825 * asc_prt_adv_sgblock()
2827 * Display an ADV_SG_BLOCK structure.
2829 static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
2831 int i;
2833 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
2834 (ulong)b, sgblockno);
2835 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
2836 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
2837 BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK);
2838 if (b->sg_ptr != 0)
2839 BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK);
2840 for (i = 0; i < b->sg_cnt; i++) {
2841 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
2842 i, (ulong)b->sg_list[i].sg_addr,
2843 (ulong)b->sg_list[i].sg_count);
2848 * asc_prt_hex()
2850 * Print hexadecimal output in 4 byte groupings 32 bytes
2851 * or 8 double-words per line.
2853 static void asc_prt_hex(char *f, uchar *s, int l)
2855 int i;
2856 int j;
2857 int k;
2858 int m;
2860 printk("%s: (%d bytes)\n", f, l);
2862 for (i = 0; i < l; i += 32) {
2864 /* Display a maximum of 8 double-words per line. */
2865 if ((k = (l - i) / 4) >= 8) {
2866 k = 8;
2867 m = 0;
2868 } else {
2869 m = (l - i) % 4;
2872 for (j = 0; j < k; j++) {
2873 printk(" %2.2X%2.2X%2.2X%2.2X",
2874 (unsigned)s[i + (j * 4)],
2875 (unsigned)s[i + (j * 4) + 1],
2876 (unsigned)s[i + (j * 4) + 2],
2877 (unsigned)s[i + (j * 4) + 3]);
2880 switch (m) {
2881 case 0:
2882 default:
2883 break;
2884 case 1:
2885 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
2886 break;
2887 case 2:
2888 printk(" %2.2X%2.2X",
2889 (unsigned)s[i + (j * 4)],
2890 (unsigned)s[i + (j * 4) + 1]);
2891 break;
2892 case 3:
2893 printk(" %2.2X%2.2X%2.2X",
2894 (unsigned)s[i + (j * 4) + 1],
2895 (unsigned)s[i + (j * 4) + 2],
2896 (unsigned)s[i + (j * 4) + 3]);
2897 break;
2900 printk("\n");
2903 #endif /* ADVANSYS_DEBUG */
2906 * advansys_info()
2908 * Return suitable for printing on the console with the argument
2909 * adapter's configuration information.
2911 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
2912 * otherwise the static 'info' array will be overrun.
2914 static const char *advansys_info(struct Scsi_Host *shost)
2916 static char info[ASC_INFO_SIZE];
2917 asc_board_t *boardp;
2918 ASC_DVC_VAR *asc_dvc_varp;
2919 ADV_DVC_VAR *adv_dvc_varp;
2920 char *busname;
2921 char *widename = NULL;
2923 boardp = ASC_BOARDP(shost);
2924 if (ASC_NARROW_BOARD(boardp)) {
2925 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
2926 ASC_DBG(1, "advansys_info: begin\n");
2927 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
2928 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
2929 ASC_IS_ISAPNP) {
2930 busname = "ISA PnP";
2931 } else {
2932 busname = "ISA";
2934 sprintf(info,
2935 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
2936 ASC_VERSION, busname,
2937 (ulong)shost->io_port,
2938 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2939 boardp->irq, shost->dma_channel);
2940 } else {
2941 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
2942 busname = "VL";
2943 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
2944 busname = "EISA";
2945 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
2946 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
2947 == ASC_IS_PCI_ULTRA) {
2948 busname = "PCI Ultra";
2949 } else {
2950 busname = "PCI";
2952 } else {
2953 busname = "?";
2954 ASC_PRINT2("advansys_info: board %d: unknown "
2955 "bus type %d\n", boardp->id,
2956 asc_dvc_varp->bus_type);
2958 sprintf(info,
2959 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
2960 ASC_VERSION, busname, (ulong)shost->io_port,
2961 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2962 boardp->irq);
2964 } else {
2966 * Wide Adapter Information
2968 * Memory-mapped I/O is used instead of I/O space to access
2969 * the adapter, but display the I/O Port range. The Memory
2970 * I/O address is displayed through the driver /proc file.
2972 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
2973 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
2974 widename = "Ultra-Wide";
2975 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
2976 widename = "Ultra2-Wide";
2977 } else {
2978 widename = "Ultra3-Wide";
2980 sprintf(info,
2981 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
2982 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
2983 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, boardp->irq);
2985 BUG_ON(strlen(info) >= ASC_INFO_SIZE);
2986 ASC_DBG(1, "advansys_info: end\n");
2987 return info;
2990 #ifdef CONFIG_PROC_FS
2992 * asc_prt_line()
2994 * If 'cp' is NULL print to the console, otherwise print to a buffer.
2996 * Return 0 if printing to the console, otherwise return the number of
2997 * bytes written to the buffer.
2999 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
3000 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
3002 static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
3004 va_list args;
3005 int ret;
3006 char s[ASC_PRTLINE_SIZE];
3008 va_start(args, fmt);
3009 ret = vsprintf(s, fmt, args);
3010 BUG_ON(ret >= ASC_PRTLINE_SIZE);
3011 if (buf == NULL) {
3012 (void)printk(s);
3013 ret = 0;
3014 } else {
3015 ret = min(buflen, ret);
3016 memcpy(buf, s, ret);
3018 va_end(args);
3019 return ret;
3023 * asc_prt_board_devices()
3025 * Print driver information for devices attached to the board.
3027 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3028 * cf. asc_prt_line().
3030 * Return the number of characters copied into 'cp'. No more than
3031 * 'cplen' characters will be copied to 'cp'.
3033 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
3035 asc_board_t *boardp;
3036 int leftlen;
3037 int totlen;
3038 int len;
3039 int chip_scsi_id;
3040 int i;
3042 boardp = ASC_BOARDP(shost);
3043 leftlen = cplen;
3044 totlen = len = 0;
3046 len = asc_prt_line(cp, leftlen,
3047 "\nDevice Information for AdvanSys SCSI Host %d:\n",
3048 shost->host_no);
3049 ASC_PRT_NEXT();
3051 if (ASC_NARROW_BOARD(boardp)) {
3052 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
3053 } else {
3054 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
3057 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
3058 ASC_PRT_NEXT();
3059 for (i = 0; i <= ADV_MAX_TID; i++) {
3060 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
3061 len = asc_prt_line(cp, leftlen, " %X,", i);
3062 ASC_PRT_NEXT();
3065 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
3066 ASC_PRT_NEXT();
3068 return totlen;
3072 * Display Wide Board BIOS Information.
3074 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
3076 asc_board_t *boardp;
3077 int leftlen;
3078 int totlen;
3079 int len;
3080 ushort major, minor, letter;
3082 boardp = ASC_BOARDP(shost);
3083 leftlen = cplen;
3084 totlen = len = 0;
3086 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
3087 ASC_PRT_NEXT();
3090 * If the BIOS saved a valid signature, then fill in
3091 * the BIOS code segment base address.
3093 if (boardp->bios_signature != 0x55AA) {
3094 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
3095 ASC_PRT_NEXT();
3096 len = asc_prt_line(cp, leftlen,
3097 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
3098 ASC_PRT_NEXT();
3099 len = asc_prt_line(cp, leftlen,
3100 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
3101 ASC_PRT_NEXT();
3102 } else {
3103 major = (boardp->bios_version >> 12) & 0xF;
3104 minor = (boardp->bios_version >> 8) & 0xF;
3105 letter = (boardp->bios_version & 0xFF);
3107 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
3108 major, minor,
3109 letter >= 26 ? '?' : letter + 'A');
3110 ASC_PRT_NEXT();
3113 * Current available ROM BIOS release is 3.1I for UW
3114 * and 3.2I for U2W. This code doesn't differentiate
3115 * UW and U2W boards.
3117 if (major < 3 || (major <= 3 && minor < 1) ||
3118 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
3119 len = asc_prt_line(cp, leftlen,
3120 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
3121 ASC_PRT_NEXT();
3122 len = asc_prt_line(cp, leftlen,
3123 "ftp://ftp.connectcom.net/pub\n");
3124 ASC_PRT_NEXT();
3128 return totlen;
3132 * Add serial number to information bar if signature AAh
3133 * is found in at bit 15-9 (7 bits) of word 1.
3135 * Serial Number consists fo 12 alpha-numeric digits.
3137 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
3138 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
3139 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
3140 * 5 - Product revision (A-J) Word0: " "
3142 * Signature Word1: 15-9 (7 bits)
3143 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
3144 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
3146 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
3148 * Note 1: Only production cards will have a serial number.
3150 * Note 2: Signature is most significant 7 bits (0xFE).
3152 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
3154 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
3156 ushort w, num;
3158 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
3159 return ASC_FALSE;
3160 } else {
3162 * First word - 6 digits.
3164 w = serialnum[0];
3166 /* Product type - 1st digit. */
3167 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
3168 /* Product type is P=Prototype */
3169 *cp += 0x8;
3171 cp++;
3173 /* Manufacturing location - 2nd digit. */
3174 *cp++ = 'A' + ((w & 0x1C00) >> 10);
3176 /* Product ID - 3rd, 4th digits. */
3177 num = w & 0x3FF;
3178 *cp++ = '0' + (num / 100);
3179 num %= 100;
3180 *cp++ = '0' + (num / 10);
3182 /* Product revision - 5th digit. */
3183 *cp++ = 'A' + (num % 10);
3186 * Second word
3188 w = serialnum[1];
3191 * Year - 6th digit.
3193 * If bit 15 of third word is set, then the
3194 * last digit of the year is greater than 7.
3196 if (serialnum[2] & 0x8000) {
3197 *cp++ = '8' + ((w & 0x1C0) >> 6);
3198 } else {
3199 *cp++ = '0' + ((w & 0x1C0) >> 6);
3202 /* Week of year - 7th, 8th digits. */
3203 num = w & 0x003F;
3204 *cp++ = '0' + num / 10;
3205 num %= 10;
3206 *cp++ = '0' + num;
3209 * Third word
3211 w = serialnum[2] & 0x7FFF;
3213 /* Serial number - 9th digit. */
3214 *cp++ = 'A' + (w / 1000);
3216 /* 10th, 11th, 12th digits. */
3217 num = w % 1000;
3218 *cp++ = '0' + num / 100;
3219 num %= 100;
3220 *cp++ = '0' + num / 10;
3221 num %= 10;
3222 *cp++ = '0' + num;
3224 *cp = '\0'; /* Null Terminate the string. */
3225 return ASC_TRUE;
3230 * asc_prt_asc_board_eeprom()
3232 * Print board EEPROM configuration.
3234 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3235 * cf. asc_prt_line().
3237 * Return the number of characters copied into 'cp'. No more than
3238 * 'cplen' characters will be copied to 'cp'.
3240 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
3242 asc_board_t *boardp;
3243 ASC_DVC_VAR *asc_dvc_varp;
3244 int leftlen;
3245 int totlen;
3246 int len;
3247 ASCEEP_CONFIG *ep;
3248 int i;
3249 #ifdef CONFIG_ISA
3250 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
3251 #endif /* CONFIG_ISA */
3252 uchar serialstr[13];
3254 boardp = ASC_BOARDP(shost);
3255 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3256 ep = &boardp->eep_config.asc_eep;
3258 leftlen = cplen;
3259 totlen = len = 0;
3261 len = asc_prt_line(cp, leftlen,
3262 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3263 shost->host_no);
3264 ASC_PRT_NEXT();
3266 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
3267 == ASC_TRUE) {
3268 len =
3269 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
3270 serialstr);
3271 ASC_PRT_NEXT();
3272 } else {
3273 if (ep->adapter_info[5] == 0xBB) {
3274 len = asc_prt_line(cp, leftlen,
3275 " Default Settings Used for EEPROM-less Adapter.\n");
3276 ASC_PRT_NEXT();
3277 } else {
3278 len = asc_prt_line(cp, leftlen,
3279 " Serial Number Signature Not Present.\n");
3280 ASC_PRT_NEXT();
3284 len = asc_prt_line(cp, leftlen,
3285 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3286 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
3287 ep->max_tag_qng);
3288 ASC_PRT_NEXT();
3290 len = asc_prt_line(cp, leftlen,
3291 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
3292 ASC_PRT_NEXT();
3294 len = asc_prt_line(cp, leftlen, " Target ID: ");
3295 ASC_PRT_NEXT();
3296 for (i = 0; i <= ASC_MAX_TID; i++) {
3297 len = asc_prt_line(cp, leftlen, " %d", i);
3298 ASC_PRT_NEXT();
3300 len = asc_prt_line(cp, leftlen, "\n");
3301 ASC_PRT_NEXT();
3303 len = asc_prt_line(cp, leftlen, " Disconnects: ");
3304 ASC_PRT_NEXT();
3305 for (i = 0; i <= ASC_MAX_TID; i++) {
3306 len = asc_prt_line(cp, leftlen, " %c",
3307 (ep->
3308 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3309 'N');
3310 ASC_PRT_NEXT();
3312 len = asc_prt_line(cp, leftlen, "\n");
3313 ASC_PRT_NEXT();
3315 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
3316 ASC_PRT_NEXT();
3317 for (i = 0; i <= ASC_MAX_TID; i++) {
3318 len = asc_prt_line(cp, leftlen, " %c",
3319 (ep->
3320 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3321 'N');
3322 ASC_PRT_NEXT();
3324 len = asc_prt_line(cp, leftlen, "\n");
3325 ASC_PRT_NEXT();
3327 len = asc_prt_line(cp, leftlen, " Start Motor: ");
3328 ASC_PRT_NEXT();
3329 for (i = 0; i <= ASC_MAX_TID; i++) {
3330 len = asc_prt_line(cp, leftlen, " %c",
3331 (ep->
3332 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3333 'N');
3334 ASC_PRT_NEXT();
3336 len = asc_prt_line(cp, leftlen, "\n");
3337 ASC_PRT_NEXT();
3339 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3340 ASC_PRT_NEXT();
3341 for (i = 0; i <= ASC_MAX_TID; i++) {
3342 len = asc_prt_line(cp, leftlen, " %c",
3343 (ep->
3344 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3345 'N');
3346 ASC_PRT_NEXT();
3348 len = asc_prt_line(cp, leftlen, "\n");
3349 ASC_PRT_NEXT();
3351 #ifdef CONFIG_ISA
3352 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3353 len = asc_prt_line(cp, leftlen,
3354 " Host ISA DMA speed: %d MB/S\n",
3355 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
3356 ASC_PRT_NEXT();
3358 #endif /* CONFIG_ISA */
3360 return totlen;
3364 * asc_prt_adv_board_eeprom()
3366 * Print board EEPROM configuration.
3368 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3369 * cf. asc_prt_line().
3371 * Return the number of characters copied into 'cp'. No more than
3372 * 'cplen' characters will be copied to 'cp'.
3374 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
3376 asc_board_t *boardp;
3377 ADV_DVC_VAR *adv_dvc_varp;
3378 int leftlen;
3379 int totlen;
3380 int len;
3381 int i;
3382 char *termstr;
3383 uchar serialstr[13];
3384 ADVEEP_3550_CONFIG *ep_3550 = NULL;
3385 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
3386 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
3387 ushort word;
3388 ushort *wordp;
3389 ushort sdtr_speed = 0;
3391 boardp = ASC_BOARDP(shost);
3392 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3393 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3394 ep_3550 = &boardp->eep_config.adv_3550_eep;
3395 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3396 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
3397 } else {
3398 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
3401 leftlen = cplen;
3402 totlen = len = 0;
3404 len = asc_prt_line(cp, leftlen,
3405 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3406 shost->host_no);
3407 ASC_PRT_NEXT();
3409 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3410 wordp = &ep_3550->serial_number_word1;
3411 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3412 wordp = &ep_38C0800->serial_number_word1;
3413 } else {
3414 wordp = &ep_38C1600->serial_number_word1;
3417 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
3418 len =
3419 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
3420 serialstr);
3421 ASC_PRT_NEXT();
3422 } else {
3423 len = asc_prt_line(cp, leftlen,
3424 " Serial Number Signature Not Present.\n");
3425 ASC_PRT_NEXT();
3428 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3429 len = asc_prt_line(cp, leftlen,
3430 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3431 ep_3550->adapter_scsi_id,
3432 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
3433 ASC_PRT_NEXT();
3434 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3435 len = asc_prt_line(cp, leftlen,
3436 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3437 ep_38C0800->adapter_scsi_id,
3438 ep_38C0800->max_host_qng,
3439 ep_38C0800->max_dvc_qng);
3440 ASC_PRT_NEXT();
3441 } else {
3442 len = asc_prt_line(cp, leftlen,
3443 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3444 ep_38C1600->adapter_scsi_id,
3445 ep_38C1600->max_host_qng,
3446 ep_38C1600->max_dvc_qng);
3447 ASC_PRT_NEXT();
3449 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3450 word = ep_3550->termination;
3451 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3452 word = ep_38C0800->termination_lvd;
3453 } else {
3454 word = ep_38C1600->termination_lvd;
3456 switch (word) {
3457 case 1:
3458 termstr = "Low Off/High Off";
3459 break;
3460 case 2:
3461 termstr = "Low Off/High On";
3462 break;
3463 case 3:
3464 termstr = "Low On/High On";
3465 break;
3466 default:
3467 case 0:
3468 termstr = "Automatic";
3469 break;
3472 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3473 len = asc_prt_line(cp, leftlen,
3474 " termination: %u (%s), bios_ctrl: 0x%x\n",
3475 ep_3550->termination, termstr,
3476 ep_3550->bios_ctrl);
3477 ASC_PRT_NEXT();
3478 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3479 len = asc_prt_line(cp, leftlen,
3480 " termination: %u (%s), bios_ctrl: 0x%x\n",
3481 ep_38C0800->termination_lvd, termstr,
3482 ep_38C0800->bios_ctrl);
3483 ASC_PRT_NEXT();
3484 } else {
3485 len = asc_prt_line(cp, leftlen,
3486 " termination: %u (%s), bios_ctrl: 0x%x\n",
3487 ep_38C1600->termination_lvd, termstr,
3488 ep_38C1600->bios_ctrl);
3489 ASC_PRT_NEXT();
3492 len = asc_prt_line(cp, leftlen, " Target ID: ");
3493 ASC_PRT_NEXT();
3494 for (i = 0; i <= ADV_MAX_TID; i++) {
3495 len = asc_prt_line(cp, leftlen, " %X", i);
3496 ASC_PRT_NEXT();
3498 len = asc_prt_line(cp, leftlen, "\n");
3499 ASC_PRT_NEXT();
3501 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3502 word = ep_3550->disc_enable;
3503 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3504 word = ep_38C0800->disc_enable;
3505 } else {
3506 word = ep_38C1600->disc_enable;
3508 len = asc_prt_line(cp, leftlen, " Disconnects: ");
3509 ASC_PRT_NEXT();
3510 for (i = 0; i <= ADV_MAX_TID; i++) {
3511 len = asc_prt_line(cp, leftlen, " %c",
3512 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3513 ASC_PRT_NEXT();
3515 len = asc_prt_line(cp, leftlen, "\n");
3516 ASC_PRT_NEXT();
3518 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3519 word = ep_3550->tagqng_able;
3520 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3521 word = ep_38C0800->tagqng_able;
3522 } else {
3523 word = ep_38C1600->tagqng_able;
3525 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
3526 ASC_PRT_NEXT();
3527 for (i = 0; i <= ADV_MAX_TID; i++) {
3528 len = asc_prt_line(cp, leftlen, " %c",
3529 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3530 ASC_PRT_NEXT();
3532 len = asc_prt_line(cp, leftlen, "\n");
3533 ASC_PRT_NEXT();
3535 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3536 word = ep_3550->start_motor;
3537 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3538 word = ep_38C0800->start_motor;
3539 } else {
3540 word = ep_38C1600->start_motor;
3542 len = asc_prt_line(cp, leftlen, " Start Motor: ");
3543 ASC_PRT_NEXT();
3544 for (i = 0; i <= ADV_MAX_TID; i++) {
3545 len = asc_prt_line(cp, leftlen, " %c",
3546 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3547 ASC_PRT_NEXT();
3549 len = asc_prt_line(cp, leftlen, "\n");
3550 ASC_PRT_NEXT();
3552 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3553 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3554 ASC_PRT_NEXT();
3555 for (i = 0; i <= ADV_MAX_TID; i++) {
3556 len = asc_prt_line(cp, leftlen, " %c",
3557 (ep_3550->
3558 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
3559 'Y' : 'N');
3560 ASC_PRT_NEXT();
3562 len = asc_prt_line(cp, leftlen, "\n");
3563 ASC_PRT_NEXT();
3566 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3567 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
3568 ASC_PRT_NEXT();
3569 for (i = 0; i <= ADV_MAX_TID; i++) {
3570 len = asc_prt_line(cp, leftlen, " %c",
3571 (ep_3550->
3572 ultra_able & ADV_TID_TO_TIDMASK(i))
3573 ? 'Y' : 'N');
3574 ASC_PRT_NEXT();
3576 len = asc_prt_line(cp, leftlen, "\n");
3577 ASC_PRT_NEXT();
3580 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3581 word = ep_3550->wdtr_able;
3582 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3583 word = ep_38C0800->wdtr_able;
3584 } else {
3585 word = ep_38C1600->wdtr_able;
3587 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
3588 ASC_PRT_NEXT();
3589 for (i = 0; i <= ADV_MAX_TID; i++) {
3590 len = asc_prt_line(cp, leftlen, " %c",
3591 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3592 ASC_PRT_NEXT();
3594 len = asc_prt_line(cp, leftlen, "\n");
3595 ASC_PRT_NEXT();
3597 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
3598 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
3599 len = asc_prt_line(cp, leftlen,
3600 " Synchronous Transfer Speed (Mhz):\n ");
3601 ASC_PRT_NEXT();
3602 for (i = 0; i <= ADV_MAX_TID; i++) {
3603 char *speed_str;
3605 if (i == 0) {
3606 sdtr_speed = adv_dvc_varp->sdtr_speed1;
3607 } else if (i == 4) {
3608 sdtr_speed = adv_dvc_varp->sdtr_speed2;
3609 } else if (i == 8) {
3610 sdtr_speed = adv_dvc_varp->sdtr_speed3;
3611 } else if (i == 12) {
3612 sdtr_speed = adv_dvc_varp->sdtr_speed4;
3614 switch (sdtr_speed & ADV_MAX_TID) {
3615 case 0:
3616 speed_str = "Off";
3617 break;
3618 case 1:
3619 speed_str = " 5";
3620 break;
3621 case 2:
3622 speed_str = " 10";
3623 break;
3624 case 3:
3625 speed_str = " 20";
3626 break;
3627 case 4:
3628 speed_str = " 40";
3629 break;
3630 case 5:
3631 speed_str = " 80";
3632 break;
3633 default:
3634 speed_str = "Unk";
3635 break;
3637 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
3638 ASC_PRT_NEXT();
3639 if (i == 7) {
3640 len = asc_prt_line(cp, leftlen, "\n ");
3641 ASC_PRT_NEXT();
3643 sdtr_speed >>= 4;
3645 len = asc_prt_line(cp, leftlen, "\n");
3646 ASC_PRT_NEXT();
3649 return totlen;
3653 * asc_prt_driver_conf()
3655 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3656 * cf. asc_prt_line().
3658 * Return the number of characters copied into 'cp'. No more than
3659 * 'cplen' characters will be copied to 'cp'.
3661 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
3663 asc_board_t *boardp;
3664 int leftlen;
3665 int totlen;
3666 int len;
3667 int chip_scsi_id;
3669 boardp = ASC_BOARDP(shost);
3671 leftlen = cplen;
3672 totlen = len = 0;
3674 len = asc_prt_line(cp, leftlen,
3675 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
3676 shost->host_no);
3677 ASC_PRT_NEXT();
3679 len = asc_prt_line(cp, leftlen,
3680 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
3681 shost->host_busy, shost->last_reset, shost->max_id,
3682 shost->max_lun, shost->max_channel);
3683 ASC_PRT_NEXT();
3685 len = asc_prt_line(cp, leftlen,
3686 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
3687 shost->unique_id, shost->can_queue, shost->this_id,
3688 shost->sg_tablesize, shost->cmd_per_lun);
3689 ASC_PRT_NEXT();
3691 len = asc_prt_line(cp, leftlen,
3692 " unchecked_isa_dma %d, use_clustering %d\n",
3693 shost->unchecked_isa_dma, shost->use_clustering);
3694 ASC_PRT_NEXT();
3696 len = asc_prt_line(cp, leftlen,
3697 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
3698 boardp->flags, boardp->last_reset, jiffies,
3699 boardp->asc_n_io_port);
3700 ASC_PRT_NEXT();
3702 len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
3703 ASC_PRT_NEXT();
3705 if (ASC_NARROW_BOARD(boardp)) {
3706 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
3707 } else {
3708 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
3711 return totlen;
3715 * asc_prt_asc_board_info()
3717 * Print dynamic board configuration information.
3719 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3720 * cf. asc_prt_line().
3722 * Return the number of characters copied into 'cp'. No more than
3723 * 'cplen' characters will be copied to 'cp'.
3725 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
3727 asc_board_t *boardp;
3728 int chip_scsi_id;
3729 int leftlen;
3730 int totlen;
3731 int len;
3732 ASC_DVC_VAR *v;
3733 ASC_DVC_CFG *c;
3734 int i;
3735 int renegotiate = 0;
3737 boardp = ASC_BOARDP(shost);
3738 v = &boardp->dvc_var.asc_dvc_var;
3739 c = &boardp->dvc_cfg.asc_dvc_cfg;
3740 chip_scsi_id = c->chip_scsi_id;
3742 leftlen = cplen;
3743 totlen = len = 0;
3745 len = asc_prt_line(cp, leftlen,
3746 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3747 shost->host_no);
3748 ASC_PRT_NEXT();
3750 len = asc_prt_line(cp, leftlen,
3751 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
3752 c->chip_version, c->lib_version, c->lib_serial_no,
3753 c->mcode_date);
3754 ASC_PRT_NEXT();
3756 len = asc_prt_line(cp, leftlen,
3757 " mcode_version 0x%x, err_code %u\n",
3758 c->mcode_version, v->err_code);
3759 ASC_PRT_NEXT();
3761 /* Current number of commands waiting for the host. */
3762 len = asc_prt_line(cp, leftlen,
3763 " Total Command Pending: %d\n", v->cur_total_qng);
3764 ASC_PRT_NEXT();
3766 len = asc_prt_line(cp, leftlen, " Command Queuing:");
3767 ASC_PRT_NEXT();
3768 for (i = 0; i <= ASC_MAX_TID; i++) {
3769 if ((chip_scsi_id == i) ||
3770 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3771 continue;
3773 len = asc_prt_line(cp, leftlen, " %X:%c",
3775 (v->
3776 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
3777 'Y' : 'N');
3778 ASC_PRT_NEXT();
3780 len = asc_prt_line(cp, leftlen, "\n");
3781 ASC_PRT_NEXT();
3783 /* Current number of commands waiting for a device. */
3784 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
3785 ASC_PRT_NEXT();
3786 for (i = 0; i <= ASC_MAX_TID; i++) {
3787 if ((chip_scsi_id == i) ||
3788 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3789 continue;
3791 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
3792 ASC_PRT_NEXT();
3794 len = asc_prt_line(cp, leftlen, "\n");
3795 ASC_PRT_NEXT();
3797 /* Current limit on number of commands that can be sent to a device. */
3798 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
3799 ASC_PRT_NEXT();
3800 for (i = 0; i <= ASC_MAX_TID; i++) {
3801 if ((chip_scsi_id == i) ||
3802 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3803 continue;
3805 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
3806 ASC_PRT_NEXT();
3808 len = asc_prt_line(cp, leftlen, "\n");
3809 ASC_PRT_NEXT();
3811 /* Indicate whether the device has returned queue full status. */
3812 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
3813 ASC_PRT_NEXT();
3814 for (i = 0; i <= ASC_MAX_TID; i++) {
3815 if ((chip_scsi_id == i) ||
3816 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3817 continue;
3819 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
3820 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
3821 i, boardp->queue_full_cnt[i]);
3822 } else {
3823 len = asc_prt_line(cp, leftlen, " %X:N", i);
3825 ASC_PRT_NEXT();
3827 len = asc_prt_line(cp, leftlen, "\n");
3828 ASC_PRT_NEXT();
3830 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3831 ASC_PRT_NEXT();
3832 for (i = 0; i <= ASC_MAX_TID; i++) {
3833 if ((chip_scsi_id == i) ||
3834 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3835 continue;
3837 len = asc_prt_line(cp, leftlen, " %X:%c",
3839 (v->
3840 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3841 'N');
3842 ASC_PRT_NEXT();
3844 len = asc_prt_line(cp, leftlen, "\n");
3845 ASC_PRT_NEXT();
3847 for (i = 0; i <= ASC_MAX_TID; i++) {
3848 uchar syn_period_ix;
3850 if ((chip_scsi_id == i) ||
3851 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3852 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
3853 continue;
3856 len = asc_prt_line(cp, leftlen, " %X:", i);
3857 ASC_PRT_NEXT();
3859 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
3860 len = asc_prt_line(cp, leftlen, " Asynchronous");
3861 ASC_PRT_NEXT();
3862 } else {
3863 syn_period_ix =
3864 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
3867 len = asc_prt_line(cp, leftlen,
3868 " Transfer Period Factor: %d (%d.%d Mhz),",
3869 v->sdtr_period_tbl[syn_period_ix],
3870 250 /
3871 v->sdtr_period_tbl[syn_period_ix],
3872 ASC_TENTHS(250,
3874 sdtr_period_tbl
3875 [syn_period_ix]));
3876 ASC_PRT_NEXT();
3878 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
3879 boardp->
3880 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
3881 ASC_PRT_NEXT();
3884 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3885 len = asc_prt_line(cp, leftlen, "*\n");
3886 renegotiate = 1;
3887 } else {
3888 len = asc_prt_line(cp, leftlen, "\n");
3890 ASC_PRT_NEXT();
3893 if (renegotiate) {
3894 len = asc_prt_line(cp, leftlen,
3895 " * = Re-negotiation pending before next command.\n");
3896 ASC_PRT_NEXT();
3899 return totlen;
3903 * asc_prt_adv_board_info()
3905 * Print dynamic board configuration information.
3907 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3908 * cf. asc_prt_line().
3910 * Return the number of characters copied into 'cp'. No more than
3911 * 'cplen' characters will be copied to 'cp'.
3913 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
3915 asc_board_t *boardp;
3916 int leftlen;
3917 int totlen;
3918 int len;
3919 int i;
3920 ADV_DVC_VAR *v;
3921 ADV_DVC_CFG *c;
3922 AdvPortAddr iop_base;
3923 ushort chip_scsi_id;
3924 ushort lramword;
3925 uchar lrambyte;
3926 ushort tagqng_able;
3927 ushort sdtr_able, wdtr_able;
3928 ushort wdtr_done, sdtr_done;
3929 ushort period = 0;
3930 int renegotiate = 0;
3932 boardp = ASC_BOARDP(shost);
3933 v = &boardp->dvc_var.adv_dvc_var;
3934 c = &boardp->dvc_cfg.adv_dvc_cfg;
3935 iop_base = v->iop_base;
3936 chip_scsi_id = v->chip_scsi_id;
3938 leftlen = cplen;
3939 totlen = len = 0;
3941 len = asc_prt_line(cp, leftlen,
3942 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3943 shost->host_no);
3944 ASC_PRT_NEXT();
3946 len = asc_prt_line(cp, leftlen,
3947 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
3948 v->iop_base,
3949 AdvReadWordRegister(iop_base,
3950 IOPW_SCSI_CFG1) & CABLE_DETECT,
3951 v->err_code);
3952 ASC_PRT_NEXT();
3954 len = asc_prt_line(cp, leftlen,
3955 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
3956 c->chip_version, c->lib_version, c->mcode_date,
3957 c->mcode_version);
3958 ASC_PRT_NEXT();
3960 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
3961 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
3962 ASC_PRT_NEXT();
3963 for (i = 0; i <= ADV_MAX_TID; i++) {
3964 if ((chip_scsi_id == i) ||
3965 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3966 continue;
3969 len = asc_prt_line(cp, leftlen, " %X:%c",
3971 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3972 'N');
3973 ASC_PRT_NEXT();
3975 len = asc_prt_line(cp, leftlen, "\n");
3976 ASC_PRT_NEXT();
3978 len = asc_prt_line(cp, leftlen, " Queue Limit:");
3979 ASC_PRT_NEXT();
3980 for (i = 0; i <= ADV_MAX_TID; i++) {
3981 if ((chip_scsi_id == i) ||
3982 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3983 continue;
3986 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
3987 lrambyte);
3989 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
3990 ASC_PRT_NEXT();
3992 len = asc_prt_line(cp, leftlen, "\n");
3993 ASC_PRT_NEXT();
3995 len = asc_prt_line(cp, leftlen, " Command Pending:");
3996 ASC_PRT_NEXT();
3997 for (i = 0; i <= ADV_MAX_TID; i++) {
3998 if ((chip_scsi_id == i) ||
3999 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
4000 continue;
4003 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
4004 lrambyte);
4006 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
4007 ASC_PRT_NEXT();
4009 len = asc_prt_line(cp, leftlen, "\n");
4010 ASC_PRT_NEXT();
4012 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
4013 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
4014 ASC_PRT_NEXT();
4015 for (i = 0; i <= ADV_MAX_TID; i++) {
4016 if ((chip_scsi_id == i) ||
4017 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
4018 continue;
4021 len = asc_prt_line(cp, leftlen, " %X:%c",
4023 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4024 'N');
4025 ASC_PRT_NEXT();
4027 len = asc_prt_line(cp, leftlen, "\n");
4028 ASC_PRT_NEXT();
4030 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
4031 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
4032 ASC_PRT_NEXT();
4033 for (i = 0; i <= ADV_MAX_TID; i++) {
4034 if ((chip_scsi_id == i) ||
4035 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
4036 continue;
4039 AdvReadWordLram(iop_base,
4040 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
4041 lramword);
4043 len = asc_prt_line(cp, leftlen, " %X:%d",
4044 i, (lramword & 0x8000) ? 16 : 8);
4045 ASC_PRT_NEXT();
4047 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
4048 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
4049 len = asc_prt_line(cp, leftlen, "*");
4050 ASC_PRT_NEXT();
4051 renegotiate = 1;
4054 len = asc_prt_line(cp, leftlen, "\n");
4055 ASC_PRT_NEXT();
4057 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
4058 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
4059 ASC_PRT_NEXT();
4060 for (i = 0; i <= ADV_MAX_TID; i++) {
4061 if ((chip_scsi_id == i) ||
4062 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
4063 continue;
4066 len = asc_prt_line(cp, leftlen, " %X:%c",
4068 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4069 'N');
4070 ASC_PRT_NEXT();
4072 len = asc_prt_line(cp, leftlen, "\n");
4073 ASC_PRT_NEXT();
4075 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
4076 for (i = 0; i <= ADV_MAX_TID; i++) {
4078 AdvReadWordLram(iop_base,
4079 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
4080 lramword);
4081 lramword &= ~0x8000;
4083 if ((chip_scsi_id == i) ||
4084 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
4085 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
4086 continue;
4089 len = asc_prt_line(cp, leftlen, " %X:", i);
4090 ASC_PRT_NEXT();
4092 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
4093 len = asc_prt_line(cp, leftlen, " Asynchronous");
4094 ASC_PRT_NEXT();
4095 } else {
4096 len =
4097 asc_prt_line(cp, leftlen,
4098 " Transfer Period Factor: ");
4099 ASC_PRT_NEXT();
4101 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
4102 len =
4103 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
4104 ASC_PRT_NEXT();
4105 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
4106 len =
4107 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
4108 ASC_PRT_NEXT();
4109 } else { /* 20 Mhz or below. */
4111 period = (((lramword >> 8) * 25) + 50) / 4;
4113 if (period == 0) { /* Should never happen. */
4114 len =
4115 asc_prt_line(cp, leftlen,
4116 "%d (? Mhz), ");
4117 ASC_PRT_NEXT();
4118 } else {
4119 len = asc_prt_line(cp, leftlen,
4120 "%d (%d.%d Mhz),",
4121 period, 250 / period,
4122 ASC_TENTHS(250,
4123 period));
4124 ASC_PRT_NEXT();
4128 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
4129 lramword & 0x1F);
4130 ASC_PRT_NEXT();
4133 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
4134 len = asc_prt_line(cp, leftlen, "*\n");
4135 renegotiate = 1;
4136 } else {
4137 len = asc_prt_line(cp, leftlen, "\n");
4139 ASC_PRT_NEXT();
4142 if (renegotiate) {
4143 len = asc_prt_line(cp, leftlen,
4144 " * = Re-negotiation pending before next command.\n");
4145 ASC_PRT_NEXT();
4148 return totlen;
4152 * asc_proc_copy()
4154 * Copy proc information to a read buffer taking into account the current
4155 * read offset in the file and the remaining space in the read buffer.
4157 static int
4158 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
4159 char *cp, int cplen)
4161 int cnt = 0;
4163 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
4164 (unsigned)offset, (unsigned)advoffset, cplen);
4165 if (offset <= advoffset) {
4166 /* Read offset below current offset, copy everything. */
4167 cnt = min(cplen, leftlen);
4168 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
4169 (ulong)curbuf, (ulong)cp, cnt);
4170 memcpy(curbuf, cp, cnt);
4171 } else if (offset < advoffset + cplen) {
4172 /* Read offset within current range, partial copy. */
4173 cnt = (advoffset + cplen) - offset;
4174 cp = (cp + cplen) - cnt;
4175 cnt = min(cnt, leftlen);
4176 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
4177 (ulong)curbuf, (ulong)cp, cnt);
4178 memcpy(curbuf, cp, cnt);
4180 return cnt;
4183 #ifdef ADVANSYS_STATS
4185 * asc_prt_board_stats()
4187 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4188 * cf. asc_prt_line().
4190 * Return the number of characters copied into 'cp'. No more than
4191 * 'cplen' characters will be copied to 'cp'.
4193 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
4195 int leftlen;
4196 int totlen;
4197 int len;
4198 struct asc_stats *s;
4199 asc_board_t *boardp;
4201 leftlen = cplen;
4202 totlen = len = 0;
4204 boardp = ASC_BOARDP(shost);
4205 s = &boardp->asc_stats;
4207 len = asc_prt_line(cp, leftlen,
4208 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
4209 shost->host_no);
4210 ASC_PRT_NEXT();
4212 len = asc_prt_line(cp, leftlen,
4213 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
4214 s->queuecommand, s->reset, s->biosparam,
4215 s->interrupt);
4216 ASC_PRT_NEXT();
4218 len = asc_prt_line(cp, leftlen,
4219 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
4220 s->callback, s->done, s->build_error,
4221 s->adv_build_noreq, s->adv_build_nosg);
4222 ASC_PRT_NEXT();
4224 len = asc_prt_line(cp, leftlen,
4225 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
4226 s->exe_noerror, s->exe_busy, s->exe_error,
4227 s->exe_unknown);
4228 ASC_PRT_NEXT();
4231 * Display data transfer statistics.
4233 if (s->cont_cnt > 0) {
4234 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
4235 ASC_PRT_NEXT();
4237 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
4238 s->cont_xfer / 2,
4239 ASC_TENTHS(s->cont_xfer, 2));
4240 ASC_PRT_NEXT();
4242 /* Contiguous transfer average size */
4243 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
4244 (s->cont_xfer / 2) / s->cont_cnt,
4245 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
4246 ASC_PRT_NEXT();
4249 if (s->sg_cnt > 0) {
4251 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
4252 s->sg_cnt, s->sg_elem);
4253 ASC_PRT_NEXT();
4255 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
4256 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
4257 ASC_PRT_NEXT();
4259 /* Scatter gather transfer statistics */
4260 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
4261 s->sg_elem / s->sg_cnt,
4262 ASC_TENTHS(s->sg_elem, s->sg_cnt));
4263 ASC_PRT_NEXT();
4265 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
4266 (s->sg_xfer / 2) / s->sg_elem,
4267 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
4268 ASC_PRT_NEXT();
4270 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
4271 (s->sg_xfer / 2) / s->sg_cnt,
4272 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
4273 ASC_PRT_NEXT();
4277 * Display request queuing statistics.
4279 len = asc_prt_line(cp, leftlen,
4280 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
4281 HZ);
4282 ASC_PRT_NEXT();
4284 return totlen;
4286 #endif /* ADVANSYS_STATS */
4289 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
4291 * *buffer: I/O buffer
4292 * **start: if inout == FALSE pointer into buffer where user read should start
4293 * offset: current offset into a /proc/scsi/advansys/[0...] file
4294 * length: length of buffer
4295 * hostno: Scsi_Host host_no
4296 * inout: TRUE - user is writing; FALSE - user is reading
4298 * Return the number of bytes read from or written to a
4299 * /proc/scsi/advansys/[0...] file.
4301 * Note: This function uses the per board buffer 'prtbuf' which is
4302 * allocated when the board is initialized in advansys_detect(). The
4303 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4304 * used to write to the buffer. The way asc_proc_copy() is written
4305 * if 'prtbuf' is too small it will not be overwritten. Instead the
4306 * user just won't get all the available statistics.
4308 static int
4309 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4310 off_t offset, int length, int inout)
4312 asc_board_t *boardp;
4313 char *cp;
4314 int cplen;
4315 int cnt;
4316 int totcnt;
4317 int leftlen;
4318 char *curbuf;
4319 off_t advoffset;
4321 ASC_DBG(1, "advansys_proc_info: begin\n");
4324 * User write not supported.
4326 if (inout == TRUE) {
4327 return (-ENOSYS);
4331 * User read of /proc/scsi/advansys/[0...] file.
4334 boardp = ASC_BOARDP(shost);
4336 /* Copy read data starting at the beginning of the buffer. */
4337 *start = buffer;
4338 curbuf = buffer;
4339 advoffset = 0;
4340 totcnt = 0;
4341 leftlen = length;
4344 * Get board configuration information.
4346 * advansys_info() returns the board string from its own static buffer.
4348 cp = (char *)advansys_info(shost);
4349 strcat(cp, "\n");
4350 cplen = strlen(cp);
4351 /* Copy board information. */
4352 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4353 totcnt += cnt;
4354 leftlen -= cnt;
4355 if (leftlen == 0) {
4356 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4357 return totcnt;
4359 advoffset += cplen;
4360 curbuf += cnt;
4363 * Display Wide Board BIOS Information.
4365 if (!ASC_NARROW_BOARD(boardp)) {
4366 cp = boardp->prtbuf;
4367 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
4368 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4369 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4370 cplen);
4371 totcnt += cnt;
4372 leftlen -= cnt;
4373 if (leftlen == 0) {
4374 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4375 return totcnt;
4377 advoffset += cplen;
4378 curbuf += cnt;
4382 * Display driver information for each device attached to the board.
4384 cp = boardp->prtbuf;
4385 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
4386 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4387 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4388 totcnt += cnt;
4389 leftlen -= cnt;
4390 if (leftlen == 0) {
4391 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4392 return totcnt;
4394 advoffset += cplen;
4395 curbuf += cnt;
4398 * Display EEPROM configuration for the board.
4400 cp = boardp->prtbuf;
4401 if (ASC_NARROW_BOARD(boardp)) {
4402 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4403 } else {
4404 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4406 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4407 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4408 totcnt += cnt;
4409 leftlen -= cnt;
4410 if (leftlen == 0) {
4411 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4412 return totcnt;
4414 advoffset += cplen;
4415 curbuf += cnt;
4418 * Display driver configuration and information for the board.
4420 cp = boardp->prtbuf;
4421 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
4422 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4423 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4424 totcnt += cnt;
4425 leftlen -= cnt;
4426 if (leftlen == 0) {
4427 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4428 return totcnt;
4430 advoffset += cplen;
4431 curbuf += cnt;
4433 #ifdef ADVANSYS_STATS
4435 * Display driver statistics for the board.
4437 cp = boardp->prtbuf;
4438 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
4439 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4440 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4441 totcnt += cnt;
4442 leftlen -= cnt;
4443 if (leftlen == 0) {
4444 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4445 return totcnt;
4447 advoffset += cplen;
4448 curbuf += cnt;
4449 #endif /* ADVANSYS_STATS */
4452 * Display Asc Library dynamic configuration information
4453 * for the board.
4455 cp = boardp->prtbuf;
4456 if (ASC_NARROW_BOARD(boardp)) {
4457 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
4458 } else {
4459 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
4461 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4462 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4463 totcnt += cnt;
4464 leftlen -= cnt;
4465 if (leftlen == 0) {
4466 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4467 return totcnt;
4469 advoffset += cplen;
4470 curbuf += cnt;
4472 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4474 return totcnt;
4476 #endif /* CONFIG_PROC_FS */
4478 static void asc_scsi_done(struct scsi_cmnd *scp)
4480 struct asc_board *boardp = ASC_BOARDP(scp->device->host);
4482 if (scp->use_sg)
4483 dma_unmap_sg(boardp->dev,
4484 (struct scatterlist *)scp->request_buffer,
4485 scp->use_sg, scp->sc_data_direction);
4486 else if (scp->request_bufflen)
4487 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
4488 scp->request_bufflen, scp->sc_data_direction);
4490 ASC_STATS(scp->device->host, done);
4492 scp->scsi_done(scp);
4495 static void AscSetBank(PortAddr iop_base, uchar bank)
4497 uchar val;
4499 val = AscGetChipControl(iop_base) &
4501 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
4502 CC_CHIP_RESET));
4503 if (bank == 1) {
4504 val |= CC_BANK_ONE;
4505 } else if (bank == 2) {
4506 val |= CC_DIAG | CC_BANK_ONE;
4507 } else {
4508 val &= ~CC_BANK_ONE;
4510 AscSetChipControl(iop_base, val);
4511 return;
4514 static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
4516 AscSetBank(iop_base, 1);
4517 AscWriteChipIH(iop_base, ins_code);
4518 AscSetBank(iop_base, 0);
4519 return;
4522 static int AscStartChip(PortAddr iop_base)
4524 AscSetChipControl(iop_base, 0);
4525 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4526 return (0);
4528 return (1);
4531 static int AscStopChip(PortAddr iop_base)
4533 uchar cc_val;
4535 cc_val =
4536 AscGetChipControl(iop_base) &
4537 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
4538 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
4539 AscSetChipIH(iop_base, INS_HALT);
4540 AscSetChipIH(iop_base, INS_RFLAG_WTM);
4541 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
4542 return (0);
4544 return (1);
4547 static int AscIsChipHalted(PortAddr iop_base)
4549 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4550 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
4551 return (1);
4554 return (0);
4557 static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
4559 PortAddr iop_base;
4560 int i = 10;
4562 iop_base = asc_dvc->iop_base;
4563 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
4564 && (i-- > 0)) {
4565 mdelay(100);
4567 AscStopChip(iop_base);
4568 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
4569 udelay(60);
4570 AscSetChipIH(iop_base, INS_RFLAG_WTM);
4571 AscSetChipIH(iop_base, INS_HALT);
4572 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
4573 AscSetChipControl(iop_base, CC_HALT);
4574 mdelay(200);
4575 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
4576 AscSetChipStatus(iop_base, 0);
4577 return (AscIsChipHalted(iop_base));
4580 static int AscFindSignature(PortAddr iop_base)
4582 ushort sig_word;
4584 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
4585 iop_base, AscGetChipSignatureByte(iop_base));
4586 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
4587 ASC_DBG2(1,
4588 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
4589 iop_base, AscGetChipSignatureWord(iop_base));
4590 sig_word = AscGetChipSignatureWord(iop_base);
4591 if ((sig_word == (ushort)ASC_1000_ID0W) ||
4592 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
4593 return (1);
4596 return (0);
4599 static void AscEnableInterrupt(PortAddr iop_base)
4601 ushort cfg;
4603 cfg = AscGetChipCfgLsw(iop_base);
4604 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
4605 return;
4608 static void AscDisableInterrupt(PortAddr iop_base)
4610 ushort cfg;
4612 cfg = AscGetChipCfgLsw(iop_base);
4613 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
4614 return;
4617 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
4619 unsigned char byte_data;
4620 unsigned short word_data;
4622 if (isodd_word(addr)) {
4623 AscSetChipLramAddr(iop_base, addr - 1);
4624 word_data = AscGetChipLramData(iop_base);
4625 byte_data = (word_data >> 8) & 0xFF;
4626 } else {
4627 AscSetChipLramAddr(iop_base, addr);
4628 word_data = AscGetChipLramData(iop_base);
4629 byte_data = word_data & 0xFF;
4631 return byte_data;
4634 static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
4636 ushort word_data;
4638 AscSetChipLramAddr(iop_base, addr);
4639 word_data = AscGetChipLramData(iop_base);
4640 return (word_data);
4643 #if CC_VERY_LONG_SG_LIST
4644 static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
4646 ushort val_low, val_high;
4647 ASC_DCNT dword_data;
4649 AscSetChipLramAddr(iop_base, addr);
4650 val_low = AscGetChipLramData(iop_base);
4651 val_high = AscGetChipLramData(iop_base);
4652 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
4653 return (dword_data);
4655 #endif /* CC_VERY_LONG_SG_LIST */
4657 static void
4658 AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
4660 int i;
4662 AscSetChipLramAddr(iop_base, s_addr);
4663 for (i = 0; i < words; i++) {
4664 AscSetChipLramData(iop_base, set_wval);
4668 static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
4670 AscSetChipLramAddr(iop_base, addr);
4671 AscSetChipLramData(iop_base, word_val);
4672 return;
4675 static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
4677 ushort word_data;
4679 if (isodd_word(addr)) {
4680 addr--;
4681 word_data = AscReadLramWord(iop_base, addr);
4682 word_data &= 0x00FF;
4683 word_data |= (((ushort)byte_val << 8) & 0xFF00);
4684 } else {
4685 word_data = AscReadLramWord(iop_base, addr);
4686 word_data &= 0xFF00;
4687 word_data |= ((ushort)byte_val & 0x00FF);
4689 AscWriteLramWord(iop_base, addr, word_data);
4690 return;
4694 * Copy 2 bytes to LRAM.
4696 * The source data is assumed to be in little-endian order in memory
4697 * and is maintained in little-endian order when written to LRAM.
4699 static void
4700 AscMemWordCopyPtrToLram(PortAddr iop_base,
4701 ushort s_addr, uchar *s_buffer, int words)
4703 int i;
4705 AscSetChipLramAddr(iop_base, s_addr);
4706 for (i = 0; i < 2 * words; i += 2) {
4708 * On a little-endian system the second argument below
4709 * produces a little-endian ushort which is written to
4710 * LRAM in little-endian order. On a big-endian system
4711 * the second argument produces a big-endian ushort which
4712 * is "transparently" byte-swapped by outpw() and written
4713 * in little-endian order to LRAM.
4715 outpw(iop_base + IOP_RAM_DATA,
4716 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
4718 return;
4722 * Copy 4 bytes to LRAM.
4724 * The source data is assumed to be in little-endian order in memory
4725 * and is maintained in little-endian order when writen to LRAM.
4727 static void
4728 AscMemDWordCopyPtrToLram(PortAddr iop_base,
4729 ushort s_addr, uchar *s_buffer, int dwords)
4731 int i;
4733 AscSetChipLramAddr(iop_base, s_addr);
4734 for (i = 0; i < 4 * dwords; i += 4) {
4735 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
4736 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
4738 return;
4742 * Copy 2 bytes from LRAM.
4744 * The source data is assumed to be in little-endian order in LRAM
4745 * and is maintained in little-endian order when written to memory.
4747 static void
4748 AscMemWordCopyPtrFromLram(PortAddr iop_base,
4749 ushort s_addr, uchar *d_buffer, int words)
4751 int i;
4752 ushort word;
4754 AscSetChipLramAddr(iop_base, s_addr);
4755 for (i = 0; i < 2 * words; i += 2) {
4756 word = inpw(iop_base + IOP_RAM_DATA);
4757 d_buffer[i] = word & 0xff;
4758 d_buffer[i + 1] = (word >> 8) & 0xff;
4760 return;
4763 static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
4765 ASC_DCNT sum;
4766 int i;
4768 sum = 0L;
4769 for (i = 0; i < words; i++, s_addr += 2) {
4770 sum += AscReadLramWord(iop_base, s_addr);
4772 return (sum);
4775 static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
4777 uchar i;
4778 ushort s_addr;
4779 PortAddr iop_base;
4780 ushort warn_code;
4782 iop_base = asc_dvc->iop_base;
4783 warn_code = 0;
4784 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
4785 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
4786 64) >> 1));
4787 i = ASC_MIN_ACTIVE_QNO;
4788 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
4789 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4790 (uchar)(i + 1));
4791 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4792 (uchar)(asc_dvc->max_total_qng));
4793 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4794 (uchar)i);
4795 i++;
4796 s_addr += ASC_QBLK_SIZE;
4797 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
4798 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4799 (uchar)(i + 1));
4800 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4801 (uchar)(i - 1));
4802 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4803 (uchar)i);
4805 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4806 (uchar)ASC_QLINK_END);
4807 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4808 (uchar)(asc_dvc->max_total_qng - 1));
4809 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4810 (uchar)asc_dvc->max_total_qng);
4811 i++;
4812 s_addr += ASC_QBLK_SIZE;
4813 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
4814 i++, s_addr += ASC_QBLK_SIZE) {
4815 AscWriteLramByte(iop_base,
4816 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
4817 AscWriteLramByte(iop_base,
4818 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
4819 AscWriteLramByte(iop_base,
4820 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
4822 return warn_code;
4825 static ASC_DCNT
4826 AscLoadMicroCode(PortAddr iop_base,
4827 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
4829 ASC_DCNT chksum;
4830 ushort mcode_word_size;
4831 ushort mcode_chksum;
4833 /* Write the microcode buffer starting at LRAM address 0. */
4834 mcode_word_size = (ushort)(mcode_size >> 1);
4835 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
4836 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
4838 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
4839 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
4840 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
4841 (ushort)ASC_CODE_SEC_BEG,
4842 (ushort)((mcode_size -
4843 s_addr - (ushort)
4844 ASC_CODE_SEC_BEG) /
4845 2));
4846 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
4847 (ulong)mcode_chksum);
4848 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
4849 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
4850 return (chksum);
4853 /* Microcode buffer is kept after initialization for error recovery. */
4854 static uchar _asc_mcode_buf[] = {
4855 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4856 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
4857 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4858 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4860 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05,
4861 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4862 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4863 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
4864 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
4865 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04,
4866 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
4867 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
4868 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98,
4869 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00,
4870 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
4871 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
4872 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23,
4873 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04,
4874 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
4875 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
4876 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88,
4877 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00,
4878 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
4879 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
4880 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01,
4881 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8,
4882 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
4883 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
4884 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01,
4885 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33,
4886 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
4887 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
4888 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
4889 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23,
4890 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
4891 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
4892 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
4893 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84,
4894 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
4895 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
4896 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
4897 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46,
4898 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
4899 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
4900 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02,
4901 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82,
4902 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
4903 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
4904 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02,
4905 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23,
4906 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
4907 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
4908 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01,
4909 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02,
4910 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
4911 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
4912 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01,
4913 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
4914 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
4915 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
4916 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39,
4917 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6,
4918 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
4919 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
4920 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42,
4921 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01,
4922 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
4923 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
4924 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33,
4925 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83,
4926 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
4927 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
4928 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83,
4929 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00,
4930 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
4931 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
4932 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42,
4933 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95,
4934 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
4935 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
4936 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32,
4937 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84,
4938 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
4939 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
4940 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95,
4941 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4,
4942 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
4943 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
4944 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84,
4945 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84,
4946 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
4947 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
4948 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2,
4949 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00,
4950 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
4951 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
4952 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04,
4953 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00,
4954 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
4955 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
4956 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE,
4957 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62,
4958 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
4959 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
4960 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC,
4961 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95,
4962 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
4963 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
4964 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01,
4965 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01,
4966 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
4967 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
4968 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01,
4969 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05,
4970 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
4971 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
4972 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85,
4973 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63,
4974 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
4975 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
4976 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85,
4977 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85,
4978 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
4979 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
4980 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23,
4981 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87,
4982 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
4983 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
4984 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33,
4985 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60,
4986 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
4987 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
4988 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA,
4989 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33,
4990 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
4991 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
4992 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67,
4993 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
4994 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
4995 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
4996 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6,
4997 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06,
4998 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
4999 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
5000 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03,
5001 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33,
5002 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
5003 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
5004 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B,
5005 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88,
5006 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
5007 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
5008 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07,
5009 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84,
5010 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
5011 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
5012 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04,
5013 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00,
5014 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
5015 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
5016 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01,
5017 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04,
5018 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
5019 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
5020 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05,
5021 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23,
5022 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
5023 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
5024 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
5025 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
5026 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
5027 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
5028 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43,
5029 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01,
5030 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
5031 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
5032 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95,
5033 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88,
5034 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
5035 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
5036 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09,
5037 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32,
5038 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
5039 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
5040 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
5041 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73,
5042 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
5043 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
5044 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77,
5045 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23,
5046 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
5049 static unsigned short _asc_mcode_size = sizeof(_asc_mcode_buf);
5050 static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
5052 /* Microcode buffer is kept after initialization for error recovery. */
5053 static unsigned char _adv_asc3550_buf[] = {
5054 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
5055 0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00,
5056 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7,
5057 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
5058 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
5059 0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54,
5060 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01,
5061 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
5062 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
5063 0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
5064 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
5065 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
5066 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
5067 0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
5068 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a,
5069 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
5070 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
5071 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00,
5072 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c,
5073 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
5074 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
5075 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10,
5076 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56,
5077 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
5078 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
5079 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00,
5080 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10,
5081 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
5082 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
5083 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55,
5084 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0,
5085 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
5086 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
5087 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01,
5088 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02,
5089 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
5090 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
5091 0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13,
5092 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18,
5093 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
5094 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
5095 0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90,
5096 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10,
5097 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
5098 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
5099 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00,
5100 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5101 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
5102 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
5103 0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe,
5104 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02,
5105 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
5106 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
5107 0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe,
5108 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
5109 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
5110 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
5111 0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02,
5112 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02,
5113 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
5114 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
5115 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10,
5116 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d,
5117 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
5118 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
5119 0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0,
5120 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe,
5121 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
5122 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
5123 0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d,
5124 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a,
5125 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
5126 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
5127 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03,
5128 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe,
5129 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
5130 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
5131 0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0,
5132 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f,
5133 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
5134 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
5135 0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2,
5136 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11,
5137 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
5138 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
5139 0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe,
5140 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1,
5141 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
5142 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
5143 0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28,
5144 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02,
5145 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
5146 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
5147 0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04,
5148 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe,
5149 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
5150 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
5151 0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c,
5152 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe,
5153 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
5154 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
5155 0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90,
5156 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67,
5157 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
5158 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
5159 0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2,
5160 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04,
5161 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
5162 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
5163 0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05,
5164 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1,
5165 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
5166 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
5167 0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d,
5168 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b,
5169 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
5170 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
5171 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19,
5172 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05,
5173 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
5174 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
5175 0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48,
5176 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d,
5177 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
5178 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
5179 0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4,
5180 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87,
5181 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
5182 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
5183 0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a,
5184 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
5185 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
5186 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
5187 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
5188 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02,
5189 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
5190 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
5191 0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25,
5192 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c,
5193 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
5194 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
5195 0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a,
5196 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80,
5197 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
5198 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
5199 0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
5200 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52,
5201 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
5202 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
5203 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18,
5204 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58,
5205 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
5206 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
5207 0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35,
5208 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0,
5209 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
5210 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
5211 0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10,
5212 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61,
5213 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
5214 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
5215 0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe,
5216 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10,
5217 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
5218 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
5219 0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
5220 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d,
5221 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
5222 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
5223 0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01,
5224 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02,
5225 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
5226 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
5227 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
5228 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77,
5229 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
5230 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
5231 0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05,
5232 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56,
5233 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
5234 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
5235 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59,
5236 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00,
5237 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
5238 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
5239 0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a,
5240 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d,
5241 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
5242 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
5243 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe,
5244 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51,
5245 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
5246 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
5247 0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00,
5248 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33,
5249 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
5250 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
5251 0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe,
5252 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93,
5253 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
5254 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
5255 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0,
5256 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9,
5257 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
5258 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
5259 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd,
5260 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f,
5261 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
5262 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
5263 0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54,
5264 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01,
5265 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
5266 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
5267 0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e,
5268 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01,
5269 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
5270 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
5271 0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02,
5272 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe,
5273 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
5274 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
5275 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35,
5276 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f,
5277 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
5278 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
5279 0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b,
5280 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea,
5281 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
5282 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
5283 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47,
5284 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38,
5285 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
5286 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
5287 0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe,
5288 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce,
5289 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
5290 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
5291 0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe,
5292 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe,
5293 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
5294 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
5295 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4,
5296 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe,
5297 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
5298 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
5299 0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11,
5300 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12,
5301 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
5302 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
5303 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc,
5304 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23,
5305 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
5306 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
5307 0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe,
5308 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
5309 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
5310 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
5311 0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01,
5312 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
5313 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
5314 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
5315 0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76,
5316 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
5317 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
5318 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
5319 0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48,
5320 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08,
5321 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
5322 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
5323 0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0,
5324 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
5325 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
5326 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
5327 0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a,
5328 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
5329 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
5330 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
5331 0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03,
5332 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe,
5333 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
5334 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
5335 0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30,
5336 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16,
5337 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
5338 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
5339 0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01,
5340 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe,
5341 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
5342 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
5343 0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77,
5344 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c,
5345 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
5346 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
5347 0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40,
5348 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1,
5349 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
5350 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
5351 0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe,
5352 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
5353 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
5354 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
5355 0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5,
5356 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c,
5357 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
5358 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
5359 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19,
5360 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e,
5361 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
5362 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
5363 0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49,
5364 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f,
5365 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
5366 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
5367 0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe,
5368 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c,
5369 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
5370 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
5371 0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14,
5372 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a,
5373 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
5374 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
5375 0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe,
5376 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc,
5377 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
5378 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
5379 0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13,
5380 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56,
5381 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
5382 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
5383 0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c,
5384 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00,
5385 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
5386 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
5387 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01,
5388 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f,
5389 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
5390 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
5391 0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2,
5392 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78,
5393 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
5394 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
5395 0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00,
5396 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28,
5397 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
5398 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
5399 0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4,
5400 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe,
5401 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
5402 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
5403 0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe,
5404 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23,
5405 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
5406 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
5407 0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26,
5408 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08,
5409 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
5410 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
5411 0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44,
5412 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e,
5413 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
5414 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
5415 0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03,
5416 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01,
5417 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
5418 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
5419 0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03,
5420 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10,
5421 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
5422 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
5423 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01,
5424 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f,
5425 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
5426 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
5427 0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90,
5428 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe,
5429 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
5430 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
5431 0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
5432 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10,
5433 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
5434 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
5435 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f,
5436 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14,
5437 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
5438 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
5439 0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe,
5440 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe,
5441 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
5442 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
5443 0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17,
5444 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71,
5445 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
5446 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
5447 0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0,
5448 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
5449 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
5450 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
5451 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c,
5452 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17,
5453 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
5454 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
5455 0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73,
5456 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e,
5457 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
5458 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
5459 0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18,
5460 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2,
5461 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
5462 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
5463 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe,
5464 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12,
5465 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
5466 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
5467 0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26,
5468 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93,
5469 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
5470 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
5471 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
5472 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
5475 static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
5476 static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
5478 /* Microcode buffer is kept after initialization for error recovery. */
5479 static unsigned char _adv_asc38C0800_buf[] = {
5480 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
5481 0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19,
5482 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00,
5483 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
5484 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
5485 0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0,
5486 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc,
5487 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
5488 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
5489 0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc,
5490 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54,
5491 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
5492 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
5493 0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80,
5494 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00,
5495 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
5496 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
5497 0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0,
5498 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01,
5499 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
5500 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
5501 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
5502 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11,
5503 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
5504 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
5505 0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc,
5506 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00,
5507 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
5508 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
5509 0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17,
5510 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44,
5511 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
5512 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
5513 0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00,
5514 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00,
5515 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
5516 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
5517 0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f,
5518 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12,
5519 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
5520 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
5521 0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
5522 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10,
5523 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
5524 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
5525 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00,
5526 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5527 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
5528 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
5529 0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe,
5530 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06,
5531 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
5532 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
5533 0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe,
5534 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
5535 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
5536 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
5537 0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02,
5538 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02,
5539 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
5540 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
5541 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10,
5542 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59,
5543 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
5544 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
5545 0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0,
5546 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe,
5547 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
5548 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
5549 0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43,
5550 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54,
5551 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
5552 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
5553 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe,
5554 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02,
5555 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
5556 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
5557 0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe,
5558 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10,
5559 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
5560 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
5561 0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78,
5562 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9,
5563 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
5564 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
5565 0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a,
5566 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d,
5567 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
5568 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
5569 0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda,
5570 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28,
5571 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
5572 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
5573 0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
5574 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04,
5575 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
5576 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
5577 0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62,
5578 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52,
5579 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
5580 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
5581 0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe,
5582 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00,
5583 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
5584 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
5585 0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf,
5586 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08,
5587 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
5588 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
5589 0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe,
5590 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff,
5591 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
5592 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
5593 0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05,
5594 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab,
5595 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
5596 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
5597 0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39,
5598 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2,
5599 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
5600 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
5601 0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18,
5602 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe,
5603 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
5604 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
5605 0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01,
5606 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02,
5607 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
5608 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
5609 0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12,
5610 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2,
5611 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
5612 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
5613 0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05,
5614 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
5615 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
5616 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
5617 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01,
5618 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
5619 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
5620 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
5621 0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d,
5622 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0,
5623 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
5624 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
5625 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14,
5626 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12,
5627 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
5628 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
5629 0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe,
5630 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88,
5631 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
5632 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
5633 0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe,
5634 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b,
5635 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
5636 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
5637 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d,
5638 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08,
5639 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
5640 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
5641 0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06,
5642 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9,
5643 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
5644 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
5645 0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a,
5646 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09,
5647 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
5648 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
5649 0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58,
5650 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe,
5651 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
5652 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
5653 0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe,
5654 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76,
5655 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
5656 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
5657 0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10,
5658 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a,
5659 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
5660 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
5661 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f,
5662 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18,
5663 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
5664 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
5665 0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a,
5666 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09,
5667 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
5668 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
5669 0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a,
5670 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d,
5671 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
5672 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
5673 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe,
5674 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe,
5675 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
5676 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
5677 0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8,
5678 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40,
5679 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
5680 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
5681 0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05,
5682 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe,
5683 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
5684 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
5685 0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32,
5686 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe,
5687 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
5688 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
5689 0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
5690 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe,
5691 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
5692 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
5693 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6,
5694 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe,
5695 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
5696 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
5697 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd,
5698 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb,
5699 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
5700 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
5701 0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05,
5702 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27,
5703 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
5704 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
5705 0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6,
5706 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00,
5707 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
5708 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
5709 0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c,
5710 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe,
5711 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
5712 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
5713 0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09,
5714 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b,
5715 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
5716 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
5717 0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96,
5718 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f,
5719 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
5720 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
5721 0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c,
5722 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
5723 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
5724 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
5725 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41,
5726 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70,
5727 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
5728 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
5729 0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02,
5730 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45,
5731 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
5732 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
5733 0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09,
5734 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe,
5735 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
5736 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
5737 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe,
5738 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41,
5739 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
5740 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
5741 0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00,
5742 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
5743 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
5744 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
5745 0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01,
5746 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01,
5747 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
5748 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
5749 0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24,
5750 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03,
5751 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
5752 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
5753 0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05,
5754 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
5755 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
5756 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
5757 0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f,
5758 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01,
5759 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
5760 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
5761 0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe,
5762 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
5763 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
5764 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
5765 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe,
5766 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
5767 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
5768 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
5769 0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe,
5770 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22,
5771 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
5772 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
5773 0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b,
5774 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f,
5775 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
5776 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
5777 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe,
5778 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe,
5779 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
5780 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
5781 0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe,
5782 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7,
5783 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
5784 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
5785 0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17,
5786 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24,
5787 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
5788 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
5789 0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe,
5790 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c,
5791 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
5792 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
5793 0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01,
5794 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe,
5795 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
5796 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
5797 0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe,
5798 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a,
5799 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
5800 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
5801 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe,
5802 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50,
5803 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
5804 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
5805 0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a,
5806 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d,
5807 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
5808 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
5809 0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a,
5810 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf,
5811 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
5812 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
5813 0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06,
5814 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee,
5815 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
5816 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
5817 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01,
5818 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33,
5819 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
5820 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
5821 0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1,
5822 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15,
5823 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
5824 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
5825 0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01,
5826 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
5827 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
5828 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
5829 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
5830 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58,
5831 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
5832 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
5833 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c,
5834 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd,
5835 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
5836 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
5837 0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15,
5838 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe,
5839 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
5840 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
5841 0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83,
5842 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d,
5843 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
5844 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
5845 0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2,
5846 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90,
5847 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
5848 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
5849 0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e,
5850 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90,
5851 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
5852 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
5853 0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
5854 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16,
5855 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
5856 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
5857 0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
5858 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01,
5859 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
5860 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
5861 0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27,
5862 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d,
5863 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
5864 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
5865 0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8,
5866 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11,
5867 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
5868 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
5869 0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01,
5870 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75,
5871 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
5872 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
5873 0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04,
5874 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03,
5875 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
5876 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
5877 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79,
5878 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35,
5879 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
5880 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
5881 0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c,
5882 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe,
5883 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
5884 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
5885 0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23,
5886 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe,
5887 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
5888 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
5889 0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7,
5890 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04,
5891 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
5892 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
5893 0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2,
5894 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32,
5895 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
5896 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
5897 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11,
5898 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16,
5899 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
5900 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
5901 0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18,
5902 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73,
5903 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
5904 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
5905 0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46,
5906 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04,
5907 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
5908 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
5909 0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10,
5910 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00,
5911 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
5912 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
5913 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e,
5914 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08,
5915 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
5916 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
5917 0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09,
5918 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19,
5919 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
5920 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
5921 0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe,
5922 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0,
5923 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
5924 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
5927 static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
5928 static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
5930 /* Microcode buffer is kept after initialization for error recovery. */
5931 static unsigned char _adv_asc38C1600_buf[] = {
5932 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
5933 0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13,
5934 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff,
5935 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
5936 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
5937 0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4,
5938 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e,
5939 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
5940 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
5941 0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc,
5942 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12,
5943 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
5944 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
5945 0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4,
5946 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01,
5947 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
5948 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
5949 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
5950 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10,
5951 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
5952 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
5953 0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12,
5954 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c,
5955 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
5956 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
5957 0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00,
5958 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10,
5959 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
5960 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
5961 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7,
5962 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00,
5963 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
5964 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
5965 0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46,
5966 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6,
5967 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
5968 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
5969 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01,
5970 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01,
5971 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
5972 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
5973 0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13,
5974 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10,
5975 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
5976 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
5977 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00,
5978 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5979 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
5980 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
5981 0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe,
5982 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c,
5983 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
5984 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
5985 0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05,
5986 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1,
5987 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
5988 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
5989 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60,
5990 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52,
5991 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
5992 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
5993 0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7,
5994 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f,
5995 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
5996 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
5997 0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d,
5998 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe,
5999 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
6000 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
6001 0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec,
6002 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde,
6003 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
6004 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
6005 0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41,
6006 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03,
6007 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
6008 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
6009 0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40,
6010 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0,
6011 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
6012 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
6013 0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28,
6014 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01,
6015 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
6016 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
6017 0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe,
6018 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0,
6019 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
6020 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
6021 0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf,
6022 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a,
6023 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
6024 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
6025 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29,
6026 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00,
6027 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
6028 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
6029 0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13,
6030 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e,
6031 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
6032 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
6033 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe,
6034 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43,
6035 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
6036 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
6037 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe,
6038 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f,
6039 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
6040 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
6041 0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c,
6042 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0,
6043 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
6044 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
6045 0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe,
6046 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f,
6047 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
6048 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
6049 0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba,
6050 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2,
6051 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
6052 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
6053 0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27,
6054 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f,
6055 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
6056 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
6057 0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13,
6058 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06,
6059 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
6060 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
6061 0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13,
6062 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe,
6063 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
6064 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
6065 0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01,
6066 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15,
6067 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
6068 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
6069 0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01,
6070 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95,
6071 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
6072 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
6073 0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe,
6074 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21,
6075 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
6076 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
6077 0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00,
6078 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe,
6079 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
6080 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
6081 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe,
6082 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76,
6083 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
6084 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
6085 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00,
6086 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe,
6087 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
6088 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
6089 0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c,
6090 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08,
6091 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
6092 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
6093 0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe,
6094 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21,
6095 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
6096 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
6097 0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20,
6098 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
6099 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
6100 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
6101 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b,
6102 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12,
6103 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
6104 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
6105 0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90,
6106 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6,
6107 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
6108 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
6109 0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2,
6110 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34,
6111 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
6112 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
6113 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a,
6114 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a,
6115 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
6116 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
6117 0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d,
6118 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76,
6119 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
6120 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
6121 0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe,
6122 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b,
6123 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
6124 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
6125 0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5,
6126 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe,
6127 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
6128 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
6129 0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05,
6130 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06,
6131 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
6132 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
6133 0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42,
6134 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57,
6135 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
6136 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
6137 0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01,
6138 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c,
6139 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
6140 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
6141 0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06,
6142 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7,
6143 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
6144 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
6145 0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe,
6146 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a,
6147 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
6148 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
6149 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e,
6150 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26,
6151 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
6152 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
6153 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef,
6154 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe,
6155 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
6156 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
6157 0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18,
6158 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe,
6159 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
6160 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
6161 0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe,
6162 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe,
6163 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
6164 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
6165 0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12,
6166 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e,
6167 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
6168 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
6169 0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0,
6170 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41,
6171 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
6172 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
6173 0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01,
6174 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81,
6175 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
6176 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
6177 0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe,
6178 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00,
6179 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
6180 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
6181 0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f,
6182 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e,
6183 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
6184 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
6185 0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01,
6186 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d,
6187 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
6188 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
6189 0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
6190 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19,
6191 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
6192 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
6193 0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75,
6194 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d,
6195 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
6196 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
6197 0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e,
6198 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0,
6199 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
6200 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
6201 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe,
6202 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe,
6203 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
6204 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
6205 0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12,
6206 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe,
6207 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
6208 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
6209 0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe,
6210 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec,
6211 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
6212 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
6213 0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3,
6214 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10,
6215 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
6216 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
6217 0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13,
6218 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc,
6219 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
6220 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
6221 0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06,
6222 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83,
6223 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
6224 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
6225 0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c,
6226 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe,
6227 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
6228 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
6229 0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01,
6230 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01,
6231 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
6232 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
6233 0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64,
6234 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe,
6235 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
6236 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
6237 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03,
6238 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07,
6239 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
6240 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
6241 0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe,
6242 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13,
6243 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
6244 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
6245 0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
6246 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10,
6247 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
6248 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
6249 0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
6250 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01,
6251 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
6252 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
6253 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85,
6254 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec,
6255 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
6256 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
6257 0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee,
6258 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d,
6259 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
6260 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
6261 0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42,
6262 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a,
6263 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
6264 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
6265 0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34,
6266 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e,
6267 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
6268 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
6269 0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
6270 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa,
6271 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
6272 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
6273 0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56,
6274 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9,
6275 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
6276 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
6277 0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03,
6278 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e,
6279 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
6280 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
6281 0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13,
6282 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9,
6283 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
6284 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
6285 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d,
6286 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a,
6287 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
6288 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
6289 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45,
6290 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01,
6291 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
6292 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
6293 0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66,
6294 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56,
6295 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
6296 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
6297 0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe,
6298 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05,
6299 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
6300 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
6301 0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b,
6302 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d,
6303 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
6304 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
6305 0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17,
6306 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe,
6307 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
6308 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
6309 0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02,
6310 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30,
6311 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
6312 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
6313 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58,
6314 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01,
6315 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
6316 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
6317 0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a,
6318 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00,
6319 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
6320 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
6321 0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16,
6322 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17,
6323 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
6324 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
6325 0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d,
6326 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04,
6327 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
6328 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
6329 0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16,
6330 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64,
6331 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
6332 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
6333 0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe,
6334 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe,
6335 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
6336 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
6337 0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe,
6338 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7,
6339 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
6340 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
6341 0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9,
6342 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe,
6343 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
6344 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
6345 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01,
6346 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2,
6347 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
6348 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
6349 0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18,
6350 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe,
6351 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
6352 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
6353 0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe,
6354 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10,
6355 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
6356 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
6357 0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe,
6358 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4,
6359 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
6360 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
6361 0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01,
6362 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e,
6363 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
6364 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
6365 0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f,
6366 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
6367 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
6368 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
6369 0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f,
6370 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89,
6371 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
6372 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
6373 0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c,
6374 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e,
6375 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
6376 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
6377 0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09,
6378 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18,
6379 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
6380 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
6381 0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe,
6382 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01,
6383 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
6384 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
6385 0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c,
6386 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d,
6387 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
6388 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
6389 0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01,
6390 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe,
6391 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
6392 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
6393 0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9,
6394 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83,
6395 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
6396 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
6397 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b,
6398 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04,
6399 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
6400 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
6401 0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6,
6402 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c,
6403 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
6404 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
6405 0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83,
6406 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a,
6407 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
6408 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
6409 0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13,
6410 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1,
6411 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
6412 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
6413 0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48,
6414 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f,
6415 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
6416 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
6417 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d,
6418 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30,
6419 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
6420 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
6421 0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31,
6422 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba,
6423 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
6424 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
6425 0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89,
6426 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90,
6427 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
6428 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
6429 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe,
6430 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1,
6431 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
6432 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
6433 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa,
6434 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d,
6435 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
6436 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
6437 0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e,
6438 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99,
6439 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
6440 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
6441 0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80,
6442 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98,
6443 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
6444 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
6445 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b,
6446 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84,
6447 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
6448 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
6449 0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06,
6450 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f,
6451 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6452 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6453 0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6454 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6455 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6456 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6457 0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b,
6458 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e,
6459 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
6462 static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
6463 static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
6465 static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
6467 PortAddr iop_base;
6468 int i;
6469 ushort lram_addr;
6471 iop_base = asc_dvc->iop_base;
6472 AscPutRiscVarFreeQHead(iop_base, 1);
6473 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6474 AscPutVarFreeQHead(iop_base, 1);
6475 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6476 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
6477 (uchar)((int)asc_dvc->max_total_qng + 1));
6478 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
6479 (uchar)((int)asc_dvc->max_total_qng + 2));
6480 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
6481 asc_dvc->max_total_qng);
6482 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
6483 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6484 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
6485 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
6486 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
6487 AscPutQDoneInProgress(iop_base, 0);
6488 lram_addr = ASC_QADR_BEG;
6489 for (i = 0; i < 32; i++, lram_addr += 2) {
6490 AscWriteLramWord(iop_base, lram_addr, 0);
6494 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
6496 int i;
6497 ushort warn_code;
6498 PortAddr iop_base;
6499 ASC_PADDR phy_addr;
6500 ASC_DCNT phy_size;
6502 iop_base = asc_dvc->iop_base;
6503 warn_code = 0;
6504 for (i = 0; i <= ASC_MAX_TID; i++) {
6505 AscPutMCodeInitSDTRAtID(iop_base, i,
6506 asc_dvc->cfg->sdtr_period_offset[i]);
6509 AscInitQLinkVar(asc_dvc);
6510 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
6511 asc_dvc->cfg->disc_enable);
6512 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
6513 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
6515 /* Align overrun buffer on an 8 byte boundary. */
6516 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
6517 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
6518 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
6519 (uchar *)&phy_addr, 1);
6520 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
6521 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
6522 (uchar *)&phy_size, 1);
6524 asc_dvc->cfg->mcode_date =
6525 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
6526 asc_dvc->cfg->mcode_version =
6527 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
6529 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
6530 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
6531 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
6532 return warn_code;
6534 if (AscStartChip(iop_base) != 1) {
6535 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
6536 return warn_code;
6539 return warn_code;
6542 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
6544 ushort warn_code;
6545 PortAddr iop_base;
6547 iop_base = asc_dvc->iop_base;
6548 warn_code = 0;
6549 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
6550 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
6551 AscResetChipAndScsiBus(asc_dvc);
6552 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
6554 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
6555 if (asc_dvc->err_code != 0)
6556 return UW_ERR;
6557 if (!AscFindSignature(asc_dvc->iop_base)) {
6558 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
6559 return warn_code;
6561 AscDisableInterrupt(iop_base);
6562 warn_code |= AscInitLram(asc_dvc);
6563 if (asc_dvc->err_code != 0)
6564 return UW_ERR;
6565 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
6566 (ulong)_asc_mcode_chksum);
6567 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
6568 _asc_mcode_size) != _asc_mcode_chksum) {
6569 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
6570 return warn_code;
6572 warn_code |= AscInitMicroCodeVar(asc_dvc);
6573 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
6574 AscEnableInterrupt(iop_base);
6575 return warn_code;
6579 * Load the Microcode
6581 * Write the microcode image to RISC memory starting at address 0.
6583 * The microcode is stored compressed in the following format:
6585 * 254 word (508 byte) table indexed by byte code followed
6586 * by the following byte codes:
6588 * 1-Byte Code:
6589 * 00: Emit word 0 in table.
6590 * 01: Emit word 1 in table.
6592 * FD: Emit word 253 in table.
6594 * Multi-Byte Code:
6595 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
6596 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
6598 * Returns 0 or an error if the checksum doesn't match
6600 static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
6601 int memsize, int chksum)
6603 int i, j, end, len = 0;
6604 ADV_DCNT sum;
6606 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6608 for (i = 253 * 2; i < size; i++) {
6609 if (buf[i] == 0xff) {
6610 unsigned short word = (buf[i + 3] << 8) | buf[i + 2];
6611 for (j = 0; j < buf[i + 1]; j++) {
6612 AdvWriteWordAutoIncLram(iop_base, word);
6613 len += 2;
6615 i += 3;
6616 } else if (buf[i] == 0xfe) {
6617 unsigned short word = (buf[i + 2] << 8) | buf[i + 1];
6618 AdvWriteWordAutoIncLram(iop_base, word);
6619 i += 2;
6620 len += 2;
6621 } else {
6622 unsigned char off = buf[i] * 2;
6623 unsigned short word = (buf[off + 1] << 8) | buf[off];
6624 AdvWriteWordAutoIncLram(iop_base, word);
6625 len += 2;
6629 end = len;
6631 while (len < memsize) {
6632 AdvWriteWordAutoIncLram(iop_base, 0);
6633 len += 2;
6636 /* Verify the microcode checksum. */
6637 sum = 0;
6638 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6640 for (len = 0; len < end; len += 2) {
6641 sum += AdvReadWordAutoIncLram(iop_base);
6644 if (sum != chksum)
6645 return ASC_IERR_MCODE_CHKSUM;
6647 return 0;
6651 * DvcGetPhyAddr()
6653 * Return the physical address of 'vaddr' and set '*lenp' to the
6654 * number of physically contiguous bytes that follow 'vaddr'.
6655 * 'flag' indicates the type of structure whose physical address
6656 * is being translated.
6658 * Note: Because Linux currently doesn't page the kernel and all
6659 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
6661 ADV_PADDR
6662 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
6663 uchar *vaddr, ADV_SDCNT *lenp, int flag)
6665 ADV_PADDR paddr = virt_to_bus(vaddr);
6667 ASC_DBG4(4, "DvcGetPhyAddr: vaddr 0x%p, lenp 0x%p *lenp %lu, paddr 0x%lx\n",
6668 vaddr, lenp, (ulong)*((ulong *)lenp), (ulong)paddr);
6670 return paddr;
6673 static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
6675 ADV_CARR_T *carrp;
6676 ADV_SDCNT buf_size;
6677 ADV_PADDR carr_paddr;
6679 BUG_ON(!asc_dvc->carrier_buf);
6681 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
6682 asc_dvc->carr_freelist = NULL;
6683 if (carrp == asc_dvc->carrier_buf) {
6684 buf_size = ADV_CARRIER_BUFSIZE;
6685 } else {
6686 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
6689 do {
6690 /* Get physical address of the carrier 'carrp'. */
6691 ADV_DCNT contig_len = sizeof(ADV_CARR_T);
6692 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL,
6693 (uchar *)carrp,
6694 (ADV_SDCNT *)&contig_len,
6695 ADV_IS_CARRIER_FLAG));
6697 buf_size -= sizeof(ADV_CARR_T);
6700 * If the current carrier is not physically contiguous, then
6701 * maybe there was a page crossing. Try the next carrier
6702 * aligned start address.
6704 if (contig_len < sizeof(ADV_CARR_T)) {
6705 carrp++;
6706 continue;
6709 carrp->carr_pa = carr_paddr;
6710 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
6713 * Insert the carrier at the beginning of the freelist.
6715 carrp->next_vpa =
6716 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
6717 asc_dvc->carr_freelist = carrp;
6719 carrp++;
6720 } while (buf_size > 0);
6724 * Send an idle command to the chip and wait for completion.
6726 * Command completion is polled for once per microsecond.
6728 * The function can be called from anywhere including an interrupt handler.
6729 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
6730 * functions to prevent reentrancy.
6732 * Return Values:
6733 * ADV_TRUE - command completed successfully
6734 * ADV_FALSE - command failed
6735 * ADV_ERROR - command timed out
6737 static int
6738 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
6739 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
6741 int result;
6742 ADV_DCNT i, j;
6743 AdvPortAddr iop_base;
6745 iop_base = asc_dvc->iop_base;
6748 * Clear the idle command status which is set by the microcode
6749 * to a non-zero value to indicate when the command is completed.
6750 * The non-zero result is one of the IDLE_CMD_STATUS_* values
6752 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
6755 * Write the idle command value after the idle command parameter
6756 * has been written to avoid a race condition. If the order is not
6757 * followed, the microcode may process the idle command before the
6758 * parameters have been written to LRAM.
6760 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
6761 cpu_to_le32(idle_cmd_parameter));
6762 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
6765 * Tickle the RISC to tell it to process the idle command.
6767 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
6768 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
6770 * Clear the tickle value. In the ASC-3550 the RISC flag
6771 * command 'clr_tickle_b' does not work unless the host
6772 * value is cleared.
6774 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
6777 /* Wait for up to 100 millisecond for the idle command to timeout. */
6778 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
6779 /* Poll once each microsecond for command completion. */
6780 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
6781 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
6782 result);
6783 if (result != 0)
6784 return result;
6785 udelay(1);
6789 BUG(); /* The idle command should never timeout. */
6790 return ADV_ERROR;
6794 * Reset SCSI Bus and purge all outstanding requests.
6796 * Return Value:
6797 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
6798 * ADV_FALSE(0) - Microcode command failed.
6799 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
6800 * may be hung which requires driver recovery.
6802 static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
6804 int status;
6807 * Send the SCSI Bus Reset idle start idle command which asserts
6808 * the SCSI Bus Reset signal.
6810 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
6811 if (status != ADV_TRUE) {
6812 return status;
6816 * Delay for the specified SCSI Bus Reset hold time.
6818 * The hold time delay is done on the host because the RISC has no
6819 * microsecond accurate timer.
6821 udelay(ASC_SCSI_RESET_HOLD_TIME_US);
6824 * Send the SCSI Bus Reset end idle command which de-asserts
6825 * the SCSI Bus Reset signal and purges any pending requests.
6827 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
6828 if (status != ADV_TRUE) {
6829 return status;
6832 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
6834 return status;
6838 * Initialize the ASC-3550.
6840 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
6842 * For a non-fatal error return a warning code. If there are no warnings
6843 * then 0 is returned.
6845 * Needed after initialization for error recovery.
6847 static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
6849 AdvPortAddr iop_base;
6850 ushort warn_code;
6851 int begin_addr;
6852 int end_addr;
6853 ushort code_sum;
6854 int word;
6855 int i;
6856 ushort scsi_cfg1;
6857 uchar tid;
6858 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
6859 ushort wdtr_able = 0, sdtr_able, tagqng_able;
6860 uchar max_cmd[ADV_MAX_TID + 1];
6862 /* If there is already an error, don't continue. */
6863 if (asc_dvc->err_code != 0)
6864 return ADV_ERROR;
6867 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
6869 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
6870 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
6871 return ADV_ERROR;
6874 warn_code = 0;
6875 iop_base = asc_dvc->iop_base;
6878 * Save the RISC memory BIOS region before writing the microcode.
6879 * The BIOS may already be loaded and using its RISC LRAM region
6880 * so its region must be saved and restored.
6882 * Note: This code makes the assumption, which is currently true,
6883 * that a chip reset does not clear RISC LRAM.
6885 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6886 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6887 bios_mem[i]);
6891 * Save current per TID negotiated values.
6893 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
6894 ushort bios_version, major, minor;
6896 bios_version =
6897 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
6898 major = (bios_version >> 12) & 0xF;
6899 minor = (bios_version >> 8) & 0xF;
6900 if (major < 3 || (major == 3 && minor == 1)) {
6901 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
6902 AdvReadWordLram(iop_base, 0x120, wdtr_able);
6903 } else {
6904 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
6907 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
6908 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6909 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
6910 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
6911 max_cmd[tid]);
6914 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf,
6915 _adv_asc3550_size, ADV_3550_MEMSIZE,
6916 _adv_asc3550_chksum);
6917 if (asc_dvc->err_code)
6918 return ADV_ERROR;
6921 * Restore the RISC memory BIOS region.
6923 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6924 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6925 bios_mem[i]);
6929 * Calculate and write the microcode code checksum to the microcode
6930 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
6932 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
6933 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
6934 code_sum = 0;
6935 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
6936 for (word = begin_addr; word < end_addr; word += 2) {
6937 code_sum += AdvReadWordAutoIncLram(iop_base);
6939 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
6942 * Read and save microcode version and date.
6944 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
6945 asc_dvc->cfg->mcode_date);
6946 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
6947 asc_dvc->cfg->mcode_version);
6950 * Set the chip type to indicate the ASC3550.
6952 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
6955 * If the PCI Configuration Command Register "Parity Error Response
6956 * Control" Bit was clear (0), then set the microcode variable
6957 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
6958 * to ignore DMA parity errors.
6960 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
6961 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
6962 word |= CONTROL_FLAG_IGNORE_PERR;
6963 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
6967 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
6968 * threshold of 128 bytes. This register is only accessible to the host.
6970 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
6971 START_CTL_EMFU | READ_CMD_MRM);
6974 * Microcode operating variables for WDTR, SDTR, and command tag
6975 * queuing will be set in slave_configure() based on what a
6976 * device reports it is capable of in Inquiry byte 7.
6978 * If SCSI Bus Resets have been disabled, then directly set
6979 * SDTR and WDTR from the EEPROM configuration. This will allow
6980 * the BIOS and warm boot to work without a SCSI bus hang on
6981 * the Inquiry caused by host and target mismatched DTR values.
6982 * Without the SCSI Bus Reset, before an Inquiry a device can't
6983 * be assumed to be in Asynchronous, Narrow mode.
6985 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
6986 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
6987 asc_dvc->wdtr_able);
6988 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
6989 asc_dvc->sdtr_able);
6993 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
6994 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
6995 * bitmask. These values determine the maximum SDTR speed negotiated
6996 * with a device.
6998 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
6999 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7000 * without determining here whether the device supports SDTR.
7002 * 4-bit speed SDTR speed name
7003 * =========== ===============
7004 * 0000b (0x0) SDTR disabled
7005 * 0001b (0x1) 5 Mhz
7006 * 0010b (0x2) 10 Mhz
7007 * 0011b (0x3) 20 Mhz (Ultra)
7008 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
7009 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
7010 * 0110b (0x6) Undefined
7012 * 1111b (0xF) Undefined
7014 word = 0;
7015 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7016 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
7017 /* Set Ultra speed for TID 'tid'. */
7018 word |= (0x3 << (4 * (tid % 4)));
7019 } else {
7020 /* Set Fast speed for TID 'tid'. */
7021 word |= (0x2 << (4 * (tid % 4)));
7023 if (tid == 3) { /* Check if done with sdtr_speed1. */
7024 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
7025 word = 0;
7026 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
7027 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
7028 word = 0;
7029 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
7030 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
7031 word = 0;
7032 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
7033 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
7034 /* End of loop. */
7039 * Set microcode operating variable for the disconnect per TID bitmask.
7041 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
7042 asc_dvc->cfg->disc_enable);
7045 * Set SCSI_CFG0 Microcode Default Value.
7047 * The microcode will set the SCSI_CFG0 register using this value
7048 * after it is started below.
7050 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
7051 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
7052 asc_dvc->chip_scsi_id);
7055 * Determine SCSI_CFG1 Microcode Default Value.
7057 * The microcode will set the SCSI_CFG1 register using this value
7058 * after it is started below.
7061 /* Read current SCSI_CFG1 Register value. */
7062 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7065 * If all three connectors are in use, return an error.
7067 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
7068 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
7069 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
7070 return ADV_ERROR;
7074 * If the internal narrow cable is reversed all of the SCSI_CTRL
7075 * register signals will be set. Check for and return an error if
7076 * this condition is found.
7078 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7079 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7080 return ADV_ERROR;
7084 * If this is a differential board and a single-ended device
7085 * is attached to one of the connectors, return an error.
7087 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
7088 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
7089 return ADV_ERROR;
7093 * If automatic termination control is enabled, then set the
7094 * termination value based on a table listed in a_condor.h.
7096 * If manual termination was specified with an EEPROM setting
7097 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
7098 * is ready to be 'ored' into SCSI_CFG1.
7100 if (asc_dvc->cfg->termination == 0) {
7102 * The software always controls termination by setting TERM_CTL_SEL.
7103 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
7105 asc_dvc->cfg->termination |= TERM_CTL_SEL;
7107 switch (scsi_cfg1 & CABLE_DETECT) {
7108 /* TERM_CTL_H: on, TERM_CTL_L: on */
7109 case 0x3:
7110 case 0x7:
7111 case 0xB:
7112 case 0xD:
7113 case 0xE:
7114 case 0xF:
7115 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
7116 break;
7118 /* TERM_CTL_H: on, TERM_CTL_L: off */
7119 case 0x1:
7120 case 0x5:
7121 case 0x9:
7122 case 0xA:
7123 case 0xC:
7124 asc_dvc->cfg->termination |= TERM_CTL_H;
7125 break;
7127 /* TERM_CTL_H: off, TERM_CTL_L: off */
7128 case 0x2:
7129 case 0x6:
7130 break;
7135 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
7137 scsi_cfg1 &= ~TERM_CTL;
7140 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
7141 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
7142 * referenced, because the hardware internally inverts
7143 * the Termination High and Low bits if TERM_POL is set.
7145 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
7148 * Set SCSI_CFG1 Microcode Default Value
7150 * Set filter value and possibly modified termination control
7151 * bits in the Microcode SCSI_CFG1 Register Value.
7153 * The microcode will set the SCSI_CFG1 register using this value
7154 * after it is started below.
7156 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
7157 FLTR_DISABLE | scsi_cfg1);
7160 * Set MEM_CFG Microcode Default Value
7162 * The microcode will set the MEM_CFG register using this value
7163 * after it is started below.
7165 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7166 * are defined.
7168 * ASC-3550 has 8KB internal memory.
7170 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7171 BIOS_EN | RAM_SZ_8KB);
7174 * Set SEL_MASK Microcode Default Value
7176 * The microcode will set the SEL_MASK register using this value
7177 * after it is started below.
7179 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7180 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7182 AdvBuildCarrierFreelist(asc_dvc);
7185 * Set-up the Host->RISC Initiator Command Queue (ICQ).
7188 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7189 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7190 return ADV_ERROR;
7192 asc_dvc->carr_freelist = (ADV_CARR_T *)
7193 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7196 * The first command issued will be placed in the stopper carrier.
7198 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7201 * Set RISC ICQ physical address start value.
7203 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7206 * Set-up the RISC->Host Initiator Response Queue (IRQ).
7208 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7209 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7210 return ADV_ERROR;
7212 asc_dvc->carr_freelist = (ADV_CARR_T *)
7213 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7216 * The first command completed by the RISC will be placed in
7217 * the stopper.
7219 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7220 * completed the RISC will set the ASC_RQ_STOPPER bit.
7222 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7225 * Set RISC IRQ physical address start value.
7227 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7228 asc_dvc->carr_pending_cnt = 0;
7230 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7231 (ADV_INTR_ENABLE_HOST_INTR |
7232 ADV_INTR_ENABLE_GLOBAL_INTR));
7234 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7235 AdvWriteWordRegister(iop_base, IOPW_PC, word);
7237 /* finally, finally, gentlemen, start your engine */
7238 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7241 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7242 * Resets should be performed. The RISC has to be running
7243 * to issue a SCSI Bus Reset.
7245 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7247 * If the BIOS Signature is present in memory, restore the
7248 * BIOS Handshake Configuration Table and do not perform
7249 * a SCSI Bus Reset.
7251 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7252 0x55AA) {
7254 * Restore per TID negotiated values.
7256 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7257 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7258 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7259 tagqng_able);
7260 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7261 AdvWriteByteLram(iop_base,
7262 ASC_MC_NUMBER_OF_MAX_CMD + tid,
7263 max_cmd[tid]);
7265 } else {
7266 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7267 warn_code = ASC_WARN_BUSRESET_ERROR;
7272 return warn_code;
7276 * Initialize the ASC-38C0800.
7278 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
7280 * For a non-fatal error return a warning code. If there are no warnings
7281 * then 0 is returned.
7283 * Needed after initialization for error recovery.
7285 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
7287 AdvPortAddr iop_base;
7288 ushort warn_code;
7289 int begin_addr;
7290 int end_addr;
7291 ushort code_sum;
7292 int word;
7293 int i;
7294 ushort scsi_cfg1;
7295 uchar byte;
7296 uchar tid;
7297 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
7298 ushort wdtr_able, sdtr_able, tagqng_able;
7299 uchar max_cmd[ADV_MAX_TID + 1];
7301 /* If there is already an error, don't continue. */
7302 if (asc_dvc->err_code != 0)
7303 return ADV_ERROR;
7306 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
7308 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
7309 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7310 return ADV_ERROR;
7313 warn_code = 0;
7314 iop_base = asc_dvc->iop_base;
7317 * Save the RISC memory BIOS region before writing the microcode.
7318 * The BIOS may already be loaded and using its RISC LRAM region
7319 * so its region must be saved and restored.
7321 * Note: This code makes the assumption, which is currently true,
7322 * that a chip reset does not clear RISC LRAM.
7324 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7325 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7326 bios_mem[i]);
7330 * Save current per TID negotiated values.
7332 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7333 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7334 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7335 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7336 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
7337 max_cmd[tid]);
7341 * RAM BIST (RAM Built-In Self Test)
7343 * Address : I/O base + offset 0x38h register (byte).
7344 * Function: Bit 7-6(RW) : RAM mode
7345 * Normal Mode : 0x00
7346 * Pre-test Mode : 0x40
7347 * RAM Test Mode : 0x80
7348 * Bit 5 : unused
7349 * Bit 4(RO) : Done bit
7350 * Bit 3-0(RO) : Status
7351 * Host Error : 0x08
7352 * Int_RAM Error : 0x04
7353 * RISC Error : 0x02
7354 * SCSI Error : 0x01
7355 * No Error : 0x00
7357 * Note: RAM BIST code should be put right here, before loading the
7358 * microcode and after saving the RISC memory BIOS region.
7362 * LRAM Pre-test
7364 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
7365 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
7366 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
7367 * to NORMAL_MODE, return an error too.
7369 for (i = 0; i < 2; i++) {
7370 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
7371 mdelay(10); /* Wait for 10ms before reading back. */
7372 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7373 if ((byte & RAM_TEST_DONE) == 0
7374 || (byte & 0x0F) != PRE_TEST_VALUE) {
7375 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7376 return ADV_ERROR;
7379 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7380 mdelay(10); /* Wait for 10ms before reading back. */
7381 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
7382 != NORMAL_VALUE) {
7383 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7384 return ADV_ERROR;
7389 * LRAM Test - It takes about 1.5 ms to run through the test.
7391 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
7392 * If Done bit not set or Status not 0, save register byte, set the
7393 * err_code, and return an error.
7395 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7396 mdelay(10); /* Wait for 10ms before checking status. */
7398 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7399 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
7400 /* Get here if Done bit not set or Status not 0. */
7401 asc_dvc->bist_err_code = byte; /* for BIOS display message */
7402 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
7403 return ADV_ERROR;
7406 /* We need to reset back to normal mode after LRAM test passes. */
7407 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7409 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf,
7410 _adv_asc38C0800_size, ADV_38C0800_MEMSIZE,
7411 _adv_asc38C0800_chksum);
7412 if (asc_dvc->err_code)
7413 return ADV_ERROR;
7416 * Restore the RISC memory BIOS region.
7418 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7419 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7420 bios_mem[i]);
7424 * Calculate and write the microcode code checksum to the microcode
7425 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7427 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
7428 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
7429 code_sum = 0;
7430 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
7431 for (word = begin_addr; word < end_addr; word += 2) {
7432 code_sum += AdvReadWordAutoIncLram(iop_base);
7434 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7437 * Read microcode version and date.
7439 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
7440 asc_dvc->cfg->mcode_date);
7441 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
7442 asc_dvc->cfg->mcode_version);
7445 * Set the chip type to indicate the ASC38C0800.
7447 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
7450 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
7451 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
7452 * cable detection and then we are able to read C_DET[3:0].
7454 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7455 * Microcode Default Value' section below.
7457 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7458 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7459 scsi_cfg1 | DIS_TERM_DRV);
7462 * If the PCI Configuration Command Register "Parity Error Response
7463 * Control" Bit was clear (0), then set the microcode variable
7464 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
7465 * to ignore DMA parity errors.
7467 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
7468 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7469 word |= CONTROL_FLAG_IGNORE_PERR;
7470 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7474 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
7475 * bits for the default FIFO threshold.
7477 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
7479 * For DMA Errata #4 set the BC_THRESH_ENB bit.
7481 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7482 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
7483 READ_CMD_MRM);
7486 * Microcode operating variables for WDTR, SDTR, and command tag
7487 * queuing will be set in slave_configure() based on what a
7488 * device reports it is capable of in Inquiry byte 7.
7490 * If SCSI Bus Resets have been disabled, then directly set
7491 * SDTR and WDTR from the EEPROM configuration. This will allow
7492 * the BIOS and warm boot to work without a SCSI bus hang on
7493 * the Inquiry caused by host and target mismatched DTR values.
7494 * Without the SCSI Bus Reset, before an Inquiry a device can't
7495 * be assumed to be in Asynchronous, Narrow mode.
7497 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
7498 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
7499 asc_dvc->wdtr_able);
7500 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
7501 asc_dvc->sdtr_able);
7505 * Set microcode operating variables for DISC and SDTR_SPEED1,
7506 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
7507 * configuration values.
7509 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
7510 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7511 * without determining here whether the device supports SDTR.
7513 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
7514 asc_dvc->cfg->disc_enable);
7515 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
7516 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
7517 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
7518 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
7521 * Set SCSI_CFG0 Microcode Default Value.
7523 * The microcode will set the SCSI_CFG0 register using this value
7524 * after it is started below.
7526 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
7527 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
7528 asc_dvc->chip_scsi_id);
7531 * Determine SCSI_CFG1 Microcode Default Value.
7533 * The microcode will set the SCSI_CFG1 register using this value
7534 * after it is started below.
7537 /* Read current SCSI_CFG1 Register value. */
7538 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7541 * If the internal narrow cable is reversed all of the SCSI_CTRL
7542 * register signals will be set. Check for and return an error if
7543 * this condition is found.
7545 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7546 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7547 return ADV_ERROR;
7551 * All kind of combinations of devices attached to one of four
7552 * connectors are acceptable except HVD device attached. For example,
7553 * LVD device can be attached to SE connector while SE device attached
7554 * to LVD connector. If LVD device attached to SE connector, it only
7555 * runs up to Ultra speed.
7557 * If an HVD device is attached to one of LVD connectors, return an
7558 * error. However, there is no way to detect HVD device attached to
7559 * SE connectors.
7561 if (scsi_cfg1 & HVD) {
7562 asc_dvc->err_code = ASC_IERR_HVD_DEVICE;
7563 return ADV_ERROR;
7567 * If either SE or LVD automatic termination control is enabled, then
7568 * set the termination value based on a table listed in a_condor.h.
7570 * If manual termination was specified with an EEPROM setting then
7571 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready
7572 * to be 'ored' into SCSI_CFG1.
7574 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
7575 /* SE automatic termination control is enabled. */
7576 switch (scsi_cfg1 & C_DET_SE) {
7577 /* TERM_SE_HI: on, TERM_SE_LO: on */
7578 case 0x1:
7579 case 0x2:
7580 case 0x3:
7581 asc_dvc->cfg->termination |= TERM_SE;
7582 break;
7584 /* TERM_SE_HI: on, TERM_SE_LO: off */
7585 case 0x0:
7586 asc_dvc->cfg->termination |= TERM_SE_HI;
7587 break;
7591 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
7592 /* LVD automatic termination control is enabled. */
7593 switch (scsi_cfg1 & C_DET_LVD) {
7594 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
7595 case 0x4:
7596 case 0x8:
7597 case 0xC:
7598 asc_dvc->cfg->termination |= TERM_LVD;
7599 break;
7601 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
7602 case 0x0:
7603 break;
7608 * Clear any set TERM_SE and TERM_LVD bits.
7610 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
7613 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
7615 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
7618 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE
7619 * bits and set possibly modified termination control bits in the
7620 * Microcode SCSI_CFG1 Register Value.
7622 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
7625 * Set SCSI_CFG1 Microcode Default Value
7627 * Set possibly modified termination control and reset DIS_TERM_DRV
7628 * bits in the Microcode SCSI_CFG1 Register Value.
7630 * The microcode will set the SCSI_CFG1 register using this value
7631 * after it is started below.
7633 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
7636 * Set MEM_CFG Microcode Default Value
7638 * The microcode will set the MEM_CFG register using this value
7639 * after it is started below.
7641 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7642 * are defined.
7644 * ASC-38C0800 has 16KB internal memory.
7646 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7647 BIOS_EN | RAM_SZ_16KB);
7650 * Set SEL_MASK Microcode Default Value
7652 * The microcode will set the SEL_MASK register using this value
7653 * after it is started below.
7655 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7656 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7658 AdvBuildCarrierFreelist(asc_dvc);
7661 * Set-up the Host->RISC Initiator Command Queue (ICQ).
7664 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7665 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7666 return ADV_ERROR;
7668 asc_dvc->carr_freelist = (ADV_CARR_T *)
7669 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7672 * The first command issued will be placed in the stopper carrier.
7674 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7677 * Set RISC ICQ physical address start value.
7678 * carr_pa is LE, must be native before write
7680 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7683 * Set-up the RISC->Host Initiator Response Queue (IRQ).
7685 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7686 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7687 return ADV_ERROR;
7689 asc_dvc->carr_freelist = (ADV_CARR_T *)
7690 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7693 * The first command completed by the RISC will be placed in
7694 * the stopper.
7696 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7697 * completed the RISC will set the ASC_RQ_STOPPER bit.
7699 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7702 * Set RISC IRQ physical address start value.
7704 * carr_pa is LE, must be native before write *
7706 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7707 asc_dvc->carr_pending_cnt = 0;
7709 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7710 (ADV_INTR_ENABLE_HOST_INTR |
7711 ADV_INTR_ENABLE_GLOBAL_INTR));
7713 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7714 AdvWriteWordRegister(iop_base, IOPW_PC, word);
7716 /* finally, finally, gentlemen, start your engine */
7717 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7720 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7721 * Resets should be performed. The RISC has to be running
7722 * to issue a SCSI Bus Reset.
7724 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7726 * If the BIOS Signature is present in memory, restore the
7727 * BIOS Handshake Configuration Table and do not perform
7728 * a SCSI Bus Reset.
7730 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7731 0x55AA) {
7733 * Restore per TID negotiated values.
7735 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7736 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7737 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7738 tagqng_able);
7739 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7740 AdvWriteByteLram(iop_base,
7741 ASC_MC_NUMBER_OF_MAX_CMD + tid,
7742 max_cmd[tid]);
7744 } else {
7745 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7746 warn_code = ASC_WARN_BUSRESET_ERROR;
7751 return warn_code;
7755 * Initialize the ASC-38C1600.
7757 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
7759 * For a non-fatal error return a warning code. If there are no warnings
7760 * then 0 is returned.
7762 * Needed after initialization for error recovery.
7764 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
7766 AdvPortAddr iop_base;
7767 ushort warn_code;
7768 int begin_addr;
7769 int end_addr;
7770 ushort code_sum;
7771 long word;
7772 int i;
7773 ushort scsi_cfg1;
7774 uchar byte;
7775 uchar tid;
7776 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
7777 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
7778 uchar max_cmd[ASC_MAX_TID + 1];
7780 /* If there is already an error, don't continue. */
7781 if (asc_dvc->err_code != 0) {
7782 return ADV_ERROR;
7786 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
7788 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
7789 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7790 return ADV_ERROR;
7793 warn_code = 0;
7794 iop_base = asc_dvc->iop_base;
7797 * Save the RISC memory BIOS region before writing the microcode.
7798 * The BIOS may already be loaded and using its RISC LRAM region
7799 * so its region must be saved and restored.
7801 * Note: This code makes the assumption, which is currently true,
7802 * that a chip reset does not clear RISC LRAM.
7804 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7805 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7806 bios_mem[i]);
7810 * Save current per TID negotiated values.
7812 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7813 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7814 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
7815 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7816 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
7817 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
7818 max_cmd[tid]);
7822 * RAM BIST (Built-In Self Test)
7824 * Address : I/O base + offset 0x38h register (byte).
7825 * Function: Bit 7-6(RW) : RAM mode
7826 * Normal Mode : 0x00
7827 * Pre-test Mode : 0x40
7828 * RAM Test Mode : 0x80
7829 * Bit 5 : unused
7830 * Bit 4(RO) : Done bit
7831 * Bit 3-0(RO) : Status
7832 * Host Error : 0x08
7833 * Int_RAM Error : 0x04
7834 * RISC Error : 0x02
7835 * SCSI Error : 0x01
7836 * No Error : 0x00
7838 * Note: RAM BIST code should be put right here, before loading the
7839 * microcode and after saving the RISC memory BIOS region.
7843 * LRAM Pre-test
7845 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
7846 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
7847 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
7848 * to NORMAL_MODE, return an error too.
7850 for (i = 0; i < 2; i++) {
7851 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
7852 mdelay(10); /* Wait for 10ms before reading back. */
7853 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7854 if ((byte & RAM_TEST_DONE) == 0
7855 || (byte & 0x0F) != PRE_TEST_VALUE) {
7856 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7857 return ADV_ERROR;
7860 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7861 mdelay(10); /* Wait for 10ms before reading back. */
7862 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
7863 != NORMAL_VALUE) {
7864 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7865 return ADV_ERROR;
7870 * LRAM Test - It takes about 1.5 ms to run through the test.
7872 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
7873 * If Done bit not set or Status not 0, save register byte, set the
7874 * err_code, and return an error.
7876 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7877 mdelay(10); /* Wait for 10ms before checking status. */
7879 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7880 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
7881 /* Get here if Done bit not set or Status not 0. */
7882 asc_dvc->bist_err_code = byte; /* for BIOS display message */
7883 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
7884 return ADV_ERROR;
7887 /* We need to reset back to normal mode after LRAM test passes. */
7888 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7890 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf,
7891 _adv_asc38C1600_size, ADV_38C1600_MEMSIZE,
7892 _adv_asc38C1600_chksum);
7893 if (asc_dvc->err_code)
7894 return ADV_ERROR;
7897 * Restore the RISC memory BIOS region.
7899 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7900 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7901 bios_mem[i]);
7905 * Calculate and write the microcode code checksum to the microcode
7906 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7908 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
7909 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
7910 code_sum = 0;
7911 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
7912 for (word = begin_addr; word < end_addr; word += 2) {
7913 code_sum += AdvReadWordAutoIncLram(iop_base);
7915 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7918 * Read microcode version and date.
7920 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
7921 asc_dvc->cfg->mcode_date);
7922 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
7923 asc_dvc->cfg->mcode_version);
7926 * Set the chip type to indicate the ASC38C1600.
7928 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
7931 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
7932 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
7933 * cable detection and then we are able to read C_DET[3:0].
7935 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7936 * Microcode Default Value' section below.
7938 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7939 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7940 scsi_cfg1 | DIS_TERM_DRV);
7943 * If the PCI Configuration Command Register "Parity Error Response
7944 * Control" Bit was clear (0), then set the microcode variable
7945 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
7946 * to ignore DMA parity errors.
7948 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
7949 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7950 word |= CONTROL_FLAG_IGNORE_PERR;
7951 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7955 * If the BIOS control flag AIPP (Asynchronous Information
7956 * Phase Protection) disable bit is not set, then set the firmware
7957 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
7958 * AIPP checking and encoding.
7960 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
7961 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7962 word |= CONTROL_FLAG_ENABLE_AIPP;
7963 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7967 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
7968 * and START_CTL_TH [3:2].
7970 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7971 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
7974 * Microcode operating variables for WDTR, SDTR, and command tag
7975 * queuing will be set in slave_configure() based on what a
7976 * device reports it is capable of in Inquiry byte 7.
7978 * If SCSI Bus Resets have been disabled, then directly set
7979 * SDTR and WDTR from the EEPROM configuration. This will allow
7980 * the BIOS and warm boot to work without a SCSI bus hang on
7981 * the Inquiry caused by host and target mismatched DTR values.
7982 * Without the SCSI Bus Reset, before an Inquiry a device can't
7983 * be assumed to be in Asynchronous, Narrow mode.
7985 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
7986 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
7987 asc_dvc->wdtr_able);
7988 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
7989 asc_dvc->sdtr_able);
7993 * Set microcode operating variables for DISC and SDTR_SPEED1,
7994 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
7995 * configuration values.
7997 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
7998 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7999 * without determining here whether the device supports SDTR.
8001 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
8002 asc_dvc->cfg->disc_enable);
8003 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
8004 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
8005 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
8006 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
8009 * Set SCSI_CFG0 Microcode Default Value.
8011 * The microcode will set the SCSI_CFG0 register using this value
8012 * after it is started below.
8014 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
8015 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
8016 asc_dvc->chip_scsi_id);
8019 * Calculate SCSI_CFG1 Microcode Default Value.
8021 * The microcode will set the SCSI_CFG1 register using this value
8022 * after it is started below.
8024 * Each ASC-38C1600 function has only two cable detect bits.
8025 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
8027 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
8030 * If the cable is reversed all of the SCSI_CTRL register signals
8031 * will be set. Check for and return an error if this condition is
8032 * found.
8034 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
8035 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
8036 return ADV_ERROR;
8040 * Each ASC-38C1600 function has two connectors. Only an HVD device
8041 * can not be connected to either connector. An LVD device or SE device
8042 * may be connected to either connecor. If an SE device is connected,
8043 * then at most Ultra speed (20 Mhz) can be used on both connectors.
8045 * If an HVD device is attached, return an error.
8047 if (scsi_cfg1 & HVD) {
8048 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
8049 return ADV_ERROR;
8053 * Each function in the ASC-38C1600 uses only the SE cable detect and
8054 * termination because there are two connectors for each function. Each
8055 * function may use either LVD or SE mode. Corresponding the SE automatic
8056 * termination control EEPROM bits are used for each function. Each
8057 * function has its own EEPROM. If SE automatic control is enabled for
8058 * the function, then set the termination value based on a table listed
8059 * in a_condor.h.
8061 * If manual termination is specified in the EEPROM for the function,
8062 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
8063 * ready to be 'ored' into SCSI_CFG1.
8065 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
8066 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
8067 /* SE automatic termination control is enabled. */
8068 switch (scsi_cfg1 & C_DET_SE) {
8069 /* TERM_SE_HI: on, TERM_SE_LO: on */
8070 case 0x1:
8071 case 0x2:
8072 case 0x3:
8073 asc_dvc->cfg->termination |= TERM_SE;
8074 break;
8076 case 0x0:
8077 if (PCI_FUNC(pdev->devfn) == 0) {
8078 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
8079 } else {
8080 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
8081 asc_dvc->cfg->termination |= TERM_SE_HI;
8083 break;
8088 * Clear any set TERM_SE bits.
8090 scsi_cfg1 &= ~TERM_SE;
8093 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
8095 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
8098 * Clear Big Endian and Terminator Polarity bits and set possibly
8099 * modified termination control bits in the Microcode SCSI_CFG1
8100 * Register Value.
8102 * Big Endian bit is not used even on big endian machines.
8104 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
8107 * Set SCSI_CFG1 Microcode Default Value
8109 * Set possibly modified termination control bits in the Microcode
8110 * SCSI_CFG1 Register Value.
8112 * The microcode will set the SCSI_CFG1 register using this value
8113 * after it is started below.
8115 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
8118 * Set MEM_CFG Microcode Default Value
8120 * The microcode will set the MEM_CFG register using this value
8121 * after it is started below.
8123 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
8124 * are defined.
8126 * ASC-38C1600 has 32KB internal memory.
8128 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
8129 * out a special 16K Adv Library and Microcode version. After the issue
8130 * resolved, we should turn back to the 32K support. Both a_condor.h and
8131 * mcode.sas files also need to be updated.
8133 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
8134 * BIOS_EN | RAM_SZ_32KB);
8136 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
8137 BIOS_EN | RAM_SZ_16KB);
8140 * Set SEL_MASK Microcode Default Value
8142 * The microcode will set the SEL_MASK register using this value
8143 * after it is started below.
8145 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
8146 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
8148 AdvBuildCarrierFreelist(asc_dvc);
8151 * Set-up the Host->RISC Initiator Command Queue (ICQ).
8153 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
8154 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
8155 return ADV_ERROR;
8157 asc_dvc->carr_freelist = (ADV_CARR_T *)
8158 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
8161 * The first command issued will be placed in the stopper carrier.
8163 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
8166 * Set RISC ICQ physical address start value. Initialize the
8167 * COMMA register to the same value otherwise the RISC will
8168 * prematurely detect a command is available.
8170 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
8171 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
8172 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
8175 * Set-up the RISC->Host Initiator Response Queue (IRQ).
8177 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
8178 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
8179 return ADV_ERROR;
8181 asc_dvc->carr_freelist = (ADV_CARR_T *)
8182 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
8185 * The first command completed by the RISC will be placed in
8186 * the stopper.
8188 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
8189 * completed the RISC will set the ASC_RQ_STOPPER bit.
8191 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
8194 * Set RISC IRQ physical address start value.
8196 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
8197 asc_dvc->carr_pending_cnt = 0;
8199 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
8200 (ADV_INTR_ENABLE_HOST_INTR |
8201 ADV_INTR_ENABLE_GLOBAL_INTR));
8202 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
8203 AdvWriteWordRegister(iop_base, IOPW_PC, word);
8205 /* finally, finally, gentlemen, start your engine */
8206 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
8209 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
8210 * Resets should be performed. The RISC has to be running
8211 * to issue a SCSI Bus Reset.
8213 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
8215 * If the BIOS Signature is present in memory, restore the
8216 * per TID microcode operating variables.
8218 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
8219 0x55AA) {
8221 * Restore per TID negotiated values.
8223 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8224 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8225 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8226 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
8227 tagqng_able);
8228 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
8229 AdvWriteByteLram(iop_base,
8230 ASC_MC_NUMBER_OF_MAX_CMD + tid,
8231 max_cmd[tid]);
8233 } else {
8234 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
8235 warn_code = ASC_WARN_BUSRESET_ERROR;
8240 return warn_code;
8244 * Reset chip and SCSI Bus.
8246 * Return Value:
8247 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
8248 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
8250 static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
8252 int status;
8253 ushort wdtr_able, sdtr_able, tagqng_able;
8254 ushort ppr_able = 0;
8255 uchar tid, max_cmd[ADV_MAX_TID + 1];
8256 AdvPortAddr iop_base;
8257 ushort bios_sig;
8259 iop_base = asc_dvc->iop_base;
8262 * Save current per TID negotiated values.
8264 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8265 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8266 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8267 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8269 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8270 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
8271 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
8272 max_cmd[tid]);
8276 * Force the AdvInitAsc3550/38C0800Driver() function to
8277 * perform a SCSI Bus Reset by clearing the BIOS signature word.
8278 * The initialization functions assumes a SCSI Bus Reset is not
8279 * needed if the BIOS signature word is present.
8281 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8282 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
8285 * Stop chip and reset it.
8287 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
8288 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
8289 mdelay(100);
8290 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
8291 ADV_CTRL_REG_CMD_WR_IO_REG);
8294 * Reset Adv Library error code, if any, and try
8295 * re-initializing the chip.
8297 asc_dvc->err_code = 0;
8298 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8299 status = AdvInitAsc38C1600Driver(asc_dvc);
8300 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8301 status = AdvInitAsc38C0800Driver(asc_dvc);
8302 } else {
8303 status = AdvInitAsc3550Driver(asc_dvc);
8306 /* Translate initialization return value to status value. */
8307 if (status == 0) {
8308 status = ADV_TRUE;
8309 } else {
8310 status = ADV_FALSE;
8314 * Restore the BIOS signature word.
8316 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8319 * Restore per TID negotiated values.
8321 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8322 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8323 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8324 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8326 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8327 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
8328 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
8329 max_cmd[tid]);
8332 return status;
8336 * adv_async_callback() - Adv Library asynchronous event callback function.
8338 static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
8340 switch (code) {
8341 case ADV_ASYNC_SCSI_BUS_RESET_DET:
8343 * The firmware detected a SCSI Bus reset.
8345 ASC_DBG(0,
8346 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
8347 break;
8349 case ADV_ASYNC_RDMA_FAILURE:
8351 * Handle RDMA failure by resetting the SCSI Bus and
8352 * possibly the chip if it is unresponsive. Log the error
8353 * with a unique code.
8355 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
8356 AdvResetChipAndSB(adv_dvc_varp);
8357 break;
8359 case ADV_HOST_SCSI_BUS_RESET:
8361 * Host generated SCSI bus reset occurred.
8363 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
8364 break;
8366 default:
8367 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
8368 break;
8373 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
8375 * Callback function for the Wide SCSI Adv Library.
8377 static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
8379 asc_board_t *boardp;
8380 adv_req_t *reqp;
8381 adv_sgblk_t *sgblkp;
8382 struct scsi_cmnd *scp;
8383 struct Scsi_Host *shost;
8384 ADV_DCNT resid_cnt;
8386 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
8387 (ulong)adv_dvc_varp, (ulong)scsiqp);
8388 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
8391 * Get the adv_req_t structure for the command that has been
8392 * completed. The adv_req_t structure actually contains the
8393 * completed ADV_SCSI_REQ_Q structure.
8395 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
8396 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
8397 if (reqp == NULL) {
8398 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
8399 return;
8403 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
8404 * command that has been completed.
8406 * Note: The adv_req_t request structure and adv_sgblk_t structure,
8407 * if any, are dropped, because a board structure pointer can not be
8408 * determined.
8410 scp = reqp->cmndp;
8411 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
8412 if (scp == NULL) {
8413 ASC_PRINT
8414 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
8415 return;
8417 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
8419 shost = scp->device->host;
8420 ASC_STATS(shost, callback);
8421 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
8423 boardp = ASC_BOARDP(shost);
8424 BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var);
8427 * 'done_status' contains the command's ending status.
8429 switch (scsiqp->done_status) {
8430 case QD_NO_ERROR:
8431 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
8432 scp->result = 0;
8435 * Check for an underrun condition.
8437 * If there was no error and an underrun condition, then
8438 * then return the number of underrun bytes.
8440 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
8441 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
8442 resid_cnt <= scp->request_bufflen) {
8443 ASC_DBG1(1,
8444 "adv_isr_callback: underrun condition %lu bytes\n",
8445 (ulong)resid_cnt);
8446 scp->resid = resid_cnt;
8448 break;
8450 case QD_WITH_ERROR:
8451 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
8452 switch (scsiqp->host_status) {
8453 case QHSTA_NO_ERROR:
8454 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
8455 ASC_DBG(2,
8456 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
8457 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
8458 sizeof(scp->sense_buffer));
8460 * Note: The 'status_byte()' macro used by
8461 * target drivers defined in scsi.h shifts the
8462 * status byte returned by host drivers right
8463 * by 1 bit. This is why target drivers also
8464 * use right shifted status byte definitions.
8465 * For instance target drivers use
8466 * CHECK_CONDITION, defined to 0x1, instead of
8467 * the SCSI defined check condition value of
8468 * 0x2. Host drivers are supposed to return
8469 * the status byte as it is defined by SCSI.
8471 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
8472 STATUS_BYTE(scsiqp->scsi_status);
8473 } else {
8474 scp->result = STATUS_BYTE(scsiqp->scsi_status);
8476 break;
8478 default:
8479 /* Some other QHSTA error occurred. */
8480 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
8481 scsiqp->host_status);
8482 scp->result = HOST_BYTE(DID_BAD_TARGET);
8483 break;
8485 break;
8487 case QD_ABORTED_BY_HOST:
8488 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
8489 scp->result =
8490 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
8491 break;
8493 default:
8494 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
8495 scsiqp->done_status);
8496 scp->result =
8497 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
8498 break;
8502 * If the 'init_tidmask' bit isn't already set for the target and the
8503 * current request finished normally, then set the bit for the target
8504 * to indicate that a device is present.
8506 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
8507 scsiqp->done_status == QD_NO_ERROR &&
8508 scsiqp->host_status == QHSTA_NO_ERROR) {
8509 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
8512 asc_scsi_done(scp);
8515 * Free all 'adv_sgblk_t' structures allocated for the request.
8517 while ((sgblkp = reqp->sgblkp) != NULL) {
8518 /* Remove 'sgblkp' from the request list. */
8519 reqp->sgblkp = sgblkp->next_sgblkp;
8521 /* Add 'sgblkp' to the board free list. */
8522 sgblkp->next_sgblkp = boardp->adv_sgblkp;
8523 boardp->adv_sgblkp = sgblkp;
8527 * Free the adv_req_t structure used with the command by adding
8528 * it back to the board free list.
8530 reqp->next_reqp = boardp->adv_reqp;
8531 boardp->adv_reqp = reqp;
8533 ASC_DBG(1, "adv_isr_callback: done\n");
8535 return;
8539 * Adv Library Interrupt Service Routine
8541 * This function is called by a driver's interrupt service routine.
8542 * The function disables and re-enables interrupts.
8544 * When a microcode idle command is completed, the ADV_DVC_VAR
8545 * 'idle_cmd_done' field is set to ADV_TRUE.
8547 * Note: AdvISR() can be called when interrupts are disabled or even
8548 * when there is no hardware interrupt condition present. It will
8549 * always check for completed idle commands and microcode requests.
8550 * This is an important feature that shouldn't be changed because it
8551 * allows commands to be completed from polling mode loops.
8553 * Return:
8554 * ADV_TRUE(1) - interrupt was pending
8555 * ADV_FALSE(0) - no interrupt was pending
8557 static int AdvISR(ADV_DVC_VAR *asc_dvc)
8559 AdvPortAddr iop_base;
8560 uchar int_stat;
8561 ushort target_bit;
8562 ADV_CARR_T *free_carrp;
8563 ADV_VADDR irq_next_vpa;
8564 ADV_SCSI_REQ_Q *scsiq;
8566 iop_base = asc_dvc->iop_base;
8568 /* Reading the register clears the interrupt. */
8569 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
8571 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
8572 ADV_INTR_STATUS_INTRC)) == 0) {
8573 return ADV_FALSE;
8577 * Notify the driver of an asynchronous microcode condition by
8578 * calling the adv_async_callback function. The function
8579 * is passed the microcode ASC_MC_INTRB_CODE byte value.
8581 if (int_stat & ADV_INTR_STATUS_INTRB) {
8582 uchar intrb_code;
8584 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
8586 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
8587 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8588 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
8589 asc_dvc->carr_pending_cnt != 0) {
8590 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
8591 ADV_TICKLE_A);
8592 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
8593 AdvWriteByteRegister(iop_base,
8594 IOPB_TICKLE,
8595 ADV_TICKLE_NOP);
8600 adv_async_callback(asc_dvc, intrb_code);
8604 * Check if the IRQ stopper carrier contains a completed request.
8606 while (((irq_next_vpa =
8607 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
8609 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
8610 * The RISC will have set 'areq_vpa' to a virtual address.
8612 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
8613 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
8614 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
8615 * in AdvExeScsiQueue().
8617 scsiq = (ADV_SCSI_REQ_Q *)
8618 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
8621 * Request finished with good status and the queue was not
8622 * DMAed to host memory by the firmware. Set all status fields
8623 * to indicate good status.
8625 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
8626 scsiq->done_status = QD_NO_ERROR;
8627 scsiq->host_status = scsiq->scsi_status = 0;
8628 scsiq->data_cnt = 0L;
8632 * Advance the stopper pointer to the next carrier
8633 * ignoring the lower four bits. Free the previous
8634 * stopper carrier.
8636 free_carrp = asc_dvc->irq_sp;
8637 asc_dvc->irq_sp = (ADV_CARR_T *)
8638 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
8640 free_carrp->next_vpa =
8641 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
8642 asc_dvc->carr_freelist = free_carrp;
8643 asc_dvc->carr_pending_cnt--;
8645 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
8648 * Clear request microcode control flag.
8650 scsiq->cntl = 0;
8653 * Notify the driver of the completed request by passing
8654 * the ADV_SCSI_REQ_Q pointer to its callback function.
8656 scsiq->a_flag |= ADV_SCSIQ_DONE;
8657 adv_isr_callback(asc_dvc, scsiq);
8659 * Note: After the driver callback function is called, 'scsiq'
8660 * can no longer be referenced.
8662 * Fall through and continue processing other completed
8663 * requests...
8666 return ADV_TRUE;
8669 static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
8671 if (asc_dvc->err_code == 0) {
8672 asc_dvc->err_code = err_code;
8673 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
8674 err_code);
8676 return err_code;
8679 static void AscAckInterrupt(PortAddr iop_base)
8681 uchar host_flag;
8682 uchar risc_flag;
8683 ushort loop;
8685 loop = 0;
8686 do {
8687 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
8688 if (loop++ > 0x7FFF) {
8689 break;
8691 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
8692 host_flag =
8693 AscReadLramByte(iop_base,
8694 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
8695 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8696 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
8697 AscSetChipStatus(iop_base, CIW_INT_ACK);
8698 loop = 0;
8699 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
8700 AscSetChipStatus(iop_base, CIW_INT_ACK);
8701 if (loop++ > 3) {
8702 break;
8705 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8706 return;
8709 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
8711 uchar *period_table;
8712 int max_index;
8713 int min_index;
8714 int i;
8716 period_table = asc_dvc->sdtr_period_tbl;
8717 max_index = (int)asc_dvc->max_sdtr_index;
8718 min_index = (int)asc_dvc->host_init_sdtr_index;
8719 if ((syn_time <= period_table[max_index])) {
8720 for (i = min_index; i < (max_index - 1); i++) {
8721 if (syn_time <= period_table[i]) {
8722 return (uchar)i;
8725 return (uchar)max_index;
8726 } else {
8727 return (uchar)(max_index + 1);
8731 static uchar
8732 AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
8734 EXT_MSG sdtr_buf;
8735 uchar sdtr_period_index;
8736 PortAddr iop_base;
8738 iop_base = asc_dvc->iop_base;
8739 sdtr_buf.msg_type = EXTENDED_MESSAGE;
8740 sdtr_buf.msg_len = MS_SDTR_LEN;
8741 sdtr_buf.msg_req = EXTENDED_SDTR;
8742 sdtr_buf.xfer_period = sdtr_period;
8743 sdtr_offset &= ASC_SYN_MAX_OFFSET;
8744 sdtr_buf.req_ack_offset = sdtr_offset;
8745 sdtr_period_index = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8746 if (sdtr_period_index <= asc_dvc->max_sdtr_index) {
8747 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
8748 (uchar *)&sdtr_buf,
8749 sizeof(EXT_MSG) >> 1);
8750 return ((sdtr_period_index << 4) | sdtr_offset);
8751 } else {
8752 sdtr_buf.req_ack_offset = 0;
8753 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
8754 (uchar *)&sdtr_buf,
8755 sizeof(EXT_MSG) >> 1);
8756 return 0;
8760 static uchar
8761 AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
8763 uchar byte;
8764 uchar sdtr_period_ix;
8766 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8767 if (sdtr_period_ix > asc_dvc->max_sdtr_index) {
8768 return 0xFF;
8770 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
8771 return byte;
8774 static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
8776 ASC_SCSI_BIT_ID_TYPE org_id;
8777 int i;
8778 int sta = TRUE;
8780 AscSetBank(iop_base, 1);
8781 org_id = AscReadChipDvcID(iop_base);
8782 for (i = 0; i <= ASC_MAX_TID; i++) {
8783 if (org_id == (0x01 << i))
8784 break;
8786 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
8787 AscWriteChipDvcID(iop_base, id);
8788 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
8789 AscSetBank(iop_base, 0);
8790 AscSetChipSyn(iop_base, sdtr_data);
8791 if (AscGetChipSyn(iop_base) != sdtr_data) {
8792 sta = FALSE;
8794 } else {
8795 sta = FALSE;
8797 AscSetBank(iop_base, 1);
8798 AscWriteChipDvcID(iop_base, org_id);
8799 AscSetBank(iop_base, 0);
8800 return (sta);
8803 static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
8805 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
8806 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
8809 static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8811 EXT_MSG ext_msg;
8812 EXT_MSG out_msg;
8813 ushort halt_q_addr;
8814 int sdtr_accept;
8815 ushort int_halt_code;
8816 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8817 ASC_SCSI_BIT_ID_TYPE target_id;
8818 PortAddr iop_base;
8819 uchar tag_code;
8820 uchar q_status;
8821 uchar halt_qp;
8822 uchar sdtr_data;
8823 uchar target_ix;
8824 uchar q_cntl, tid_no;
8825 uchar cur_dvc_qng;
8826 uchar asyn_sdtr;
8827 uchar scsi_status;
8828 asc_board_t *boardp;
8830 BUG_ON(!asc_dvc->drv_ptr);
8831 boardp = asc_dvc->drv_ptr;
8833 iop_base = asc_dvc->iop_base;
8834 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8836 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8837 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8838 target_ix = AscReadLramByte(iop_base,
8839 (ushort)(halt_q_addr +
8840 (ushort)ASC_SCSIQ_B_TARGET_IX));
8841 q_cntl = AscReadLramByte(iop_base,
8842 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8843 tid_no = ASC_TIX_TO_TID(target_ix);
8844 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8845 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8846 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8847 } else {
8848 asyn_sdtr = 0;
8850 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8851 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8852 AscSetChipSDTR(iop_base, 0, tid_no);
8853 boardp->sdtr_data[tid_no] = 0;
8855 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8856 return (0);
8857 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8858 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8859 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8860 boardp->sdtr_data[tid_no] = asyn_sdtr;
8862 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8863 return (0);
8864 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8865 AscMemWordCopyPtrFromLram(iop_base,
8866 ASCV_MSGIN_BEG,
8867 (uchar *)&ext_msg,
8868 sizeof(EXT_MSG) >> 1);
8870 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8871 ext_msg.msg_req == EXTENDED_SDTR &&
8872 ext_msg.msg_len == MS_SDTR_LEN) {
8873 sdtr_accept = TRUE;
8874 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8876 sdtr_accept = FALSE;
8877 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8879 if ((ext_msg.xfer_period <
8880 asc_dvc->sdtr_period_tbl[asc_dvc->
8881 host_init_sdtr_index])
8882 || (ext_msg.xfer_period >
8883 asc_dvc->sdtr_period_tbl[asc_dvc->
8884 max_sdtr_index])) {
8885 sdtr_accept = FALSE;
8886 ext_msg.xfer_period =
8887 asc_dvc->sdtr_period_tbl[asc_dvc->
8888 host_init_sdtr_index];
8890 if (sdtr_accept) {
8891 sdtr_data =
8892 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8893 ext_msg.req_ack_offset);
8894 if ((sdtr_data == 0xFF)) {
8896 q_cntl |= QC_MSG_OUT;
8897 asc_dvc->init_sdtr &= ~target_id;
8898 asc_dvc->sdtr_done &= ~target_id;
8899 AscSetChipSDTR(iop_base, asyn_sdtr,
8900 tid_no);
8901 boardp->sdtr_data[tid_no] = asyn_sdtr;
8904 if (ext_msg.req_ack_offset == 0) {
8906 q_cntl &= ~QC_MSG_OUT;
8907 asc_dvc->init_sdtr &= ~target_id;
8908 asc_dvc->sdtr_done &= ~target_id;
8909 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8910 } else {
8911 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8913 q_cntl &= ~QC_MSG_OUT;
8914 asc_dvc->sdtr_done |= target_id;
8915 asc_dvc->init_sdtr |= target_id;
8916 asc_dvc->pci_fix_asyn_xfer &=
8917 ~target_id;
8918 sdtr_data =
8919 AscCalSDTRData(asc_dvc,
8920 ext_msg.xfer_period,
8921 ext_msg.
8922 req_ack_offset);
8923 AscSetChipSDTR(iop_base, sdtr_data,
8924 tid_no);
8925 boardp->sdtr_data[tid_no] = sdtr_data;
8926 } else {
8928 q_cntl |= QC_MSG_OUT;
8929 AscMsgOutSDTR(asc_dvc,
8930 ext_msg.xfer_period,
8931 ext_msg.req_ack_offset);
8932 asc_dvc->pci_fix_asyn_xfer &=
8933 ~target_id;
8934 sdtr_data =
8935 AscCalSDTRData(asc_dvc,
8936 ext_msg.xfer_period,
8937 ext_msg.
8938 req_ack_offset);
8939 AscSetChipSDTR(iop_base, sdtr_data,
8940 tid_no);
8941 boardp->sdtr_data[tid_no] = sdtr_data;
8942 asc_dvc->sdtr_done |= target_id;
8943 asc_dvc->init_sdtr |= target_id;
8947 AscWriteLramByte(iop_base,
8948 (ushort)(halt_q_addr +
8949 (ushort)ASC_SCSIQ_B_CNTL),
8950 q_cntl);
8951 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8952 return (0);
8953 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8954 ext_msg.msg_req == EXTENDED_WDTR &&
8955 ext_msg.msg_len == MS_WDTR_LEN) {
8957 ext_msg.wdtr_width = 0;
8958 AscMemWordCopyPtrToLram(iop_base,
8959 ASCV_MSGOUT_BEG,
8960 (uchar *)&ext_msg,
8961 sizeof(EXT_MSG) >> 1);
8962 q_cntl |= QC_MSG_OUT;
8963 AscWriteLramByte(iop_base,
8964 (ushort)(halt_q_addr +
8965 (ushort)ASC_SCSIQ_B_CNTL),
8966 q_cntl);
8967 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8968 return (0);
8969 } else {
8971 ext_msg.msg_type = MESSAGE_REJECT;
8972 AscMemWordCopyPtrToLram(iop_base,
8973 ASCV_MSGOUT_BEG,
8974 (uchar *)&ext_msg,
8975 sizeof(EXT_MSG) >> 1);
8976 q_cntl |= QC_MSG_OUT;
8977 AscWriteLramByte(iop_base,
8978 (ushort)(halt_q_addr +
8979 (ushort)ASC_SCSIQ_B_CNTL),
8980 q_cntl);
8981 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8982 return (0);
8984 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8986 q_cntl |= QC_REQ_SENSE;
8988 if ((asc_dvc->init_sdtr & target_id) != 0) {
8990 asc_dvc->sdtr_done &= ~target_id;
8992 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8993 q_cntl |= QC_MSG_OUT;
8994 AscMsgOutSDTR(asc_dvc,
8995 asc_dvc->
8996 sdtr_period_tbl[(sdtr_data >> 4) &
8997 (uchar)(asc_dvc->
8998 max_sdtr_index -
8999 1)],
9000 (uchar)(sdtr_data & (uchar)
9001 ASC_SYN_MAX_OFFSET));
9004 AscWriteLramByte(iop_base,
9005 (ushort)(halt_q_addr +
9006 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
9008 tag_code = AscReadLramByte(iop_base,
9009 (ushort)(halt_q_addr + (ushort)
9010 ASC_SCSIQ_B_TAG_CODE));
9011 tag_code &= 0xDC;
9012 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
9013 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
9016 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
9017 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
9020 AscWriteLramByte(iop_base,
9021 (ushort)(halt_q_addr +
9022 (ushort)ASC_SCSIQ_B_TAG_CODE),
9023 tag_code);
9025 q_status = AscReadLramByte(iop_base,
9026 (ushort)(halt_q_addr + (ushort)
9027 ASC_SCSIQ_B_STATUS));
9028 q_status |= (QS_READY | QS_BUSY);
9029 AscWriteLramByte(iop_base,
9030 (ushort)(halt_q_addr +
9031 (ushort)ASC_SCSIQ_B_STATUS),
9032 q_status);
9034 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
9035 scsi_busy &= ~target_id;
9036 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
9038 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9039 return (0);
9040 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
9042 AscMemWordCopyPtrFromLram(iop_base,
9043 ASCV_MSGOUT_BEG,
9044 (uchar *)&out_msg,
9045 sizeof(EXT_MSG) >> 1);
9047 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
9048 (out_msg.msg_len == MS_SDTR_LEN) &&
9049 (out_msg.msg_req == EXTENDED_SDTR)) {
9051 asc_dvc->init_sdtr &= ~target_id;
9052 asc_dvc->sdtr_done &= ~target_id;
9053 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9054 boardp->sdtr_data[tid_no] = asyn_sdtr;
9056 q_cntl &= ~QC_MSG_OUT;
9057 AscWriteLramByte(iop_base,
9058 (ushort)(halt_q_addr +
9059 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
9060 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9061 return (0);
9062 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
9064 scsi_status = AscReadLramByte(iop_base,
9065 (ushort)((ushort)halt_q_addr +
9066 (ushort)
9067 ASC_SCSIQ_SCSI_STATUS));
9068 cur_dvc_qng =
9069 AscReadLramByte(iop_base,
9070 (ushort)((ushort)ASC_QADR_BEG +
9071 (ushort)target_ix));
9072 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
9074 scsi_busy = AscReadLramByte(iop_base,
9075 (ushort)ASCV_SCSIBUSY_B);
9076 scsi_busy |= target_id;
9077 AscWriteLramByte(iop_base,
9078 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
9079 asc_dvc->queue_full_or_busy |= target_id;
9081 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
9082 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
9083 cur_dvc_qng -= 1;
9084 asc_dvc->max_dvc_qng[tid_no] =
9085 cur_dvc_qng;
9087 AscWriteLramByte(iop_base,
9088 (ushort)((ushort)
9089 ASCV_MAX_DVC_QNG_BEG
9090 + (ushort)
9091 tid_no),
9092 cur_dvc_qng);
9095 * Set the device queue depth to the
9096 * number of active requests when the
9097 * QUEUE FULL condition was encountered.
9099 boardp->queue_full |= target_id;
9100 boardp->queue_full_cnt[tid_no] =
9101 cur_dvc_qng;
9105 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9106 return (0);
9108 #if CC_VERY_LONG_SG_LIST
9109 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
9110 uchar q_no;
9111 ushort q_addr;
9112 uchar sg_wk_q_no;
9113 uchar first_sg_wk_q_no;
9114 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
9115 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
9116 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
9117 ushort sg_list_dwords;
9118 ushort sg_entry_cnt;
9119 uchar next_qp;
9120 int i;
9122 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
9123 if (q_no == ASC_QLINK_END)
9124 return 0;
9126 q_addr = ASC_QNO_TO_QADDR(q_no);
9129 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
9130 * structure pointer using a macro provided by the driver.
9131 * The ASC_SCSI_REQ pointer provides a pointer to the
9132 * host ASC_SG_HEAD structure.
9134 /* Read request's SRB pointer. */
9135 scsiq = (ASC_SCSI_Q *)
9136 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
9137 (ushort)
9138 (q_addr +
9139 ASC_SCSIQ_D_SRBPTR))));
9142 * Get request's first and working SG queue.
9144 sg_wk_q_no = AscReadLramByte(iop_base,
9145 (ushort)(q_addr +
9146 ASC_SCSIQ_B_SG_WK_QP));
9148 first_sg_wk_q_no = AscReadLramByte(iop_base,
9149 (ushort)(q_addr +
9150 ASC_SCSIQ_B_FIRST_SG_WK_QP));
9153 * Reset request's working SG queue back to the
9154 * first SG queue.
9156 AscWriteLramByte(iop_base,
9157 (ushort)(q_addr +
9158 (ushort)ASC_SCSIQ_B_SG_WK_QP),
9159 first_sg_wk_q_no);
9161 sg_head = scsiq->sg_head;
9164 * Set sg_entry_cnt to the number of SG elements
9165 * that will be completed on this interrupt.
9167 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
9168 * SG elements. The data_cnt and data_addr fields which
9169 * add 1 to the SG element capacity are not used when
9170 * restarting SG handling after a halt.
9172 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
9173 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9176 * Keep track of remaining number of SG elements that
9177 * will need to be handled on the next interrupt.
9179 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
9180 } else {
9181 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
9182 scsiq->remain_sg_entry_cnt = 0;
9186 * Copy SG elements into the list of allocated SG queues.
9188 * Last index completed is saved in scsiq->next_sg_index.
9190 next_qp = first_sg_wk_q_no;
9191 q_addr = ASC_QNO_TO_QADDR(next_qp);
9192 scsi_sg_q.sg_head_qp = q_no;
9193 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9194 for (i = 0; i < sg_head->queue_cnt; i++) {
9195 scsi_sg_q.seq_no = i + 1;
9196 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9197 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9198 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9200 * After very first SG queue RISC FW uses next
9201 * SG queue first element then checks sg_list_cnt
9202 * against zero and then decrements, so set
9203 * sg_list_cnt 1 less than number of SG elements
9204 * in each SG queue.
9206 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
9207 scsi_sg_q.sg_cur_list_cnt =
9208 ASC_SG_LIST_PER_Q - 1;
9209 } else {
9211 * This is the last SG queue in the list of
9212 * allocated SG queues. If there are more
9213 * SG elements than will fit in the allocated
9214 * queues, then set the QCSG_SG_XFER_MORE flag.
9216 if (scsiq->remain_sg_entry_cnt != 0) {
9217 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9218 } else {
9219 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
9221 /* equals sg_entry_cnt * 2 */
9222 sg_list_dwords = sg_entry_cnt << 1;
9223 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
9224 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
9225 sg_entry_cnt = 0;
9228 scsi_sg_q.q_no = next_qp;
9229 AscMemWordCopyPtrToLram(iop_base,
9230 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9231 (uchar *)&scsi_sg_q,
9232 sizeof(ASC_SG_LIST_Q) >> 1);
9234 AscMemDWordCopyPtrToLram(iop_base,
9235 q_addr + ASC_SGQ_LIST_BEG,
9236 (uchar *)&sg_head->
9237 sg_list[scsiq->next_sg_index],
9238 sg_list_dwords);
9240 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
9243 * If the just completed SG queue contained the
9244 * last SG element, then no more SG queues need
9245 * to be written.
9247 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
9248 break;
9251 next_qp = AscReadLramByte(iop_base,
9252 (ushort)(q_addr +
9253 ASC_SCSIQ_B_FWD));
9254 q_addr = ASC_QNO_TO_QADDR(next_qp);
9258 * Clear the halt condition so the RISC will be restarted
9259 * after the return.
9261 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9262 return (0);
9264 #endif /* CC_VERY_LONG_SG_LIST */
9265 return (0);
9269 * void
9270 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9272 * Calling/Exit State:
9273 * none
9275 * Description:
9276 * Input an ASC_QDONE_INFO structure from the chip
9278 static void
9279 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9281 int i;
9282 ushort word;
9284 AscSetChipLramAddr(iop_base, s_addr);
9285 for (i = 0; i < 2 * words; i += 2) {
9286 if (i == 10) {
9287 continue;
9289 word = inpw(iop_base + IOP_RAM_DATA);
9290 inbuf[i] = word & 0xff;
9291 inbuf[i + 1] = (word >> 8) & 0xff;
9293 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
9296 static uchar
9297 _AscCopyLramScsiDoneQ(PortAddr iop_base,
9298 ushort q_addr,
9299 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
9301 ushort _val;
9302 uchar sg_queue_cnt;
9304 DvcGetQinfo(iop_base,
9305 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
9306 (uchar *)scsiq,
9307 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
9309 _val = AscReadLramWord(iop_base,
9310 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
9311 scsiq->q_status = (uchar)_val;
9312 scsiq->q_no = (uchar)(_val >> 8);
9313 _val = AscReadLramWord(iop_base,
9314 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
9315 scsiq->cntl = (uchar)_val;
9316 sg_queue_cnt = (uchar)(_val >> 8);
9317 _val = AscReadLramWord(iop_base,
9318 (ushort)(q_addr +
9319 (ushort)ASC_SCSIQ_B_SENSE_LEN));
9320 scsiq->sense_len = (uchar)_val;
9321 scsiq->extra_bytes = (uchar)(_val >> 8);
9324 * Read high word of remain bytes from alternate location.
9326 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
9327 (ushort)(q_addr +
9328 (ushort)
9329 ASC_SCSIQ_W_ALT_DC1)))
9330 << 16);
9332 * Read low word of remain bytes from original location.
9334 scsiq->remain_bytes += AscReadLramWord(iop_base,
9335 (ushort)(q_addr + (ushort)
9336 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
9338 scsiq->remain_bytes &= max_dma_count;
9339 return sg_queue_cnt;
9343 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
9345 * Interrupt callback function for the Narrow SCSI Asc Library.
9347 static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
9349 asc_board_t *boardp;
9350 struct scsi_cmnd *scp;
9351 struct Scsi_Host *shost;
9353 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
9354 (ulong)asc_dvc_varp, (ulong)qdonep);
9355 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
9358 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
9359 * command that has been completed.
9361 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
9362 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
9364 if (scp == NULL) {
9365 ASC_PRINT("asc_isr_callback: scp is NULL\n");
9366 return;
9368 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
9370 shost = scp->device->host;
9371 ASC_STATS(shost, callback);
9372 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
9374 boardp = ASC_BOARDP(shost);
9375 BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var);
9378 * 'qdonep' contains the command's ending status.
9380 switch (qdonep->d3.done_stat) {
9381 case QD_NO_ERROR:
9382 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
9383 scp->result = 0;
9386 * Check for an underrun condition.
9388 * If there was no error and an underrun condition, then
9389 * return the number of underrun bytes.
9391 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
9392 qdonep->remain_bytes <= scp->request_bufflen) {
9393 ASC_DBG1(1,
9394 "asc_isr_callback: underrun condition %u bytes\n",
9395 (unsigned)qdonep->remain_bytes);
9396 scp->resid = qdonep->remain_bytes;
9398 break;
9400 case QD_WITH_ERROR:
9401 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
9402 switch (qdonep->d3.host_stat) {
9403 case QHSTA_NO_ERROR:
9404 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
9405 ASC_DBG(2,
9406 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
9407 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
9408 sizeof(scp->sense_buffer));
9410 * Note: The 'status_byte()' macro used by
9411 * target drivers defined in scsi.h shifts the
9412 * status byte returned by host drivers right
9413 * by 1 bit. This is why target drivers also
9414 * use right shifted status byte definitions.
9415 * For instance target drivers use
9416 * CHECK_CONDITION, defined to 0x1, instead of
9417 * the SCSI defined check condition value of
9418 * 0x2. Host drivers are supposed to return
9419 * the status byte as it is defined by SCSI.
9421 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
9422 STATUS_BYTE(qdonep->d3.scsi_stat);
9423 } else {
9424 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
9426 break;
9428 default:
9429 /* QHSTA error occurred */
9430 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
9431 qdonep->d3.host_stat);
9432 scp->result = HOST_BYTE(DID_BAD_TARGET);
9433 break;
9435 break;
9437 case QD_ABORTED_BY_HOST:
9438 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
9439 scp->result =
9440 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
9441 scsi_msg) |
9442 STATUS_BYTE(qdonep->d3.scsi_stat);
9443 break;
9445 default:
9446 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
9447 qdonep->d3.done_stat);
9448 scp->result =
9449 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
9450 scsi_msg) |
9451 STATUS_BYTE(qdonep->d3.scsi_stat);
9452 break;
9456 * If the 'init_tidmask' bit isn't already set for the target and the
9457 * current request finished normally, then set the bit for the target
9458 * to indicate that a device is present.
9460 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
9461 qdonep->d3.done_stat == QD_NO_ERROR &&
9462 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
9463 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
9466 asc_scsi_done(scp);
9468 return;
9471 static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
9473 uchar next_qp;
9474 uchar n_q_used;
9475 uchar sg_list_qp;
9476 uchar sg_queue_cnt;
9477 uchar q_cnt;
9478 uchar done_q_tail;
9479 uchar tid_no;
9480 ASC_SCSI_BIT_ID_TYPE scsi_busy;
9481 ASC_SCSI_BIT_ID_TYPE target_id;
9482 PortAddr iop_base;
9483 ushort q_addr;
9484 ushort sg_q_addr;
9485 uchar cur_target_qng;
9486 ASC_QDONE_INFO scsiq_buf;
9487 ASC_QDONE_INFO *scsiq;
9488 int false_overrun;
9490 iop_base = asc_dvc->iop_base;
9491 n_q_used = 1;
9492 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
9493 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
9494 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
9495 next_qp = AscReadLramByte(iop_base,
9496 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
9497 if (next_qp != ASC_QLINK_END) {
9498 AscPutVarDoneQTail(iop_base, next_qp);
9499 q_addr = ASC_QNO_TO_QADDR(next_qp);
9500 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
9501 asc_dvc->max_dma_count);
9502 AscWriteLramByte(iop_base,
9503 (ushort)(q_addr +
9504 (ushort)ASC_SCSIQ_B_STATUS),
9505 (uchar)(scsiq->
9506 q_status & (uchar)~(QS_READY |
9507 QS_ABORTED)));
9508 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
9509 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
9510 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
9511 sg_q_addr = q_addr;
9512 sg_list_qp = next_qp;
9513 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
9514 sg_list_qp = AscReadLramByte(iop_base,
9515 (ushort)(sg_q_addr
9516 + (ushort)
9517 ASC_SCSIQ_B_FWD));
9518 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
9519 if (sg_list_qp == ASC_QLINK_END) {
9520 AscSetLibErrorCode(asc_dvc,
9521 ASCQ_ERR_SG_Q_LINKS);
9522 scsiq->d3.done_stat = QD_WITH_ERROR;
9523 scsiq->d3.host_stat =
9524 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
9525 goto FATAL_ERR_QDONE;
9527 AscWriteLramByte(iop_base,
9528 (ushort)(sg_q_addr + (ushort)
9529 ASC_SCSIQ_B_STATUS),
9530 QS_FREE);
9532 n_q_used = sg_queue_cnt + 1;
9533 AscPutVarDoneQTail(iop_base, sg_list_qp);
9535 if (asc_dvc->queue_full_or_busy & target_id) {
9536 cur_target_qng = AscReadLramByte(iop_base,
9537 (ushort)((ushort)
9538 ASC_QADR_BEG
9539 + (ushort)
9540 scsiq->d2.
9541 target_ix));
9542 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
9543 scsi_busy = AscReadLramByte(iop_base, (ushort)
9544 ASCV_SCSIBUSY_B);
9545 scsi_busy &= ~target_id;
9546 AscWriteLramByte(iop_base,
9547 (ushort)ASCV_SCSIBUSY_B,
9548 scsi_busy);
9549 asc_dvc->queue_full_or_busy &= ~target_id;
9552 if (asc_dvc->cur_total_qng >= n_q_used) {
9553 asc_dvc->cur_total_qng -= n_q_used;
9554 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
9555 asc_dvc->cur_dvc_qng[tid_no]--;
9557 } else {
9558 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
9559 scsiq->d3.done_stat = QD_WITH_ERROR;
9560 goto FATAL_ERR_QDONE;
9562 if ((scsiq->d2.srb_ptr == 0UL) ||
9563 ((scsiq->q_status & QS_ABORTED) != 0)) {
9564 return (0x11);
9565 } else if (scsiq->q_status == QS_DONE) {
9566 false_overrun = FALSE;
9567 if (scsiq->extra_bytes != 0) {
9568 scsiq->remain_bytes +=
9569 (ADV_DCNT)scsiq->extra_bytes;
9571 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
9572 if (scsiq->d3.host_stat ==
9573 QHSTA_M_DATA_OVER_RUN) {
9574 if ((scsiq->
9575 cntl & (QC_DATA_IN | QC_DATA_OUT))
9576 == 0) {
9577 scsiq->d3.done_stat =
9578 QD_NO_ERROR;
9579 scsiq->d3.host_stat =
9580 QHSTA_NO_ERROR;
9581 } else if (false_overrun) {
9582 scsiq->d3.done_stat =
9583 QD_NO_ERROR;
9584 scsiq->d3.host_stat =
9585 QHSTA_NO_ERROR;
9587 } else if (scsiq->d3.host_stat ==
9588 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
9589 AscStopChip(iop_base);
9590 AscSetChipControl(iop_base,
9591 (uchar)(CC_SCSI_RESET
9592 | CC_HALT));
9593 udelay(60);
9594 AscSetChipControl(iop_base, CC_HALT);
9595 AscSetChipStatus(iop_base,
9596 CIW_CLR_SCSI_RESET_INT);
9597 AscSetChipStatus(iop_base, 0);
9598 AscSetChipControl(iop_base, 0);
9601 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9602 asc_isr_callback(asc_dvc, scsiq);
9603 } else {
9604 if ((AscReadLramByte(iop_base,
9605 (ushort)(q_addr + (ushort)
9606 ASC_SCSIQ_CDB_BEG))
9607 == START_STOP)) {
9608 asc_dvc->unit_not_ready &= ~target_id;
9609 if (scsiq->d3.done_stat != QD_NO_ERROR) {
9610 asc_dvc->start_motor &=
9611 ~target_id;
9615 return (1);
9616 } else {
9617 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
9618 FATAL_ERR_QDONE:
9619 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9620 asc_isr_callback(asc_dvc, scsiq);
9622 return (0x80);
9625 return (0);
9628 static int AscISR(ASC_DVC_VAR *asc_dvc)
9630 ASC_CS_TYPE chipstat;
9631 PortAddr iop_base;
9632 ushort saved_ram_addr;
9633 uchar ctrl_reg;
9634 uchar saved_ctrl_reg;
9635 int int_pending;
9636 int status;
9637 uchar host_flag;
9639 iop_base = asc_dvc->iop_base;
9640 int_pending = FALSE;
9642 if (AscIsIntPending(iop_base) == 0)
9643 return int_pending;
9645 if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
9646 return ERR;
9648 if (asc_dvc->in_critical_cnt != 0) {
9649 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
9650 return ERR;
9652 if (asc_dvc->is_in_int) {
9653 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
9654 return ERR;
9656 asc_dvc->is_in_int = TRUE;
9657 ctrl_reg = AscGetChipControl(iop_base);
9658 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
9659 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
9660 chipstat = AscGetChipStatus(iop_base);
9661 if (chipstat & CSW_SCSI_RESET_LATCH) {
9662 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
9663 int i = 10;
9664 int_pending = TRUE;
9665 asc_dvc->sdtr_done = 0;
9666 saved_ctrl_reg &= (uchar)(~CC_HALT);
9667 while ((AscGetChipStatus(iop_base) &
9668 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
9669 mdelay(100);
9671 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
9672 AscSetChipControl(iop_base, CC_HALT);
9673 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
9674 AscSetChipStatus(iop_base, 0);
9675 chipstat = AscGetChipStatus(iop_base);
9678 saved_ram_addr = AscGetChipLramAddr(iop_base);
9679 host_flag = AscReadLramByte(iop_base,
9680 ASCV_HOST_FLAG_B) &
9681 (uchar)(~ASC_HOST_FLAG_IN_ISR);
9682 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
9683 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
9684 if ((chipstat & CSW_INT_PENDING) || (int_pending)) {
9685 AscAckInterrupt(iop_base);
9686 int_pending = TRUE;
9687 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
9688 if (AscIsrChipHalted(asc_dvc) == ERR) {
9689 goto ISR_REPORT_QDONE_FATAL_ERROR;
9690 } else {
9691 saved_ctrl_reg &= (uchar)(~CC_HALT);
9693 } else {
9694 ISR_REPORT_QDONE_FATAL_ERROR:
9695 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
9696 while (((status =
9697 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
9699 } else {
9700 do {
9701 if ((status =
9702 AscIsrQDone(asc_dvc)) == 1) {
9703 break;
9705 } while (status == 0x11);
9707 if ((status & 0x80) != 0)
9708 int_pending = ERR;
9711 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9712 AscSetChipLramAddr(iop_base, saved_ram_addr);
9713 AscSetChipControl(iop_base, saved_ctrl_reg);
9714 asc_dvc->is_in_int = FALSE;
9715 return int_pending;
9719 * advansys_reset()
9721 * Reset the bus associated with the command 'scp'.
9723 * This function runs its own thread. Interrupts must be blocked but
9724 * sleeping is allowed and no locking other than for host structures is
9725 * required. Returns SUCCESS or FAILED.
9727 static int advansys_reset(struct scsi_cmnd *scp)
9729 struct Scsi_Host *shost = scp->device->host;
9730 struct asc_board *boardp = ASC_BOARDP(shost);
9731 unsigned long flags;
9732 int status;
9733 int ret = SUCCESS;
9735 ASC_DBG1(1, "advansys_reset: 0x%p\n", scp);
9737 ASC_STATS(shost, reset);
9739 scmd_printk(KERN_INFO, scp, "SCSI bus reset started...\n");
9741 if (ASC_NARROW_BOARD(boardp)) {
9742 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
9744 /* Reset the chip and SCSI bus. */
9745 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
9746 status = AscInitAsc1000Driver(asc_dvc);
9748 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
9749 if (asc_dvc->err_code) {
9750 scmd_printk(KERN_INFO, scp, "SCSI bus reset error: "
9751 "0x%x\n", asc_dvc->err_code);
9752 ret = FAILED;
9753 } else if (status) {
9754 scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: "
9755 "0x%x\n", status);
9756 } else {
9757 scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9758 "successful\n");
9761 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
9762 spin_lock_irqsave(&boardp->lock, flags);
9763 } else {
9765 * If the suggest reset bus flags are set, then reset the bus.
9766 * Otherwise only reset the device.
9768 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
9771 * Reset the target's SCSI bus.
9773 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
9774 switch (AdvResetChipAndSB(adv_dvc)) {
9775 case ASC_TRUE:
9776 scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9777 "successful\n");
9778 break;
9779 case ASC_FALSE:
9780 default:
9781 scmd_printk(KERN_INFO, scp, "SCSI bus reset error\n");
9782 ret = FAILED;
9783 break;
9785 spin_lock_irqsave(&boardp->lock, flags);
9786 AdvISR(adv_dvc);
9789 /* Save the time of the most recently completed reset. */
9790 boardp->last_reset = jiffies;
9791 spin_unlock_irqrestore(&boardp->lock, flags);
9793 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
9795 return ret;
9799 * advansys_biosparam()
9801 * Translate disk drive geometry if the "BIOS greater than 1 GB"
9802 * support is enabled for a drive.
9804 * ip (information pointer) is an int array with the following definition:
9805 * ip[0]: heads
9806 * ip[1]: sectors
9807 * ip[2]: cylinders
9809 static int
9810 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
9811 sector_t capacity, int ip[])
9813 asc_board_t *boardp;
9815 ASC_DBG(1, "advansys_biosparam: begin\n");
9816 ASC_STATS(sdev->host, biosparam);
9817 boardp = ASC_BOARDP(sdev->host);
9818 if (ASC_NARROW_BOARD(boardp)) {
9819 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
9820 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
9821 ip[0] = 255;
9822 ip[1] = 63;
9823 } else {
9824 ip[0] = 64;
9825 ip[1] = 32;
9827 } else {
9828 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
9829 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
9830 ip[0] = 255;
9831 ip[1] = 63;
9832 } else {
9833 ip[0] = 64;
9834 ip[1] = 32;
9837 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
9838 ASC_DBG(1, "advansys_biosparam: end\n");
9839 return 0;
9843 * First-level interrupt handler.
9845 * 'dev_id' is a pointer to the interrupting adapter's Scsi_Host.
9847 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
9849 unsigned long flags;
9850 struct Scsi_Host *shost = dev_id;
9851 asc_board_t *boardp = ASC_BOARDP(shost);
9852 irqreturn_t result = IRQ_NONE;
9854 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
9855 spin_lock_irqsave(&boardp->lock, flags);
9856 if (ASC_NARROW_BOARD(boardp)) {
9857 if (AscIsIntPending(shost->io_port)) {
9858 result = IRQ_HANDLED;
9859 ASC_STATS(shost, interrupt);
9860 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
9861 AscISR(&boardp->dvc_var.asc_dvc_var);
9863 } else {
9864 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
9865 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
9866 result = IRQ_HANDLED;
9867 ASC_STATS(shost, interrupt);
9870 spin_unlock_irqrestore(&boardp->lock, flags);
9872 ASC_DBG(1, "advansys_interrupt: end\n");
9873 return result;
9876 static int AscHostReqRiscHalt(PortAddr iop_base)
9878 int count = 0;
9879 int sta = 0;
9880 uchar saved_stop_code;
9882 if (AscIsChipHalted(iop_base))
9883 return (1);
9884 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
9885 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9886 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
9887 do {
9888 if (AscIsChipHalted(iop_base)) {
9889 sta = 1;
9890 break;
9892 mdelay(100);
9893 } while (count++ < 20);
9894 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
9895 return (sta);
9898 static int
9899 AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9901 int sta = FALSE;
9903 if (AscHostReqRiscHalt(iop_base)) {
9904 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9905 AscStartChip(iop_base);
9907 return sta;
9910 static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
9912 char type = sdev->type;
9913 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
9915 if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN))
9916 return;
9917 if (asc_dvc->init_sdtr & tid_bits)
9918 return;
9920 if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0))
9921 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
9923 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
9924 if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) ||
9925 (type == TYPE_ROM) || (type == TYPE_TAPE))
9926 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
9928 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
9929 AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id,
9930 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
9933 static void
9934 advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
9936 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
9937 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
9939 if (sdev->lun == 0) {
9940 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
9941 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
9942 asc_dvc->init_sdtr |= tid_bit;
9943 } else {
9944 asc_dvc->init_sdtr &= ~tid_bit;
9947 if (orig_init_sdtr != asc_dvc->init_sdtr)
9948 AscAsyncFix(asc_dvc, sdev);
9951 if (sdev->tagged_supported) {
9952 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
9953 if (sdev->lun == 0) {
9954 asc_dvc->cfg->can_tagged_qng |= tid_bit;
9955 asc_dvc->use_tagged_qng |= tid_bit;
9957 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
9958 asc_dvc->max_dvc_qng[sdev->id]);
9960 } else {
9961 if (sdev->lun == 0) {
9962 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
9963 asc_dvc->use_tagged_qng &= ~tid_bit;
9965 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
9968 if ((sdev->lun == 0) &&
9969 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
9970 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
9971 asc_dvc->cfg->disc_enable);
9972 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
9973 asc_dvc->use_tagged_qng);
9974 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
9975 asc_dvc->cfg->can_tagged_qng);
9977 asc_dvc->max_dvc_qng[sdev->id] =
9978 asc_dvc->cfg->max_tag_qng[sdev->id];
9979 AscWriteLramByte(asc_dvc->iop_base,
9980 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
9981 asc_dvc->max_dvc_qng[sdev->id]);
9986 * Wide Transfers
9988 * If the EEPROM enabled WDTR for the device and the device supports wide
9989 * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
9990 * write the new value to the microcode.
9992 static void
9993 advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
9995 unsigned short cfg_word;
9996 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
9997 if ((cfg_word & tidmask) != 0)
9998 return;
10000 cfg_word |= tidmask;
10001 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
10004 * Clear the microcode SDTR and WDTR negotiation done indicators for
10005 * the target to cause it to negotiate with the new setting set above.
10006 * WDTR when accepted causes the target to enter asynchronous mode, so
10007 * SDTR must be negotiated.
10009 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
10010 cfg_word &= ~tidmask;
10011 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
10012 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
10013 cfg_word &= ~tidmask;
10014 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
10018 * Synchronous Transfers
10020 * If the EEPROM enabled SDTR for the device and the device
10021 * supports synchronous transfers, then turn on the device's
10022 * 'sdtr_able' bit. Write the new value to the microcode.
10024 static void
10025 advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
10027 unsigned short cfg_word;
10028 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
10029 if ((cfg_word & tidmask) != 0)
10030 return;
10032 cfg_word |= tidmask;
10033 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
10036 * Clear the microcode "SDTR negotiation" done indicator for the
10037 * target to cause it to negotiate with the new setting set above.
10039 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
10040 cfg_word &= ~tidmask;
10041 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
10045 * PPR (Parallel Protocol Request) Capable
10047 * If the device supports DT mode, then it must be PPR capable.
10048 * The PPR message will be used in place of the SDTR and WDTR
10049 * messages to negotiate synchronous speed and offset, transfer
10050 * width, and protocol options.
10052 static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
10053 AdvPortAddr iop_base, unsigned short tidmask)
10055 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
10056 adv_dvc->ppr_able |= tidmask;
10057 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
10060 static void
10061 advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
10063 AdvPortAddr iop_base = adv_dvc->iop_base;
10064 unsigned short tidmask = 1 << sdev->id;
10066 if (sdev->lun == 0) {
10068 * Handle WDTR, SDTR, and Tag Queuing. If the feature
10069 * is enabled in the EEPROM and the device supports the
10070 * feature, then enable it in the microcode.
10073 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
10074 advansys_wide_enable_wdtr(iop_base, tidmask);
10075 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
10076 advansys_wide_enable_sdtr(iop_base, tidmask);
10077 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
10078 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
10081 * Tag Queuing is disabled for the BIOS which runs in polled
10082 * mode and would see no benefit from Tag Queuing. Also by
10083 * disabling Tag Queuing in the BIOS devices with Tag Queuing
10084 * bugs will at least work with the BIOS.
10086 if ((adv_dvc->tagqng_able & tidmask) &&
10087 sdev->tagged_supported) {
10088 unsigned short cfg_word;
10089 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
10090 cfg_word |= tidmask;
10091 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
10092 cfg_word);
10093 AdvWriteByteLram(iop_base,
10094 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
10095 adv_dvc->max_dvc_qng);
10099 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
10100 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
10101 adv_dvc->max_dvc_qng);
10102 } else {
10103 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
10108 * Set the number of commands to queue per device for the
10109 * specified host adapter.
10111 static int advansys_slave_configure(struct scsi_device *sdev)
10113 asc_board_t *boardp = ASC_BOARDP(sdev->host);
10115 if (ASC_NARROW_BOARD(boardp))
10116 advansys_narrow_slave_configure(sdev,
10117 &boardp->dvc_var.asc_dvc_var);
10118 else
10119 advansys_wide_slave_configure(sdev,
10120 &boardp->dvc_var.adv_dvc_var);
10122 return 0;
10125 static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
10126 struct asc_scsi_q *asc_scsi_q)
10128 memset(asc_scsi_q, 0, sizeof(*asc_scsi_q));
10131 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
10133 asc_scsi_q->q2.srb_ptr = ASC_VADDR_TO_U32(scp);
10136 * Build the ASC_SCSI_Q request.
10138 asc_scsi_q->cdbptr = &scp->cmnd[0];
10139 asc_scsi_q->q2.cdb_len = scp->cmd_len;
10140 asc_scsi_q->q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
10141 asc_scsi_q->q1.target_lun = scp->device->lun;
10142 asc_scsi_q->q2.target_ix =
10143 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
10144 asc_scsi_q->q1.sense_addr =
10145 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
10146 asc_scsi_q->q1.sense_len = sizeof(scp->sense_buffer);
10149 * If there are any outstanding requests for the current target,
10150 * then every 255th request send an ORDERED request. This heuristic
10151 * tries to retain the benefit of request sorting while preventing
10152 * request starvation. 255 is the max number of tags or pending commands
10153 * a device may have outstanding.
10155 * The request count is incremented below for every successfully
10156 * started request.
10159 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
10160 (boardp->reqcnt[scp->device->id] % 255) == 0) {
10161 asc_scsi_q->q2.tag_code = MSG_ORDERED_TAG;
10162 } else {
10163 asc_scsi_q->q2.tag_code = MSG_SIMPLE_TAG;
10167 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
10168 * buffer command.
10170 if (scp->use_sg == 0) {
10172 * CDB request of single contiguous buffer.
10174 ASC_STATS(scp->device->host, cont_cnt);
10175 scp->SCp.dma_handle = scp->request_bufflen ?
10176 dma_map_single(boardp->dev, scp->request_buffer,
10177 scp->request_bufflen,
10178 scp->sc_data_direction) : 0;
10179 asc_scsi_q->q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
10180 asc_scsi_q->q1.data_cnt = cpu_to_le32(scp->request_bufflen);
10181 ASC_STATS_ADD(scp->device->host, cont_xfer,
10182 ASC_CEILING(scp->request_bufflen, 512));
10183 asc_scsi_q->q1.sg_queue_cnt = 0;
10184 asc_scsi_q->sg_head = NULL;
10185 } else {
10187 * CDB scatter-gather request list.
10189 int sgcnt;
10190 int use_sg;
10191 struct scatterlist *slp;
10192 struct asc_sg_head *asc_sg_head;
10194 slp = (struct scatterlist *)scp->request_buffer;
10195 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
10196 scp->sc_data_direction);
10198 if (use_sg > scp->device->host->sg_tablesize) {
10199 ASC_PRINT3("asc_build_req: board %d: use_sg %d > "
10200 "sg_tablesize %d\n", boardp->id, use_sg,
10201 scp->device->host->sg_tablesize);
10202 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10203 scp->sc_data_direction);
10204 scp->result = HOST_BYTE(DID_ERROR);
10205 return ASC_ERROR;
10208 ASC_STATS(scp->device->host, sg_cnt);
10210 asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) +
10211 use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC);
10212 if (!asc_sg_head) {
10213 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10214 scp->sc_data_direction);
10215 scp->result = HOST_BYTE(DID_SOFT_ERROR);
10216 return ASC_ERROR;
10219 asc_scsi_q->q1.cntl |= QC_SG_HEAD;
10220 asc_scsi_q->sg_head = asc_sg_head;
10221 asc_scsi_q->q1.data_cnt = 0;
10222 asc_scsi_q->q1.data_addr = 0;
10223 /* This is a byte value, otherwise it would need to be swapped. */
10224 asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg;
10225 ASC_STATS_ADD(scp->device->host, sg_elem,
10226 asc_sg_head->entry_cnt);
10229 * Convert scatter-gather list into ASC_SG_HEAD list.
10231 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
10232 asc_sg_head->sg_list[sgcnt].addr =
10233 cpu_to_le32(sg_dma_address(slp));
10234 asc_sg_head->sg_list[sgcnt].bytes =
10235 cpu_to_le32(sg_dma_len(slp));
10236 ASC_STATS_ADD(scp->device->host, sg_xfer,
10237 ASC_CEILING(sg_dma_len(slp), 512));
10241 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
10242 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
10244 return ASC_NOERROR;
10248 * Build scatter-gather list for Adv Library (Wide Board).
10250 * Additional ADV_SG_BLOCK structures will need to be allocated
10251 * if the total number of scatter-gather elements exceeds
10252 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
10253 * assumed to be physically contiguous.
10255 * Return:
10256 * ADV_SUCCESS(1) - SG List successfully created
10257 * ADV_ERROR(-1) - SG List creation failed
10259 static int
10260 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
10261 int use_sg)
10263 adv_sgblk_t *sgblkp;
10264 ADV_SCSI_REQ_Q *scsiqp;
10265 struct scatterlist *slp;
10266 int sg_elem_cnt;
10267 ADV_SG_BLOCK *sg_block, *prev_sg_block;
10268 ADV_PADDR sg_block_paddr;
10269 int i;
10271 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
10272 slp = (struct scatterlist *)scp->request_buffer;
10273 sg_elem_cnt = use_sg;
10274 prev_sg_block = NULL;
10275 reqp->sgblkp = NULL;
10277 for (;;) {
10279 * Allocate a 'adv_sgblk_t' structure from the board free
10280 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
10281 * (15) scatter-gather elements.
10283 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
10284 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
10285 ASC_STATS(scp->device->host, adv_build_nosg);
10288 * Allocation failed. Free 'adv_sgblk_t' structures
10289 * already allocated for the request.
10291 while ((sgblkp = reqp->sgblkp) != NULL) {
10292 /* Remove 'sgblkp' from the request list. */
10293 reqp->sgblkp = sgblkp->next_sgblkp;
10295 /* Add 'sgblkp' to the board free list. */
10296 sgblkp->next_sgblkp = boardp->adv_sgblkp;
10297 boardp->adv_sgblkp = sgblkp;
10299 return ASC_BUSY;
10302 /* Complete 'adv_sgblk_t' board allocation. */
10303 boardp->adv_sgblkp = sgblkp->next_sgblkp;
10304 sgblkp->next_sgblkp = NULL;
10307 * Get 8 byte aligned virtual and physical addresses
10308 * for the allocated ADV_SG_BLOCK structure.
10310 sg_block = (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
10311 sg_block_paddr = virt_to_bus(sg_block);
10314 * Check if this is the first 'adv_sgblk_t' for the
10315 * request.
10317 if (reqp->sgblkp == NULL) {
10318 /* Request's first scatter-gather block. */
10319 reqp->sgblkp = sgblkp;
10322 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
10323 * address pointers.
10325 scsiqp->sg_list_ptr = sg_block;
10326 scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
10327 } else {
10328 /* Request's second or later scatter-gather block. */
10329 sgblkp->next_sgblkp = reqp->sgblkp;
10330 reqp->sgblkp = sgblkp;
10333 * Point the previous ADV_SG_BLOCK structure to
10334 * the newly allocated ADV_SG_BLOCK structure.
10336 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
10339 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
10340 sg_block->sg_list[i].sg_addr =
10341 cpu_to_le32(sg_dma_address(slp));
10342 sg_block->sg_list[i].sg_count =
10343 cpu_to_le32(sg_dma_len(slp));
10344 ASC_STATS_ADD(scp->device->host, sg_xfer,
10345 ASC_CEILING(sg_dma_len(slp), 512));
10347 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
10348 sg_block->sg_cnt = i + 1;
10349 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
10350 return ADV_SUCCESS;
10352 slp++;
10354 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
10355 prev_sg_block = sg_block;
10360 * Build a request structure for the Adv Library (Wide Board).
10362 * If an adv_req_t can not be allocated to issue the request,
10363 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
10365 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
10366 * microcode for DMA addresses or math operations are byte swapped
10367 * to little-endian order.
10369 static int
10370 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
10371 ADV_SCSI_REQ_Q **adv_scsiqpp)
10373 adv_req_t *reqp;
10374 ADV_SCSI_REQ_Q *scsiqp;
10375 int i;
10376 int ret;
10379 * Allocate an adv_req_t structure from the board to execute
10380 * the command.
10382 if (boardp->adv_reqp == NULL) {
10383 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
10384 ASC_STATS(scp->device->host, adv_build_noreq);
10385 return ASC_BUSY;
10386 } else {
10387 reqp = boardp->adv_reqp;
10388 boardp->adv_reqp = reqp->next_reqp;
10389 reqp->next_reqp = NULL;
10393 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
10395 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
10398 * Initialize the structure.
10400 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
10403 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
10405 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
10408 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
10410 reqp->cmndp = scp;
10413 * Build the ADV_SCSI_REQ_Q request.
10416 /* Set CDB length and copy it to the request structure. */
10417 scsiqp->cdb_len = scp->cmd_len;
10418 /* Copy first 12 CDB bytes to cdb[]. */
10419 for (i = 0; i < scp->cmd_len && i < 12; i++) {
10420 scsiqp->cdb[i] = scp->cmnd[i];
10422 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
10423 for (; i < scp->cmd_len; i++) {
10424 scsiqp->cdb16[i - 12] = scp->cmnd[i];
10427 scsiqp->target_id = scp->device->id;
10428 scsiqp->target_lun = scp->device->lun;
10430 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
10431 scsiqp->sense_len = sizeof(scp->sense_buffer);
10434 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
10435 * buffer command.
10438 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
10439 scsiqp->vdata_addr = scp->request_buffer;
10440 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
10442 if (scp->use_sg == 0) {
10444 * CDB request of single contiguous buffer.
10446 reqp->sgblkp = NULL;
10447 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
10448 if (scp->request_bufflen) {
10449 scsiqp->vdata_addr = scp->request_buffer;
10450 scp->SCp.dma_handle =
10451 dma_map_single(boardp->dev, scp->request_buffer,
10452 scp->request_bufflen,
10453 scp->sc_data_direction);
10454 } else {
10455 scsiqp->vdata_addr = NULL;
10456 scp->SCp.dma_handle = 0;
10458 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
10459 scsiqp->sg_list_ptr = NULL;
10460 scsiqp->sg_real_addr = 0;
10461 ASC_STATS(scp->device->host, cont_cnt);
10462 ASC_STATS_ADD(scp->device->host, cont_xfer,
10463 ASC_CEILING(scp->request_bufflen, 512));
10464 } else {
10466 * CDB scatter-gather request list.
10468 struct scatterlist *slp;
10469 int use_sg;
10471 slp = (struct scatterlist *)scp->request_buffer;
10472 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
10473 scp->sc_data_direction);
10475 if (use_sg > ADV_MAX_SG_LIST) {
10476 ASC_PRINT3("adv_build_req: board %d: use_sg %d > "
10477 "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg,
10478 scp->device->host->sg_tablesize);
10479 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10480 scp->sc_data_direction);
10481 scp->result = HOST_BYTE(DID_ERROR);
10484 * Free the 'adv_req_t' structure by adding it back
10485 * to the board free list.
10487 reqp->next_reqp = boardp->adv_reqp;
10488 boardp->adv_reqp = reqp;
10490 return ASC_ERROR;
10493 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
10494 if (ret != ADV_SUCCESS) {
10496 * Free the adv_req_t structure by adding it back to
10497 * the board free list.
10499 reqp->next_reqp = boardp->adv_reqp;
10500 boardp->adv_reqp = reqp;
10502 return ret;
10505 ASC_STATS(scp->device->host, sg_cnt);
10506 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
10509 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
10510 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
10512 *adv_scsiqpp = scsiqp;
10514 return ASC_NOERROR;
10517 static int AscSgListToQueue(int sg_list)
10519 int n_sg_list_qs;
10521 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
10522 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
10523 n_sg_list_qs++;
10524 return n_sg_list_qs + 1;
10527 static uint
10528 AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
10530 uint cur_used_qs;
10531 uint cur_free_qs;
10532 ASC_SCSI_BIT_ID_TYPE target_id;
10533 uchar tid_no;
10535 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
10536 tid_no = ASC_TIX_TO_TID(target_ix);
10537 if ((asc_dvc->unit_not_ready & target_id) ||
10538 (asc_dvc->queue_full_or_busy & target_id)) {
10539 return 0;
10541 if (n_qs == 1) {
10542 cur_used_qs = (uint) asc_dvc->cur_total_qng +
10543 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
10544 } else {
10545 cur_used_qs = (uint) asc_dvc->cur_total_qng +
10546 (uint) ASC_MIN_FREE_Q;
10548 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
10549 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
10550 if (asc_dvc->cur_dvc_qng[tid_no] >=
10551 asc_dvc->max_dvc_qng[tid_no]) {
10552 return 0;
10554 return cur_free_qs;
10556 if (n_qs > 1) {
10557 if ((n_qs > asc_dvc->last_q_shortage)
10558 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
10559 asc_dvc->last_q_shortage = n_qs;
10562 return 0;
10565 static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
10567 ushort q_addr;
10568 uchar next_qp;
10569 uchar q_status;
10571 q_addr = ASC_QNO_TO_QADDR(free_q_head);
10572 q_status = (uchar)AscReadLramByte(iop_base,
10573 (ushort)(q_addr +
10574 ASC_SCSIQ_B_STATUS));
10575 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10576 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END))
10577 return next_qp;
10578 return ASC_QLINK_END;
10581 static uchar
10582 AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
10584 uchar i;
10586 for (i = 0; i < n_free_q; i++) {
10587 free_q_head = AscAllocFreeQueue(iop_base, free_q_head);
10588 if (free_q_head == ASC_QLINK_END)
10589 break;
10591 return free_q_head;
10595 * void
10596 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10598 * Calling/Exit State:
10599 * none
10601 * Description:
10602 * Output an ASC_SCSI_Q structure to the chip
10604 static void
10605 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10607 int i;
10609 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
10610 AscSetChipLramAddr(iop_base, s_addr);
10611 for (i = 0; i < 2 * words; i += 2) {
10612 if (i == 4 || i == 20) {
10613 continue;
10615 outpw(iop_base + IOP_RAM_DATA,
10616 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
10620 static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10622 ushort q_addr;
10623 uchar tid_no;
10624 uchar sdtr_data;
10625 uchar syn_period_ix;
10626 uchar syn_offset;
10627 PortAddr iop_base;
10629 iop_base = asc_dvc->iop_base;
10630 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
10631 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
10632 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
10633 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10634 syn_period_ix =
10635 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
10636 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
10637 AscMsgOutSDTR(asc_dvc,
10638 asc_dvc->sdtr_period_tbl[syn_period_ix],
10639 syn_offset);
10640 scsiq->q1.cntl |= QC_MSG_OUT;
10642 q_addr = ASC_QNO_TO_QADDR(q_no);
10643 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
10644 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10646 scsiq->q1.status = QS_FREE;
10647 AscMemWordCopyPtrToLram(iop_base,
10648 q_addr + ASC_SCSIQ_CDB_BEG,
10649 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
10651 DvcPutScsiQ(iop_base,
10652 q_addr + ASC_SCSIQ_CPY_BEG,
10653 (uchar *)&scsiq->q1.cntl,
10654 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
10655 AscWriteLramWord(iop_base,
10656 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
10657 (ushort)(((ushort)scsiq->q1.
10658 q_no << 8) | (ushort)QS_READY));
10659 return 1;
10662 static int
10663 AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10665 int sta;
10666 int i;
10667 ASC_SG_HEAD *sg_head;
10668 ASC_SG_LIST_Q scsi_sg_q;
10669 ASC_DCNT saved_data_addr;
10670 ASC_DCNT saved_data_cnt;
10671 PortAddr iop_base;
10672 ushort sg_list_dwords;
10673 ushort sg_index;
10674 ushort sg_entry_cnt;
10675 ushort q_addr;
10676 uchar next_qp;
10678 iop_base = asc_dvc->iop_base;
10679 sg_head = scsiq->sg_head;
10680 saved_data_addr = scsiq->q1.data_addr;
10681 saved_data_cnt = scsiq->q1.data_cnt;
10682 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
10683 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
10684 #if CC_VERY_LONG_SG_LIST
10686 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
10687 * then not all SG elements will fit in the allocated queues.
10688 * The rest of the SG elements will be copied when the RISC
10689 * completes the SG elements that fit and halts.
10691 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10693 * Set sg_entry_cnt to be the number of SG elements that
10694 * will fit in the allocated SG queues. It is minus 1, because
10695 * the first SG element is handled above. ASC_MAX_SG_LIST is
10696 * already inflated by 1 to account for this. For example it
10697 * may be 50 which is 1 + 7 queues * 7 SG elements.
10699 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10702 * Keep track of remaining number of SG elements that will
10703 * need to be handled from a_isr.c.
10705 scsiq->remain_sg_entry_cnt =
10706 sg_head->entry_cnt - ASC_MAX_SG_LIST;
10707 } else {
10708 #endif /* CC_VERY_LONG_SG_LIST */
10710 * Set sg_entry_cnt to be the number of SG elements that
10711 * will fit in the allocated SG queues. It is minus 1, because
10712 * the first SG element is handled above.
10714 sg_entry_cnt = sg_head->entry_cnt - 1;
10715 #if CC_VERY_LONG_SG_LIST
10717 #endif /* CC_VERY_LONG_SG_LIST */
10718 if (sg_entry_cnt != 0) {
10719 scsiq->q1.cntl |= QC_SG_HEAD;
10720 q_addr = ASC_QNO_TO_QADDR(q_no);
10721 sg_index = 1;
10722 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
10723 scsi_sg_q.sg_head_qp = q_no;
10724 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10725 for (i = 0; i < sg_head->queue_cnt; i++) {
10726 scsi_sg_q.seq_no = i + 1;
10727 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
10728 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
10729 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10730 if (i == 0) {
10731 scsi_sg_q.sg_list_cnt =
10732 ASC_SG_LIST_PER_Q;
10733 scsi_sg_q.sg_cur_list_cnt =
10734 ASC_SG_LIST_PER_Q;
10735 } else {
10736 scsi_sg_q.sg_list_cnt =
10737 ASC_SG_LIST_PER_Q - 1;
10738 scsi_sg_q.sg_cur_list_cnt =
10739 ASC_SG_LIST_PER_Q - 1;
10741 } else {
10742 #if CC_VERY_LONG_SG_LIST
10744 * This is the last SG queue in the list of
10745 * allocated SG queues. If there are more
10746 * SG elements than will fit in the allocated
10747 * queues, then set the QCSG_SG_XFER_MORE flag.
10749 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10750 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10751 } else {
10752 #endif /* CC_VERY_LONG_SG_LIST */
10753 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10754 #if CC_VERY_LONG_SG_LIST
10756 #endif /* CC_VERY_LONG_SG_LIST */
10757 sg_list_dwords = sg_entry_cnt << 1;
10758 if (i == 0) {
10759 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
10760 scsi_sg_q.sg_cur_list_cnt =
10761 sg_entry_cnt;
10762 } else {
10763 scsi_sg_q.sg_list_cnt =
10764 sg_entry_cnt - 1;
10765 scsi_sg_q.sg_cur_list_cnt =
10766 sg_entry_cnt - 1;
10768 sg_entry_cnt = 0;
10770 next_qp = AscReadLramByte(iop_base,
10771 (ushort)(q_addr +
10772 ASC_SCSIQ_B_FWD));
10773 scsi_sg_q.q_no = next_qp;
10774 q_addr = ASC_QNO_TO_QADDR(next_qp);
10775 AscMemWordCopyPtrToLram(iop_base,
10776 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10777 (uchar *)&scsi_sg_q,
10778 sizeof(ASC_SG_LIST_Q) >> 1);
10779 AscMemDWordCopyPtrToLram(iop_base,
10780 q_addr + ASC_SGQ_LIST_BEG,
10781 (uchar *)&sg_head->
10782 sg_list[sg_index],
10783 sg_list_dwords);
10784 sg_index += ASC_SG_LIST_PER_Q;
10785 scsiq->next_sg_index = sg_index;
10787 } else {
10788 scsiq->q1.cntl &= ~QC_SG_HEAD;
10790 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
10791 scsiq->q1.data_addr = saved_data_addr;
10792 scsiq->q1.data_cnt = saved_data_cnt;
10793 return (sta);
10796 static int
10797 AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
10799 PortAddr iop_base;
10800 uchar free_q_head;
10801 uchar next_qp;
10802 uchar tid_no;
10803 uchar target_ix;
10804 int sta;
10806 iop_base = asc_dvc->iop_base;
10807 target_ix = scsiq->q2.target_ix;
10808 tid_no = ASC_TIX_TO_TID(target_ix);
10809 sta = 0;
10810 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
10811 if (n_q_required > 1) {
10812 next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head,
10813 (uchar)n_q_required);
10814 if (next_qp != ASC_QLINK_END) {
10815 asc_dvc->last_q_shortage = 0;
10816 scsiq->sg_head->queue_cnt = n_q_required - 1;
10817 scsiq->q1.q_no = free_q_head;
10818 sta = AscPutReadySgListQueue(asc_dvc, scsiq,
10819 free_q_head);
10821 } else if (n_q_required == 1) {
10822 next_qp = AscAllocFreeQueue(iop_base, free_q_head);
10823 if (next_qp != ASC_QLINK_END) {
10824 scsiq->q1.q_no = free_q_head;
10825 sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head);
10828 if (sta == 1) {
10829 AscPutVarFreeQHead(iop_base, next_qp);
10830 asc_dvc->cur_total_qng += n_q_required;
10831 asc_dvc->cur_dvc_qng[tid_no]++;
10833 return sta;
10836 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
10837 static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
10838 INQUIRY,
10839 REQUEST_SENSE,
10840 READ_CAPACITY,
10841 READ_TOC,
10842 MODE_SELECT,
10843 MODE_SENSE,
10844 MODE_SELECT_10,
10845 MODE_SENSE_10,
10846 0xFF,
10847 0xFF,
10848 0xFF,
10849 0xFF,
10850 0xFF,
10851 0xFF,
10852 0xFF,
10853 0xFF
10856 static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
10858 PortAddr iop_base;
10859 int sta;
10860 int n_q_required;
10861 int disable_syn_offset_one_fix;
10862 int i;
10863 ASC_PADDR addr;
10864 ushort sg_entry_cnt = 0;
10865 ushort sg_entry_cnt_minus_one = 0;
10866 uchar target_ix;
10867 uchar tid_no;
10868 uchar sdtr_data;
10869 uchar extra_bytes;
10870 uchar scsi_cmd;
10871 uchar disable_cmd;
10872 ASC_SG_HEAD *sg_head;
10873 ASC_DCNT data_cnt;
10875 iop_base = asc_dvc->iop_base;
10876 sg_head = scsiq->sg_head;
10877 if (asc_dvc->err_code != 0)
10878 return (ERR);
10879 scsiq->q1.q_no = 0;
10880 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
10881 scsiq->q1.extra_bytes = 0;
10883 sta = 0;
10884 target_ix = scsiq->q2.target_ix;
10885 tid_no = ASC_TIX_TO_TID(target_ix);
10886 n_q_required = 1;
10887 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
10888 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
10889 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
10890 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10891 AscMsgOutSDTR(asc_dvc,
10892 asc_dvc->
10893 sdtr_period_tbl[(sdtr_data >> 4) &
10894 (uchar)(asc_dvc->
10895 max_sdtr_index -
10896 1)],
10897 (uchar)(sdtr_data & (uchar)
10898 ASC_SYN_MAX_OFFSET));
10899 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
10902 if (asc_dvc->in_critical_cnt != 0) {
10903 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
10904 return (ERR);
10906 asc_dvc->in_critical_cnt++;
10907 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10908 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
10909 asc_dvc->in_critical_cnt--;
10910 return (ERR);
10912 #if !CC_VERY_LONG_SG_LIST
10913 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
10914 asc_dvc->in_critical_cnt--;
10915 return (ERR);
10917 #endif /* !CC_VERY_LONG_SG_LIST */
10918 if (sg_entry_cnt == 1) {
10919 scsiq->q1.data_addr =
10920 (ADV_PADDR)sg_head->sg_list[0].addr;
10921 scsiq->q1.data_cnt =
10922 (ADV_DCNT)sg_head->sg_list[0].bytes;
10923 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
10925 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
10927 scsi_cmd = scsiq->cdbptr[0];
10928 disable_syn_offset_one_fix = FALSE;
10929 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
10930 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
10931 if (scsiq->q1.cntl & QC_SG_HEAD) {
10932 data_cnt = 0;
10933 for (i = 0; i < sg_entry_cnt; i++) {
10934 data_cnt +=
10935 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
10936 bytes);
10938 } else {
10939 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10941 if (data_cnt != 0UL) {
10942 if (data_cnt < 512UL) {
10943 disable_syn_offset_one_fix = TRUE;
10944 } else {
10945 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
10946 i++) {
10947 disable_cmd =
10948 _syn_offset_one_disable_cmd[i];
10949 if (disable_cmd == 0xFF) {
10950 break;
10952 if (scsi_cmd == disable_cmd) {
10953 disable_syn_offset_one_fix =
10954 TRUE;
10955 break;
10961 if (disable_syn_offset_one_fix) {
10962 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10963 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
10964 ASC_TAG_FLAG_DISABLE_DISCONNECT);
10965 } else {
10966 scsiq->q2.tag_code &= 0x27;
10968 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10969 if (asc_dvc->bug_fix_cntl) {
10970 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10971 if ((scsi_cmd == READ_6) ||
10972 (scsi_cmd == READ_10)) {
10973 addr =
10974 (ADV_PADDR)le32_to_cpu(sg_head->
10975 sg_list
10976 [sg_entry_cnt_minus_one].
10977 addr) +
10978 (ADV_DCNT)le32_to_cpu(sg_head->
10979 sg_list
10980 [sg_entry_cnt_minus_one].
10981 bytes);
10982 extra_bytes =
10983 (uchar)((ushort)addr & 0x0003);
10984 if ((extra_bytes != 0)
10986 ((scsiq->q2.
10987 tag_code &
10988 ASC_TAG_FLAG_EXTRA_BYTES)
10989 == 0)) {
10990 scsiq->q2.tag_code |=
10991 ASC_TAG_FLAG_EXTRA_BYTES;
10992 scsiq->q1.extra_bytes =
10993 extra_bytes;
10994 data_cnt =
10995 le32_to_cpu(sg_head->
10996 sg_list
10997 [sg_entry_cnt_minus_one].
10998 bytes);
10999 data_cnt -=
11000 (ASC_DCNT) extra_bytes;
11001 sg_head->
11002 sg_list
11003 [sg_entry_cnt_minus_one].
11004 bytes =
11005 cpu_to_le32(data_cnt);
11010 sg_head->entry_to_copy = sg_head->entry_cnt;
11011 #if CC_VERY_LONG_SG_LIST
11013 * Set the sg_entry_cnt to the maximum possible. The rest of
11014 * the SG elements will be copied when the RISC completes the
11015 * SG elements that fit and halts.
11017 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
11018 sg_entry_cnt = ASC_MAX_SG_LIST;
11020 #endif /* CC_VERY_LONG_SG_LIST */
11021 n_q_required = AscSgListToQueue(sg_entry_cnt);
11022 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
11023 (uint) n_q_required)
11024 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11025 if ((sta =
11026 AscSendScsiQueue(asc_dvc, scsiq,
11027 n_q_required)) == 1) {
11028 asc_dvc->in_critical_cnt--;
11029 return (sta);
11032 } else {
11033 if (asc_dvc->bug_fix_cntl) {
11034 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
11035 if ((scsi_cmd == READ_6) ||
11036 (scsi_cmd == READ_10)) {
11037 addr =
11038 le32_to_cpu(scsiq->q1.data_addr) +
11039 le32_to_cpu(scsiq->q1.data_cnt);
11040 extra_bytes =
11041 (uchar)((ushort)addr & 0x0003);
11042 if ((extra_bytes != 0)
11044 ((scsiq->q2.
11045 tag_code &
11046 ASC_TAG_FLAG_EXTRA_BYTES)
11047 == 0)) {
11048 data_cnt =
11049 le32_to_cpu(scsiq->q1.
11050 data_cnt);
11051 if (((ushort)data_cnt & 0x01FF)
11052 == 0) {
11053 scsiq->q2.tag_code |=
11054 ASC_TAG_FLAG_EXTRA_BYTES;
11055 data_cnt -= (ASC_DCNT)
11056 extra_bytes;
11057 scsiq->q1.data_cnt =
11058 cpu_to_le32
11059 (data_cnt);
11060 scsiq->q1.extra_bytes =
11061 extra_bytes;
11067 n_q_required = 1;
11068 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
11069 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11070 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11071 n_q_required)) == 1) {
11072 asc_dvc->in_critical_cnt--;
11073 return (sta);
11077 asc_dvc->in_critical_cnt--;
11078 return (sta);
11082 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
11084 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
11085 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
11086 * RISC to notify it a new command is ready to be executed.
11088 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
11089 * set to SCSI_MAX_RETRY.
11091 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
11092 * for DMA addresses or math operations are byte swapped to little-endian
11093 * order.
11095 * Return:
11096 * ADV_SUCCESS(1) - The request was successfully queued.
11097 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
11098 * request completes.
11099 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
11100 * host IC error.
11102 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
11104 AdvPortAddr iop_base;
11105 ADV_DCNT req_size;
11106 ADV_PADDR req_paddr;
11107 ADV_CARR_T *new_carrp;
11110 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
11112 if (scsiq->target_id > ADV_MAX_TID) {
11113 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
11114 scsiq->done_status = QD_WITH_ERROR;
11115 return ADV_ERROR;
11118 iop_base = asc_dvc->iop_base;
11121 * Allocate a carrier ensuring at least one carrier always
11122 * remains on the freelist and initialize fields.
11124 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
11125 return ADV_BUSY;
11127 asc_dvc->carr_freelist = (ADV_CARR_T *)
11128 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
11129 asc_dvc->carr_pending_cnt++;
11132 * Set the carrier to be a stopper by setting 'next_vpa'
11133 * to the stopper value. The current stopper will be changed
11134 * below to point to the new stopper.
11136 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
11139 * Clear the ADV_SCSI_REQ_Q done flag.
11141 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
11143 req_size = sizeof(ADV_SCSI_REQ_Q);
11144 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
11145 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
11147 BUG_ON(req_paddr & 31);
11148 BUG_ON(req_size < sizeof(ADV_SCSI_REQ_Q));
11150 /* Wait for assertion before making little-endian */
11151 req_paddr = cpu_to_le32(req_paddr);
11153 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
11154 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
11155 scsiq->scsiq_rptr = req_paddr;
11157 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
11159 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
11160 * order during initialization.
11162 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
11165 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
11166 * the microcode. The newly allocated stopper will become the new
11167 * stopper.
11169 asc_dvc->icq_sp->areq_vpa = req_paddr;
11172 * Set the 'next_vpa' pointer for the old stopper to be the
11173 * physical address of the new stopper. The RISC can only
11174 * follow physical addresses.
11176 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
11179 * Set the host adapter stopper pointer to point to the new carrier.
11181 asc_dvc->icq_sp = new_carrp;
11183 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
11184 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
11186 * Tickle the RISC to tell it to read its Command Queue Head pointer.
11188 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
11189 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
11191 * Clear the tickle value. In the ASC-3550 the RISC flag
11192 * command 'clr_tickle_a' does not work unless the host
11193 * value is cleared.
11195 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
11196 ADV_TICKLE_NOP);
11198 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
11200 * Notify the RISC a carrier is ready by writing the physical
11201 * address of the new carrier stopper to the COMMA register.
11203 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
11204 le32_to_cpu(new_carrp->carr_pa));
11207 return ADV_SUCCESS;
11211 * Execute a single 'Scsi_Cmnd'.
11213 * The function 'done' is called when the request has been completed.
11215 * Scsi_Cmnd:
11217 * host - board controlling device
11218 * device - device to send command
11219 * target - target of device
11220 * lun - lun of device
11221 * cmd_len - length of SCSI CDB
11222 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
11223 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
11225 * if (use_sg == 0) {
11226 * request_buffer - buffer address for request
11227 * request_bufflen - length of request buffer
11228 * } else {
11229 * request_buffer - pointer to scatterlist structure
11232 * sense_buffer - sense command buffer
11234 * result (4 bytes of an int):
11235 * Byte Meaning
11236 * 0 SCSI Status Byte Code
11237 * 1 SCSI One Byte Message Code
11238 * 2 Host Error Code
11239 * 3 Mid-Level Error Code
11241 * host driver fields:
11242 * SCp - Scsi_Pointer used for command processing status
11243 * scsi_done - used to save caller's done function
11244 * host_scribble - used for pointer to another struct scsi_cmnd
11246 * If this function returns ASC_NOERROR the request will be completed
11247 * from the interrupt handler.
11249 * If this function returns ASC_ERROR the host error code has been set,
11250 * and the called must call asc_scsi_done.
11252 * If ASC_BUSY is returned the request will be returned to the midlayer
11253 * and re-tried later.
11255 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
11257 int ret, err_code;
11258 asc_board_t *boardp = ASC_BOARDP(scp->device->host);
11260 ASC_DBG1(1, "asc_execute_scsi_cmnd: scp 0x%p\n", scp);
11262 if (ASC_NARROW_BOARD(boardp)) {
11263 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
11264 struct asc_scsi_q asc_scsi_q;
11266 /* asc_build_req() can not return ASC_BUSY. */
11267 ret = asc_build_req(boardp, scp, &asc_scsi_q);
11268 if (ret == ASC_ERROR) {
11269 ASC_STATS(scp->device->host, build_error);
11270 return ASC_ERROR;
11273 ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q);
11274 kfree(asc_scsi_q.sg_head);
11275 err_code = asc_dvc->err_code;
11276 } else {
11277 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
11278 ADV_SCSI_REQ_Q *adv_scsiqp;
11280 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
11281 case ASC_NOERROR:
11282 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req "
11283 "ASC_NOERROR\n");
11284 break;
11285 case ASC_BUSY:
11286 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
11287 "ASC_BUSY\n");
11289 * The asc_stats fields 'adv_build_noreq' and
11290 * 'adv_build_nosg' count wide board busy conditions.
11291 * They are updated in adv_build_req and
11292 * adv_get_sglist, respectively.
11294 return ASC_BUSY;
11295 case ASC_ERROR:
11296 default:
11297 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
11298 "ASC_ERROR\n");
11299 ASC_STATS(scp->device->host, build_error);
11300 return ASC_ERROR;
11303 ret = AdvExeScsiQueue(adv_dvc, adv_scsiqp);
11304 err_code = adv_dvc->err_code;
11307 switch (ret) {
11308 case ASC_NOERROR:
11309 ASC_STATS(scp->device->host, exe_noerror);
11311 * Increment monotonically increasing per device
11312 * successful request counter. Wrapping doesn't matter.
11314 boardp->reqcnt[scp->device->id]++;
11315 ASC_DBG(1, "asc_execute_scsi_cmnd: ExeScsiQueue(), "
11316 "ASC_NOERROR\n");
11317 break;
11318 case ASC_BUSY:
11319 ASC_STATS(scp->device->host, exe_busy);
11320 break;
11321 case ASC_ERROR:
11322 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: ExeScsiQueue() "
11323 "ASC_ERROR, err_code 0x%x\n", boardp->id, err_code);
11324 ASC_STATS(scp->device->host, exe_error);
11325 scp->result = HOST_BYTE(DID_ERROR);
11326 break;
11327 default:
11328 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: ExeScsiQueue() "
11329 "unknown, err_code 0x%x\n", boardp->id, err_code);
11330 ASC_STATS(scp->device->host, exe_unknown);
11331 scp->result = HOST_BYTE(DID_ERROR);
11332 break;
11335 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
11336 return ret;
11340 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
11342 * This function always returns 0. Command return status is saved
11343 * in the 'scp' result field.
11345 static int
11346 advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
11348 struct Scsi_Host *shost = scp->device->host;
11349 asc_board_t *boardp = ASC_BOARDP(shost);
11350 unsigned long flags;
11351 int asc_res, result = 0;
11353 ASC_STATS(shost, queuecommand);
11354 scp->scsi_done = done;
11357 * host_lock taken by mid-level prior to call, but need
11358 * to protect against own ISR
11360 spin_lock_irqsave(&boardp->lock, flags);
11361 asc_res = asc_execute_scsi_cmnd(scp);
11362 spin_unlock_irqrestore(&boardp->lock, flags);
11364 switch (asc_res) {
11365 case ASC_NOERROR:
11366 break;
11367 case ASC_BUSY:
11368 result = SCSI_MLQUEUE_HOST_BUSY;
11369 break;
11370 case ASC_ERROR:
11371 default:
11372 asc_scsi_done(scp);
11373 break;
11376 return result;
11379 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
11381 PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11382 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
11383 return inpw(eisa_cfg_iop);
11387 * Return the BIOS address of the adapter at the specified
11388 * I/O port and with the specified bus type.
11390 static unsigned short __devinit
11391 AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
11393 unsigned short cfg_lsw;
11394 unsigned short bios_addr;
11397 * The PCI BIOS is re-located by the motherboard BIOS. Because
11398 * of this the driver can not determine where a PCI BIOS is
11399 * loaded and executes.
11401 if (bus_type & ASC_IS_PCI)
11402 return 0;
11404 if ((bus_type & ASC_IS_EISA) != 0) {
11405 cfg_lsw = AscGetEisaChipCfg(iop_base);
11406 cfg_lsw &= 0x000F;
11407 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
11408 return bios_addr;
11411 cfg_lsw = AscGetChipCfgLsw(iop_base);
11414 * ISA PnP uses the top bit as the 32K BIOS flag
11416 if (bus_type == ASC_IS_ISAPNP)
11417 cfg_lsw &= 0x7FFF;
11418 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
11419 return bios_addr;
11422 static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
11424 ushort cfg_lsw;
11426 if (AscGetChipScsiID(iop_base) == new_host_id) {
11427 return (new_host_id);
11429 cfg_lsw = AscGetChipCfgLsw(iop_base);
11430 cfg_lsw &= 0xF8FF;
11431 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
11432 AscSetChipCfgLsw(iop_base, cfg_lsw);
11433 return (AscGetChipScsiID(iop_base));
11436 static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
11438 unsigned char sc;
11440 AscSetBank(iop_base, 1);
11441 sc = inp(iop_base + IOP_REG_SC);
11442 AscSetBank(iop_base, 0);
11443 return sc;
11446 static unsigned char __devinit
11447 AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
11449 if (bus_type & ASC_IS_EISA) {
11450 PortAddr eisa_iop;
11451 unsigned char revision;
11452 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11453 (PortAddr) ASC_EISA_REV_IOP_MASK;
11454 revision = inp(eisa_iop);
11455 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
11457 return AscGetChipVerNo(iop_base);
11460 #ifdef CONFIG_ISA
11461 static void __devinit AscEnableIsaDma(uchar dma_channel)
11463 if (dma_channel < 4) {
11464 outp(0x000B, (ushort)(0xC0 | dma_channel));
11465 outp(0x000A, dma_channel);
11466 } else if (dma_channel < 8) {
11467 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
11468 outp(0x00D4, (ushort)(dma_channel - 4));
11470 return;
11472 #endif /* CONFIG_ISA */
11474 static int AscStopQueueExe(PortAddr iop_base)
11476 int count = 0;
11478 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11479 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11480 ASC_STOP_REQ_RISC_STOP);
11481 do {
11482 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11483 ASC_STOP_ACK_RISC_STOP) {
11484 return (1);
11486 mdelay(100);
11487 } while (count++ < 20);
11489 return (0);
11492 static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
11494 if (bus_type & ASC_IS_ISA)
11495 return ASC_MAX_ISA_DMA_COUNT;
11496 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
11497 return ASC_MAX_VL_DMA_COUNT;
11498 return ASC_MAX_PCI_DMA_COUNT;
11501 #ifdef CONFIG_ISA
11502 static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
11504 ushort channel;
11506 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
11507 if (channel == 0x03)
11508 return (0);
11509 else if (channel == 0x00)
11510 return (7);
11511 return (channel + 4);
11514 static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
11516 ushort cfg_lsw;
11517 uchar value;
11519 if ((dma_channel >= 5) && (dma_channel <= 7)) {
11520 if (dma_channel == 7)
11521 value = 0x00;
11522 else
11523 value = dma_channel - 4;
11524 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
11525 cfg_lsw |= value;
11526 AscSetChipCfgLsw(iop_base, cfg_lsw);
11527 return (AscGetIsaDmaChannel(iop_base));
11529 return 0;
11532 static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
11534 uchar speed_value;
11536 AscSetBank(iop_base, 1);
11537 speed_value = AscReadChipDmaSpeed(iop_base);
11538 speed_value &= 0x07;
11539 AscSetBank(iop_base, 0);
11540 return speed_value;
11543 static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
11545 speed_value &= 0x07;
11546 AscSetBank(iop_base, 1);
11547 AscWriteChipDmaSpeed(iop_base, speed_value);
11548 AscSetBank(iop_base, 0);
11549 return AscGetIsaDmaSpeed(iop_base);
11551 #endif /* CONFIG_ISA */
11553 static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
11555 int i;
11556 PortAddr iop_base;
11557 ushort warn_code;
11558 uchar chip_version;
11560 iop_base = asc_dvc->iop_base;
11561 warn_code = 0;
11562 asc_dvc->err_code = 0;
11563 if ((asc_dvc->bus_type &
11564 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
11565 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
11567 AscSetChipControl(iop_base, CC_HALT);
11568 AscSetChipStatus(iop_base, 0);
11569 asc_dvc->bug_fix_cntl = 0;
11570 asc_dvc->pci_fix_asyn_xfer = 0;
11571 asc_dvc->pci_fix_asyn_xfer_always = 0;
11572 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
11573 asc_dvc->sdtr_done = 0;
11574 asc_dvc->cur_total_qng = 0;
11575 asc_dvc->is_in_int = 0;
11576 asc_dvc->in_critical_cnt = 0;
11577 asc_dvc->last_q_shortage = 0;
11578 asc_dvc->use_tagged_qng = 0;
11579 asc_dvc->no_scam = 0;
11580 asc_dvc->unit_not_ready = 0;
11581 asc_dvc->queue_full_or_busy = 0;
11582 asc_dvc->redo_scam = 0;
11583 asc_dvc->res2 = 0;
11584 asc_dvc->host_init_sdtr_index = 0;
11585 asc_dvc->cfg->can_tagged_qng = 0;
11586 asc_dvc->cfg->cmd_qng_enabled = 0;
11587 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
11588 asc_dvc->init_sdtr = 0;
11589 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
11590 asc_dvc->scsi_reset_wait = 3;
11591 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
11592 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
11593 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
11594 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
11595 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
11596 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
11597 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
11598 ASC_LIB_VERSION_MINOR;
11599 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
11600 asc_dvc->cfg->chip_version = chip_version;
11601 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
11602 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
11603 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
11604 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
11605 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
11606 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
11607 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
11608 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
11609 asc_dvc->max_sdtr_index = 7;
11610 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
11611 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
11612 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
11613 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
11614 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
11615 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
11616 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
11617 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
11618 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
11619 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
11620 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
11621 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
11622 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
11623 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
11624 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
11625 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
11626 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
11627 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
11628 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
11629 asc_dvc->max_sdtr_index = 15;
11630 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
11631 AscSetExtraControl(iop_base,
11632 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11633 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
11634 AscSetExtraControl(iop_base,
11635 (SEC_ACTIVE_NEGATE |
11636 SEC_ENABLE_FILTER));
11639 if (asc_dvc->bus_type == ASC_IS_PCI) {
11640 AscSetExtraControl(iop_base,
11641 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11644 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
11645 #ifdef CONFIG_ISA
11646 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
11647 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
11648 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
11649 asc_dvc->bus_type = ASC_IS_ISAPNP;
11651 asc_dvc->cfg->isa_dma_channel =
11652 (uchar)AscGetIsaDmaChannel(iop_base);
11654 #endif /* CONFIG_ISA */
11655 for (i = 0; i <= ASC_MAX_TID; i++) {
11656 asc_dvc->cur_dvc_qng[i] = 0;
11657 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
11658 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
11659 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
11660 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
11662 return warn_code;
11665 static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
11667 int retry;
11669 for (retry = 0; retry < ASC_EEP_MAX_RETRY; retry++) {
11670 unsigned char read_back;
11671 AscSetChipEEPCmd(iop_base, cmd_reg);
11672 mdelay(1);
11673 read_back = AscGetChipEEPCmd(iop_base);
11674 if (read_back == cmd_reg)
11675 return 1;
11677 return 0;
11680 static void __devinit AscWaitEEPRead(void)
11682 mdelay(1);
11685 static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
11687 ushort read_wval;
11688 uchar cmd_reg;
11690 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11691 AscWaitEEPRead();
11692 cmd_reg = addr | ASC_EEP_CMD_READ;
11693 AscWriteEEPCmdReg(iop_base, cmd_reg);
11694 AscWaitEEPRead();
11695 read_wval = AscGetChipEEPData(iop_base);
11696 AscWaitEEPRead();
11697 return read_wval;
11700 static ushort __devinit
11701 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11703 ushort wval;
11704 ushort sum;
11705 ushort *wbuf;
11706 int cfg_beg;
11707 int cfg_end;
11708 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11709 int s_addr;
11711 wbuf = (ushort *)cfg_buf;
11712 sum = 0;
11713 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
11714 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11715 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11716 sum += *wbuf;
11718 if (bus_type & ASC_IS_VL) {
11719 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11720 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11721 } else {
11722 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11723 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11725 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11726 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
11727 if (s_addr <= uchar_end_in_config) {
11729 * Swap all char fields - must unswap bytes already swapped
11730 * by AscReadEEPWord().
11732 *wbuf = le16_to_cpu(wval);
11733 } else {
11734 /* Don't swap word field at the end - cntl field. */
11735 *wbuf = wval;
11737 sum += wval; /* Checksum treats all EEPROM data as words. */
11740 * Read the checksum word which will be compared against 'sum'
11741 * by the caller. Word field already swapped.
11743 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11744 return sum;
11747 static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
11749 PortAddr iop_base;
11750 ushort q_addr;
11751 ushort saved_word;
11752 int sta;
11754 iop_base = asc_dvc->iop_base;
11755 sta = 0;
11756 q_addr = ASC_QNO_TO_QADDR(241);
11757 saved_word = AscReadLramWord(iop_base, q_addr);
11758 AscSetChipLramAddr(iop_base, q_addr);
11759 AscSetChipLramData(iop_base, 0x55AA);
11760 mdelay(10);
11761 AscSetChipLramAddr(iop_base, q_addr);
11762 if (AscGetChipLramData(iop_base) == 0x55AA) {
11763 sta = 1;
11764 AscWriteLramWord(iop_base, q_addr, saved_word);
11766 return (sta);
11769 static void __devinit AscWaitEEPWrite(void)
11771 mdelay(20);
11772 return;
11775 static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
11777 ushort read_back;
11778 int retry;
11780 retry = 0;
11781 while (TRUE) {
11782 AscSetChipEEPData(iop_base, data_reg);
11783 mdelay(1);
11784 read_back = AscGetChipEEPData(iop_base);
11785 if (read_back == data_reg) {
11786 return (1);
11788 if (retry++ > ASC_EEP_MAX_RETRY) {
11789 return (0);
11794 static ushort __devinit
11795 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
11797 ushort read_wval;
11799 read_wval = AscReadEEPWord(iop_base, addr);
11800 if (read_wval != word_val) {
11801 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
11802 AscWaitEEPRead();
11803 AscWriteEEPDataReg(iop_base, word_val);
11804 AscWaitEEPRead();
11805 AscWriteEEPCmdReg(iop_base,
11806 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
11807 AscWaitEEPWrite();
11808 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11809 AscWaitEEPRead();
11810 return (AscReadEEPWord(iop_base, addr));
11812 return (read_wval);
11815 static int __devinit
11816 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11818 int n_error;
11819 ushort *wbuf;
11820 ushort word;
11821 ushort sum;
11822 int s_addr;
11823 int cfg_beg;
11824 int cfg_end;
11825 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11827 wbuf = (ushort *)cfg_buf;
11828 n_error = 0;
11829 sum = 0;
11830 /* Write two config words; AscWriteEEPWord() will swap bytes. */
11831 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11832 sum += *wbuf;
11833 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11834 n_error++;
11837 if (bus_type & ASC_IS_VL) {
11838 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11839 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11840 } else {
11841 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11842 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11844 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11845 if (s_addr <= uchar_end_in_config) {
11847 * This is a char field. Swap char fields before they are
11848 * swapped again by AscWriteEEPWord().
11850 word = cpu_to_le16(*wbuf);
11851 if (word !=
11852 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11853 n_error++;
11855 } else {
11856 /* Don't swap word field at the end - cntl field. */
11857 if (*wbuf !=
11858 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11859 n_error++;
11862 sum += *wbuf; /* Checksum calculated from word values. */
11864 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
11865 *wbuf = sum;
11866 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
11867 n_error++;
11870 /* Read EEPROM back again. */
11871 wbuf = (ushort *)cfg_buf;
11873 * Read two config words; Byte-swapping done by AscReadEEPWord().
11875 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11876 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11877 n_error++;
11880 if (bus_type & ASC_IS_VL) {
11881 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11882 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11883 } else {
11884 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11885 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11887 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11888 if (s_addr <= uchar_end_in_config) {
11890 * Swap all char fields. Must unswap bytes already swapped
11891 * by AscReadEEPWord().
11893 word =
11894 le16_to_cpu(AscReadEEPWord
11895 (iop_base, (uchar)s_addr));
11896 } else {
11897 /* Don't swap word field at the end - cntl field. */
11898 word = AscReadEEPWord(iop_base, (uchar)s_addr);
11900 if (*wbuf != word) {
11901 n_error++;
11904 /* Read checksum; Byte swapping not needed. */
11905 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11906 n_error++;
11908 return n_error;
11911 static int __devinit
11912 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11914 int retry;
11915 int n_error;
11917 retry = 0;
11918 while (TRUE) {
11919 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11920 bus_type)) == 0) {
11921 break;
11923 if (++retry > ASC_EEP_MAX_RETRY) {
11924 break;
11927 return n_error;
11930 static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
11932 ASCEEP_CONFIG eep_config_buf;
11933 ASCEEP_CONFIG *eep_config;
11934 PortAddr iop_base;
11935 ushort chksum;
11936 ushort warn_code;
11937 ushort cfg_msw, cfg_lsw;
11938 int i;
11939 int write_eep = 0;
11941 iop_base = asc_dvc->iop_base;
11942 warn_code = 0;
11943 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
11944 AscStopQueueExe(iop_base);
11945 if ((AscStopChip(iop_base) == FALSE) ||
11946 (AscGetChipScsiCtrl(iop_base) != 0)) {
11947 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
11948 AscResetChipAndScsiBus(asc_dvc);
11949 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
11951 if (AscIsChipHalted(iop_base) == FALSE) {
11952 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
11953 return (warn_code);
11955 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
11956 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
11957 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
11958 return (warn_code);
11960 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
11961 cfg_msw = AscGetChipCfgMsw(iop_base);
11962 cfg_lsw = AscGetChipCfgLsw(iop_base);
11963 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
11964 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11965 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
11966 AscSetChipCfgMsw(iop_base, cfg_msw);
11968 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
11969 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
11970 if (chksum == 0) {
11971 chksum = 0xaa55;
11973 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
11974 warn_code |= ASC_WARN_AUTO_CONFIG;
11975 if (asc_dvc->cfg->chip_version == 3) {
11976 if (eep_config->cfg_lsw != cfg_lsw) {
11977 warn_code |= ASC_WARN_EEPROM_RECOVER;
11978 eep_config->cfg_lsw =
11979 AscGetChipCfgLsw(iop_base);
11981 if (eep_config->cfg_msw != cfg_msw) {
11982 warn_code |= ASC_WARN_EEPROM_RECOVER;
11983 eep_config->cfg_msw =
11984 AscGetChipCfgMsw(iop_base);
11988 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11989 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
11990 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
11991 eep_config->chksum);
11992 if (chksum != eep_config->chksum) {
11993 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
11994 ASC_CHIP_VER_PCI_ULTRA_3050) {
11995 ASC_DBG(1,
11996 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
11997 eep_config->init_sdtr = 0xFF;
11998 eep_config->disc_enable = 0xFF;
11999 eep_config->start_motor = 0xFF;
12000 eep_config->use_cmd_qng = 0;
12001 eep_config->max_total_qng = 0xF0;
12002 eep_config->max_tag_qng = 0x20;
12003 eep_config->cntl = 0xBFFF;
12004 ASC_EEP_SET_CHIP_ID(eep_config, 7);
12005 eep_config->no_scam = 0;
12006 eep_config->adapter_info[0] = 0;
12007 eep_config->adapter_info[1] = 0;
12008 eep_config->adapter_info[2] = 0;
12009 eep_config->adapter_info[3] = 0;
12010 eep_config->adapter_info[4] = 0;
12011 /* Indicate EEPROM-less board. */
12012 eep_config->adapter_info[5] = 0xBB;
12013 } else {
12014 ASC_PRINT
12015 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
12016 write_eep = 1;
12017 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12020 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
12021 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
12022 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
12023 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
12024 asc_dvc->start_motor = eep_config->start_motor;
12025 asc_dvc->dvc_cntl = eep_config->cntl;
12026 asc_dvc->no_scam = eep_config->no_scam;
12027 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
12028 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
12029 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
12030 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
12031 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
12032 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
12033 if (!AscTestExternalLram(asc_dvc)) {
12034 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
12035 ASC_IS_PCI_ULTRA)) {
12036 eep_config->max_total_qng =
12037 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
12038 eep_config->max_tag_qng =
12039 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
12040 } else {
12041 eep_config->cfg_msw |= 0x0800;
12042 cfg_msw |= 0x0800;
12043 AscSetChipCfgMsw(iop_base, cfg_msw);
12044 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
12045 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
12047 } else {
12049 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
12050 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
12052 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
12053 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
12055 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
12056 eep_config->max_tag_qng = eep_config->max_total_qng;
12058 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
12059 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
12061 asc_dvc->max_total_qng = eep_config->max_total_qng;
12062 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
12063 eep_config->use_cmd_qng) {
12064 eep_config->disc_enable = eep_config->use_cmd_qng;
12065 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12067 ASC_EEP_SET_CHIP_ID(eep_config,
12068 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
12069 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
12070 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
12071 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
12072 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
12075 for (i = 0; i <= ASC_MAX_TID; i++) {
12076 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
12077 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
12078 asc_dvc->cfg->sdtr_period_offset[i] =
12079 (uchar)(ASC_DEF_SDTR_OFFSET |
12080 (asc_dvc->host_init_sdtr_index << 4));
12082 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12083 if (write_eep) {
12084 if ((i = AscSetEEPConfig(iop_base, eep_config,
12085 asc_dvc->bus_type)) != 0) {
12086 ASC_PRINT1
12087 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
12089 } else {
12090 ASC_PRINT
12091 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
12094 return (warn_code);
12097 static int __devinit AscInitGetConfig(asc_board_t *boardp)
12099 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
12100 unsigned short warn_code = 0;
12102 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
12103 if (asc_dvc->err_code != 0)
12104 return asc_dvc->err_code;
12106 if (AscFindSignature(asc_dvc->iop_base)) {
12107 warn_code |= AscInitAscDvcVar(asc_dvc);
12108 warn_code |= AscInitFromEEP(asc_dvc);
12109 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
12110 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
12111 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
12112 } else {
12113 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12116 switch (warn_code) {
12117 case 0: /* No error */
12118 break;
12119 case ASC_WARN_IO_PORT_ROTATE:
12120 ASC_PRINT1("AscInitGetConfig: board %d: I/O port address "
12121 "modified\n", boardp->id);
12122 break;
12123 case ASC_WARN_AUTO_CONFIG:
12124 ASC_PRINT1("AscInitGetConfig: board %d: I/O port increment "
12125 "switch enabled\n", boardp->id);
12126 break;
12127 case ASC_WARN_EEPROM_CHKSUM:
12128 ASC_PRINT1("AscInitGetConfig: board %d: EEPROM checksum "
12129 "error\n", boardp->id);
12130 break;
12131 case ASC_WARN_IRQ_MODIFIED:
12132 ASC_PRINT1("AscInitGetConfig: board %d: IRQ modified\n",
12133 boardp->id);
12134 break;
12135 case ASC_WARN_CMD_QNG_CONFLICT:
12136 ASC_PRINT1("AscInitGetConfig: board %d: tag queuing enabled "
12137 "w/o disconnects\n", boardp->id);
12138 break;
12139 default:
12140 ASC_PRINT2("AscInitGetConfig: board %d: unknown warning: "
12141 "0x%x\n", boardp->id, warn_code);
12142 break;
12145 if (asc_dvc->err_code != 0) {
12146 ASC_PRINT3("AscInitGetConfig: board %d error: init_state 0x%x, "
12147 "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
12148 asc_dvc->err_code);
12151 return asc_dvc->err_code;
12154 static int __devinit AscInitSetConfig(struct pci_dev *pdev, asc_board_t *boardp)
12156 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
12157 PortAddr iop_base = asc_dvc->iop_base;
12158 unsigned short cfg_msw;
12159 unsigned short warn_code = 0;
12161 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
12162 if (asc_dvc->err_code != 0)
12163 return asc_dvc->err_code;
12164 if (!AscFindSignature(asc_dvc->iop_base)) {
12165 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12166 return asc_dvc->err_code;
12169 cfg_msw = AscGetChipCfgMsw(iop_base);
12170 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12171 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
12172 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12173 AscSetChipCfgMsw(iop_base, cfg_msw);
12175 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
12176 asc_dvc->cfg->cmd_qng_enabled) {
12177 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
12178 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12180 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12181 warn_code |= ASC_WARN_AUTO_CONFIG;
12183 #ifdef CONFIG_PCI
12184 if (asc_dvc->bus_type & ASC_IS_PCI) {
12185 cfg_msw &= 0xFFC0;
12186 AscSetChipCfgMsw(iop_base, cfg_msw);
12187 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
12188 } else {
12189 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
12190 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
12191 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
12192 asc_dvc->bug_fix_cntl |=
12193 ASC_BUG_FIX_ASYN_USE_SYN;
12196 } else
12197 #endif /* CONFIG_PCI */
12198 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
12199 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
12200 == ASC_CHIP_VER_ASYN_BUG) {
12201 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12204 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
12205 asc_dvc->cfg->chip_scsi_id) {
12206 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
12208 #ifdef CONFIG_ISA
12209 if (asc_dvc->bus_type & ASC_IS_ISA) {
12210 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
12211 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
12213 #endif /* CONFIG_ISA */
12215 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
12217 switch (warn_code) {
12218 case 0: /* No error. */
12219 break;
12220 case ASC_WARN_IO_PORT_ROTATE:
12221 ASC_PRINT1("AscInitSetConfig: board %d: I/O port address "
12222 "modified\n", boardp->id);
12223 break;
12224 case ASC_WARN_AUTO_CONFIG:
12225 ASC_PRINT1("AscInitSetConfig: board %d: I/O port increment "
12226 "switch enabled\n", boardp->id);
12227 break;
12228 case ASC_WARN_EEPROM_CHKSUM:
12229 ASC_PRINT1("AscInitSetConfig: board %d: EEPROM checksum "
12230 "error\n", boardp->id);
12231 break;
12232 case ASC_WARN_IRQ_MODIFIED:
12233 ASC_PRINT1("AscInitSetConfig: board %d: IRQ modified\n",
12234 boardp->id);
12235 break;
12236 case ASC_WARN_CMD_QNG_CONFLICT:
12237 ASC_PRINT1("AscInitSetConfig: board %d: tag queuing w/o "
12238 "disconnects\n",
12239 boardp->id);
12240 break;
12241 default:
12242 ASC_PRINT2("AscInitSetConfig: board %d: unknown warning: "
12243 "0x%x\n", boardp->id, warn_code);
12244 break;
12247 if (asc_dvc->err_code != 0) {
12248 ASC_PRINT3("AscInitSetConfig: board %d error: init_state 0x%x, "
12249 "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
12250 asc_dvc->err_code);
12253 return asc_dvc->err_code;
12257 * EEPROM Configuration.
12259 * All drivers should use this structure to set the default EEPROM
12260 * configuration. The BIOS now uses this structure when it is built.
12261 * Additional structure information can be found in a_condor.h where
12262 * the structure is defined.
12264 * The *_Field_IsChar structs are needed to correct for endianness.
12265 * These values are read from the board 16 bits at a time directly
12266 * into the structs. Because some fields are char, the values will be
12267 * in the wrong order. The *_Field_IsChar tells when to flip the
12268 * bytes. Data read and written to PCI memory is automatically swapped
12269 * on big-endian platforms so char fields read as words are actually being
12270 * unswapped on big-endian platforms.
12272 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
12273 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
12274 0x0000, /* cfg_msw */
12275 0xFFFF, /* disc_enable */
12276 0xFFFF, /* wdtr_able */
12277 0xFFFF, /* sdtr_able */
12278 0xFFFF, /* start_motor */
12279 0xFFFF, /* tagqng_able */
12280 0xFFFF, /* bios_scan */
12281 0, /* scam_tolerant */
12282 7, /* adapter_scsi_id */
12283 0, /* bios_boot_delay */
12284 3, /* scsi_reset_delay */
12285 0, /* bios_id_lun */
12286 0, /* termination */
12287 0, /* reserved1 */
12288 0xFFE7, /* bios_ctrl */
12289 0xFFFF, /* ultra_able */
12290 0, /* reserved2 */
12291 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
12292 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
12293 0, /* dvc_cntl */
12294 0, /* bug_fix */
12295 0, /* serial_number_word1 */
12296 0, /* serial_number_word2 */
12297 0, /* serial_number_word3 */
12298 0, /* check_sum */
12299 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12300 , /* oem_name[16] */
12301 0, /* dvc_err_code */
12302 0, /* adv_err_code */
12303 0, /* adv_err_addr */
12304 0, /* saved_dvc_err_code */
12305 0, /* saved_adv_err_code */
12306 0, /* saved_adv_err_addr */
12307 0 /* num_of_err */
12310 static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
12311 0, /* cfg_lsw */
12312 0, /* cfg_msw */
12313 0, /* -disc_enable */
12314 0, /* wdtr_able */
12315 0, /* sdtr_able */
12316 0, /* start_motor */
12317 0, /* tagqng_able */
12318 0, /* bios_scan */
12319 0, /* scam_tolerant */
12320 1, /* adapter_scsi_id */
12321 1, /* bios_boot_delay */
12322 1, /* scsi_reset_delay */
12323 1, /* bios_id_lun */
12324 1, /* termination */
12325 1, /* reserved1 */
12326 0, /* bios_ctrl */
12327 0, /* ultra_able */
12328 0, /* reserved2 */
12329 1, /* max_host_qng */
12330 1, /* max_dvc_qng */
12331 0, /* dvc_cntl */
12332 0, /* bug_fix */
12333 0, /* serial_number_word1 */
12334 0, /* serial_number_word2 */
12335 0, /* serial_number_word3 */
12336 0, /* check_sum */
12337 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12338 , /* oem_name[16] */
12339 0, /* dvc_err_code */
12340 0, /* adv_err_code */
12341 0, /* adv_err_addr */
12342 0, /* saved_dvc_err_code */
12343 0, /* saved_adv_err_code */
12344 0, /* saved_adv_err_addr */
12345 0 /* num_of_err */
12348 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
12349 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
12350 0x0000, /* 01 cfg_msw */
12351 0xFFFF, /* 02 disc_enable */
12352 0xFFFF, /* 03 wdtr_able */
12353 0x4444, /* 04 sdtr_speed1 */
12354 0xFFFF, /* 05 start_motor */
12355 0xFFFF, /* 06 tagqng_able */
12356 0xFFFF, /* 07 bios_scan */
12357 0, /* 08 scam_tolerant */
12358 7, /* 09 adapter_scsi_id */
12359 0, /* bios_boot_delay */
12360 3, /* 10 scsi_reset_delay */
12361 0, /* bios_id_lun */
12362 0, /* 11 termination_se */
12363 0, /* termination_lvd */
12364 0xFFE7, /* 12 bios_ctrl */
12365 0x4444, /* 13 sdtr_speed2 */
12366 0x4444, /* 14 sdtr_speed3 */
12367 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
12368 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
12369 0, /* 16 dvc_cntl */
12370 0x4444, /* 17 sdtr_speed4 */
12371 0, /* 18 serial_number_word1 */
12372 0, /* 19 serial_number_word2 */
12373 0, /* 20 serial_number_word3 */
12374 0, /* 21 check_sum */
12375 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12376 , /* 22-29 oem_name[16] */
12377 0, /* 30 dvc_err_code */
12378 0, /* 31 adv_err_code */
12379 0, /* 32 adv_err_addr */
12380 0, /* 33 saved_dvc_err_code */
12381 0, /* 34 saved_adv_err_code */
12382 0, /* 35 saved_adv_err_addr */
12383 0, /* 36 reserved */
12384 0, /* 37 reserved */
12385 0, /* 38 reserved */
12386 0, /* 39 reserved */
12387 0, /* 40 reserved */
12388 0, /* 41 reserved */
12389 0, /* 42 reserved */
12390 0, /* 43 reserved */
12391 0, /* 44 reserved */
12392 0, /* 45 reserved */
12393 0, /* 46 reserved */
12394 0, /* 47 reserved */
12395 0, /* 48 reserved */
12396 0, /* 49 reserved */
12397 0, /* 50 reserved */
12398 0, /* 51 reserved */
12399 0, /* 52 reserved */
12400 0, /* 53 reserved */
12401 0, /* 54 reserved */
12402 0, /* 55 reserved */
12403 0, /* 56 cisptr_lsw */
12404 0, /* 57 cisprt_msw */
12405 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
12406 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
12407 0, /* 60 reserved */
12408 0, /* 61 reserved */
12409 0, /* 62 reserved */
12410 0 /* 63 reserved */
12413 static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
12414 0, /* 00 cfg_lsw */
12415 0, /* 01 cfg_msw */
12416 0, /* 02 disc_enable */
12417 0, /* 03 wdtr_able */
12418 0, /* 04 sdtr_speed1 */
12419 0, /* 05 start_motor */
12420 0, /* 06 tagqng_able */
12421 0, /* 07 bios_scan */
12422 0, /* 08 scam_tolerant */
12423 1, /* 09 adapter_scsi_id */
12424 1, /* bios_boot_delay */
12425 1, /* 10 scsi_reset_delay */
12426 1, /* bios_id_lun */
12427 1, /* 11 termination_se */
12428 1, /* termination_lvd */
12429 0, /* 12 bios_ctrl */
12430 0, /* 13 sdtr_speed2 */
12431 0, /* 14 sdtr_speed3 */
12432 1, /* 15 max_host_qng */
12433 1, /* max_dvc_qng */
12434 0, /* 16 dvc_cntl */
12435 0, /* 17 sdtr_speed4 */
12436 0, /* 18 serial_number_word1 */
12437 0, /* 19 serial_number_word2 */
12438 0, /* 20 serial_number_word3 */
12439 0, /* 21 check_sum */
12440 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12441 , /* 22-29 oem_name[16] */
12442 0, /* 30 dvc_err_code */
12443 0, /* 31 adv_err_code */
12444 0, /* 32 adv_err_addr */
12445 0, /* 33 saved_dvc_err_code */
12446 0, /* 34 saved_adv_err_code */
12447 0, /* 35 saved_adv_err_addr */
12448 0, /* 36 reserved */
12449 0, /* 37 reserved */
12450 0, /* 38 reserved */
12451 0, /* 39 reserved */
12452 0, /* 40 reserved */
12453 0, /* 41 reserved */
12454 0, /* 42 reserved */
12455 0, /* 43 reserved */
12456 0, /* 44 reserved */
12457 0, /* 45 reserved */
12458 0, /* 46 reserved */
12459 0, /* 47 reserved */
12460 0, /* 48 reserved */
12461 0, /* 49 reserved */
12462 0, /* 50 reserved */
12463 0, /* 51 reserved */
12464 0, /* 52 reserved */
12465 0, /* 53 reserved */
12466 0, /* 54 reserved */
12467 0, /* 55 reserved */
12468 0, /* 56 cisptr_lsw */
12469 0, /* 57 cisprt_msw */
12470 0, /* 58 subsysvid */
12471 0, /* 59 subsysid */
12472 0, /* 60 reserved */
12473 0, /* 61 reserved */
12474 0, /* 62 reserved */
12475 0 /* 63 reserved */
12478 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
12479 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
12480 0x0000, /* 01 cfg_msw */
12481 0xFFFF, /* 02 disc_enable */
12482 0xFFFF, /* 03 wdtr_able */
12483 0x5555, /* 04 sdtr_speed1 */
12484 0xFFFF, /* 05 start_motor */
12485 0xFFFF, /* 06 tagqng_able */
12486 0xFFFF, /* 07 bios_scan */
12487 0, /* 08 scam_tolerant */
12488 7, /* 09 adapter_scsi_id */
12489 0, /* bios_boot_delay */
12490 3, /* 10 scsi_reset_delay */
12491 0, /* bios_id_lun */
12492 0, /* 11 termination_se */
12493 0, /* termination_lvd */
12494 0xFFE7, /* 12 bios_ctrl */
12495 0x5555, /* 13 sdtr_speed2 */
12496 0x5555, /* 14 sdtr_speed3 */
12497 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
12498 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
12499 0, /* 16 dvc_cntl */
12500 0x5555, /* 17 sdtr_speed4 */
12501 0, /* 18 serial_number_word1 */
12502 0, /* 19 serial_number_word2 */
12503 0, /* 20 serial_number_word3 */
12504 0, /* 21 check_sum */
12505 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12506 , /* 22-29 oem_name[16] */
12507 0, /* 30 dvc_err_code */
12508 0, /* 31 adv_err_code */
12509 0, /* 32 adv_err_addr */
12510 0, /* 33 saved_dvc_err_code */
12511 0, /* 34 saved_adv_err_code */
12512 0, /* 35 saved_adv_err_addr */
12513 0, /* 36 reserved */
12514 0, /* 37 reserved */
12515 0, /* 38 reserved */
12516 0, /* 39 reserved */
12517 0, /* 40 reserved */
12518 0, /* 41 reserved */
12519 0, /* 42 reserved */
12520 0, /* 43 reserved */
12521 0, /* 44 reserved */
12522 0, /* 45 reserved */
12523 0, /* 46 reserved */
12524 0, /* 47 reserved */
12525 0, /* 48 reserved */
12526 0, /* 49 reserved */
12527 0, /* 50 reserved */
12528 0, /* 51 reserved */
12529 0, /* 52 reserved */
12530 0, /* 53 reserved */
12531 0, /* 54 reserved */
12532 0, /* 55 reserved */
12533 0, /* 56 cisptr_lsw */
12534 0, /* 57 cisprt_msw */
12535 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
12536 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
12537 0, /* 60 reserved */
12538 0, /* 61 reserved */
12539 0, /* 62 reserved */
12540 0 /* 63 reserved */
12543 static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
12544 0, /* 00 cfg_lsw */
12545 0, /* 01 cfg_msw */
12546 0, /* 02 disc_enable */
12547 0, /* 03 wdtr_able */
12548 0, /* 04 sdtr_speed1 */
12549 0, /* 05 start_motor */
12550 0, /* 06 tagqng_able */
12551 0, /* 07 bios_scan */
12552 0, /* 08 scam_tolerant */
12553 1, /* 09 adapter_scsi_id */
12554 1, /* bios_boot_delay */
12555 1, /* 10 scsi_reset_delay */
12556 1, /* bios_id_lun */
12557 1, /* 11 termination_se */
12558 1, /* termination_lvd */
12559 0, /* 12 bios_ctrl */
12560 0, /* 13 sdtr_speed2 */
12561 0, /* 14 sdtr_speed3 */
12562 1, /* 15 max_host_qng */
12563 1, /* max_dvc_qng */
12564 0, /* 16 dvc_cntl */
12565 0, /* 17 sdtr_speed4 */
12566 0, /* 18 serial_number_word1 */
12567 0, /* 19 serial_number_word2 */
12568 0, /* 20 serial_number_word3 */
12569 0, /* 21 check_sum */
12570 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12571 , /* 22-29 oem_name[16] */
12572 0, /* 30 dvc_err_code */
12573 0, /* 31 adv_err_code */
12574 0, /* 32 adv_err_addr */
12575 0, /* 33 saved_dvc_err_code */
12576 0, /* 34 saved_adv_err_code */
12577 0, /* 35 saved_adv_err_addr */
12578 0, /* 36 reserved */
12579 0, /* 37 reserved */
12580 0, /* 38 reserved */
12581 0, /* 39 reserved */
12582 0, /* 40 reserved */
12583 0, /* 41 reserved */
12584 0, /* 42 reserved */
12585 0, /* 43 reserved */
12586 0, /* 44 reserved */
12587 0, /* 45 reserved */
12588 0, /* 46 reserved */
12589 0, /* 47 reserved */
12590 0, /* 48 reserved */
12591 0, /* 49 reserved */
12592 0, /* 50 reserved */
12593 0, /* 51 reserved */
12594 0, /* 52 reserved */
12595 0, /* 53 reserved */
12596 0, /* 54 reserved */
12597 0, /* 55 reserved */
12598 0, /* 56 cisptr_lsw */
12599 0, /* 57 cisprt_msw */
12600 0, /* 58 subsysvid */
12601 0, /* 59 subsysid */
12602 0, /* 60 reserved */
12603 0, /* 61 reserved */
12604 0, /* 62 reserved */
12605 0 /* 63 reserved */
12608 #ifdef CONFIG_PCI
12610 * Wait for EEPROM command to complete
12612 static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
12614 int eep_delay_ms;
12616 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
12617 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
12618 ASC_EEP_CMD_DONE) {
12619 break;
12621 mdelay(1);
12623 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
12625 BUG();
12629 * Read the EEPROM from specified location
12631 static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
12633 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12634 ASC_EEP_CMD_READ | eep_word_addr);
12635 AdvWaitEEPCmd(iop_base);
12636 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
12640 * Write the EEPROM from 'cfg_buf'.
12642 void __devinit
12643 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
12645 ushort *wbuf;
12646 ushort addr, chksum;
12647 ushort *charfields;
12649 wbuf = (ushort *)cfg_buf;
12650 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
12651 chksum = 0;
12653 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12654 AdvWaitEEPCmd(iop_base);
12657 * Write EEPROM from word 0 to word 20.
12659 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12660 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12661 ushort word;
12663 if (*charfields++) {
12664 word = cpu_to_le16(*wbuf);
12665 } else {
12666 word = *wbuf;
12668 chksum += *wbuf; /* Checksum is calculated from word values. */
12669 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12670 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12671 ASC_EEP_CMD_WRITE | addr);
12672 AdvWaitEEPCmd(iop_base);
12673 mdelay(ADV_EEP_DELAY_MS);
12677 * Write EEPROM checksum at word 21.
12679 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12680 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12681 AdvWaitEEPCmd(iop_base);
12682 wbuf++;
12683 charfields++;
12686 * Write EEPROM OEM name at words 22 to 29.
12688 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12689 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12690 ushort word;
12692 if (*charfields++) {
12693 word = cpu_to_le16(*wbuf);
12694 } else {
12695 word = *wbuf;
12697 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12698 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12699 ASC_EEP_CMD_WRITE | addr);
12700 AdvWaitEEPCmd(iop_base);
12702 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12703 AdvWaitEEPCmd(iop_base);
12707 * Write the EEPROM from 'cfg_buf'.
12709 void __devinit
12710 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
12712 ushort *wbuf;
12713 ushort *charfields;
12714 ushort addr, chksum;
12716 wbuf = (ushort *)cfg_buf;
12717 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
12718 chksum = 0;
12720 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12721 AdvWaitEEPCmd(iop_base);
12724 * Write EEPROM from word 0 to word 20.
12726 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12727 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12728 ushort word;
12730 if (*charfields++) {
12731 word = cpu_to_le16(*wbuf);
12732 } else {
12733 word = *wbuf;
12735 chksum += *wbuf; /* Checksum is calculated from word values. */
12736 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12737 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12738 ASC_EEP_CMD_WRITE | addr);
12739 AdvWaitEEPCmd(iop_base);
12740 mdelay(ADV_EEP_DELAY_MS);
12744 * Write EEPROM checksum at word 21.
12746 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12747 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12748 AdvWaitEEPCmd(iop_base);
12749 wbuf++;
12750 charfields++;
12753 * Write EEPROM OEM name at words 22 to 29.
12755 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12756 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12757 ushort word;
12759 if (*charfields++) {
12760 word = cpu_to_le16(*wbuf);
12761 } else {
12762 word = *wbuf;
12764 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12765 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12766 ASC_EEP_CMD_WRITE | addr);
12767 AdvWaitEEPCmd(iop_base);
12769 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12770 AdvWaitEEPCmd(iop_base);
12774 * Write the EEPROM from 'cfg_buf'.
12776 void __devinit
12777 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
12779 ushort *wbuf;
12780 ushort *charfields;
12781 ushort addr, chksum;
12783 wbuf = (ushort *)cfg_buf;
12784 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
12785 chksum = 0;
12787 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12788 AdvWaitEEPCmd(iop_base);
12791 * Write EEPROM from word 0 to word 20.
12793 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12794 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12795 ushort word;
12797 if (*charfields++) {
12798 word = cpu_to_le16(*wbuf);
12799 } else {
12800 word = *wbuf;
12802 chksum += *wbuf; /* Checksum is calculated from word values. */
12803 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12804 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12805 ASC_EEP_CMD_WRITE | addr);
12806 AdvWaitEEPCmd(iop_base);
12807 mdelay(ADV_EEP_DELAY_MS);
12811 * Write EEPROM checksum at word 21.
12813 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12814 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12815 AdvWaitEEPCmd(iop_base);
12816 wbuf++;
12817 charfields++;
12820 * Write EEPROM OEM name at words 22 to 29.
12822 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12823 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12824 ushort word;
12826 if (*charfields++) {
12827 word = cpu_to_le16(*wbuf);
12828 } else {
12829 word = *wbuf;
12831 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12832 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12833 ASC_EEP_CMD_WRITE | addr);
12834 AdvWaitEEPCmd(iop_base);
12836 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12837 AdvWaitEEPCmd(iop_base);
12841 * Read EEPROM configuration into the specified buffer.
12843 * Return a checksum based on the EEPROM configuration read.
12845 static ushort __devinit
12846 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
12848 ushort wval, chksum;
12849 ushort *wbuf;
12850 int eep_addr;
12851 ushort *charfields;
12853 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
12854 wbuf = (ushort *)cfg_buf;
12855 chksum = 0;
12857 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12858 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12859 wval = AdvReadEEPWord(iop_base, eep_addr);
12860 chksum += wval; /* Checksum is calculated from word values. */
12861 if (*charfields++) {
12862 *wbuf = le16_to_cpu(wval);
12863 } else {
12864 *wbuf = wval;
12867 /* Read checksum word. */
12868 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12869 wbuf++;
12870 charfields++;
12872 /* Read rest of EEPROM not covered by the checksum. */
12873 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12874 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12875 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12876 if (*charfields++) {
12877 *wbuf = le16_to_cpu(*wbuf);
12880 return chksum;
12884 * Read EEPROM configuration into the specified buffer.
12886 * Return a checksum based on the EEPROM configuration read.
12888 static ushort __devinit
12889 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
12891 ushort wval, chksum;
12892 ushort *wbuf;
12893 int eep_addr;
12894 ushort *charfields;
12896 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
12897 wbuf = (ushort *)cfg_buf;
12898 chksum = 0;
12900 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12901 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12902 wval = AdvReadEEPWord(iop_base, eep_addr);
12903 chksum += wval; /* Checksum is calculated from word values. */
12904 if (*charfields++) {
12905 *wbuf = le16_to_cpu(wval);
12906 } else {
12907 *wbuf = wval;
12910 /* Read checksum word. */
12911 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12912 wbuf++;
12913 charfields++;
12915 /* Read rest of EEPROM not covered by the checksum. */
12916 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12917 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12918 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12919 if (*charfields++) {
12920 *wbuf = le16_to_cpu(*wbuf);
12923 return chksum;
12927 * Read EEPROM configuration into the specified buffer.
12929 * Return a checksum based on the EEPROM configuration read.
12931 static ushort __devinit
12932 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
12934 ushort wval, chksum;
12935 ushort *wbuf;
12936 int eep_addr;
12937 ushort *charfields;
12939 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
12940 wbuf = (ushort *)cfg_buf;
12941 chksum = 0;
12943 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12944 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12945 wval = AdvReadEEPWord(iop_base, eep_addr);
12946 chksum += wval; /* Checksum is calculated from word values. */
12947 if (*charfields++) {
12948 *wbuf = le16_to_cpu(wval);
12949 } else {
12950 *wbuf = wval;
12953 /* Read checksum word. */
12954 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12955 wbuf++;
12956 charfields++;
12958 /* Read rest of EEPROM not covered by the checksum. */
12959 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12960 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12961 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12962 if (*charfields++) {
12963 *wbuf = le16_to_cpu(*wbuf);
12966 return chksum;
12970 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12971 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12972 * all of this is done.
12974 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12976 * For a non-fatal error return a warning code. If there are no warnings
12977 * then 0 is returned.
12979 * Note: Chip is stopped on entry.
12981 static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
12983 AdvPortAddr iop_base;
12984 ushort warn_code;
12985 ADVEEP_3550_CONFIG eep_config;
12987 iop_base = asc_dvc->iop_base;
12989 warn_code = 0;
12992 * Read the board's EEPROM configuration.
12994 * Set default values if a bad checksum is found.
12996 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
12997 warn_code |= ASC_WARN_EEPROM_CHKSUM;
13000 * Set EEPROM default values.
13002 memcpy(&eep_config, &Default_3550_EEPROM_Config,
13003 sizeof(ADVEEP_3550_CONFIG));
13006 * Assume the 6 byte board serial number that was read from
13007 * EEPROM is correct even if the EEPROM checksum failed.
13009 eep_config.serial_number_word3 =
13010 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
13012 eep_config.serial_number_word2 =
13013 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
13015 eep_config.serial_number_word1 =
13016 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
13018 AdvSet3550EEPConfig(iop_base, &eep_config);
13021 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13022 * EEPROM configuration that was read.
13024 * This is the mapping of EEPROM fields to Adv Library fields.
13026 asc_dvc->wdtr_able = eep_config.wdtr_able;
13027 asc_dvc->sdtr_able = eep_config.sdtr_able;
13028 asc_dvc->ultra_able = eep_config.ultra_able;
13029 asc_dvc->tagqng_able = eep_config.tagqng_able;
13030 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13031 asc_dvc->max_host_qng = eep_config.max_host_qng;
13032 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13033 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
13034 asc_dvc->start_motor = eep_config.start_motor;
13035 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13036 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13037 asc_dvc->no_scam = eep_config.scam_tolerant;
13038 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
13039 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
13040 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
13043 * Set the host maximum queuing (max. 253, min. 16) and the per device
13044 * maximum queuing (max. 63, min. 4).
13046 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13047 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13048 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13049 /* If the value is zero, assume it is uninitialized. */
13050 if (eep_config.max_host_qng == 0) {
13051 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13052 } else {
13053 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13057 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13058 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13059 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13060 /* If the value is zero, assume it is uninitialized. */
13061 if (eep_config.max_dvc_qng == 0) {
13062 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13063 } else {
13064 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13069 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13070 * set 'max_dvc_qng' to 'max_host_qng'.
13072 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13073 eep_config.max_dvc_qng = eep_config.max_host_qng;
13077 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
13078 * values based on possibly adjusted EEPROM values.
13080 asc_dvc->max_host_qng = eep_config.max_host_qng;
13081 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13084 * If the EEPROM 'termination' field is set to automatic (0), then set
13085 * the ADV_DVC_CFG 'termination' field to automatic also.
13087 * If the termination is specified with a non-zero 'termination'
13088 * value check that a legal value is set and set the ADV_DVC_CFG
13089 * 'termination' field appropriately.
13091 if (eep_config.termination == 0) {
13092 asc_dvc->cfg->termination = 0; /* auto termination */
13093 } else {
13094 /* Enable manual control with low off / high off. */
13095 if (eep_config.termination == 1) {
13096 asc_dvc->cfg->termination = TERM_CTL_SEL;
13098 /* Enable manual control with low off / high on. */
13099 } else if (eep_config.termination == 2) {
13100 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
13102 /* Enable manual control with low on / high on. */
13103 } else if (eep_config.termination == 3) {
13104 asc_dvc->cfg->termination =
13105 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
13106 } else {
13108 * The EEPROM 'termination' field contains a bad value. Use
13109 * automatic termination instead.
13111 asc_dvc->cfg->termination = 0;
13112 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13116 return warn_code;
13120 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
13121 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
13122 * all of this is done.
13124 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13126 * For a non-fatal error return a warning code. If there are no warnings
13127 * then 0 is returned.
13129 * Note: Chip is stopped on entry.
13131 static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
13133 AdvPortAddr iop_base;
13134 ushort warn_code;
13135 ADVEEP_38C0800_CONFIG eep_config;
13136 uchar tid, termination;
13137 ushort sdtr_speed = 0;
13139 iop_base = asc_dvc->iop_base;
13141 warn_code = 0;
13144 * Read the board's EEPROM configuration.
13146 * Set default values if a bad checksum is found.
13148 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
13149 eep_config.check_sum) {
13150 warn_code |= ASC_WARN_EEPROM_CHKSUM;
13153 * Set EEPROM default values.
13155 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
13156 sizeof(ADVEEP_38C0800_CONFIG));
13159 * Assume the 6 byte board serial number that was read from
13160 * EEPROM is correct even if the EEPROM checksum failed.
13162 eep_config.serial_number_word3 =
13163 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
13165 eep_config.serial_number_word2 =
13166 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
13168 eep_config.serial_number_word1 =
13169 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
13171 AdvSet38C0800EEPConfig(iop_base, &eep_config);
13174 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
13175 * EEPROM configuration that was read.
13177 * This is the mapping of EEPROM fields to Adv Library fields.
13179 asc_dvc->wdtr_able = eep_config.wdtr_able;
13180 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13181 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13182 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13183 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13184 asc_dvc->tagqng_able = eep_config.tagqng_able;
13185 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13186 asc_dvc->max_host_qng = eep_config.max_host_qng;
13187 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13188 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
13189 asc_dvc->start_motor = eep_config.start_motor;
13190 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13191 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13192 asc_dvc->no_scam = eep_config.scam_tolerant;
13193 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
13194 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
13195 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
13198 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13199 * are set, then set an 'sdtr_able' bit for it.
13201 asc_dvc->sdtr_able = 0;
13202 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13203 if (tid == 0) {
13204 sdtr_speed = asc_dvc->sdtr_speed1;
13205 } else if (tid == 4) {
13206 sdtr_speed = asc_dvc->sdtr_speed2;
13207 } else if (tid == 8) {
13208 sdtr_speed = asc_dvc->sdtr_speed3;
13209 } else if (tid == 12) {
13210 sdtr_speed = asc_dvc->sdtr_speed4;
13212 if (sdtr_speed & ADV_MAX_TID) {
13213 asc_dvc->sdtr_able |= (1 << tid);
13215 sdtr_speed >>= 4;
13219 * Set the host maximum queuing (max. 253, min. 16) and the per device
13220 * maximum queuing (max. 63, min. 4).
13222 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13223 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13224 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13225 /* If the value is zero, assume it is uninitialized. */
13226 if (eep_config.max_host_qng == 0) {
13227 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13228 } else {
13229 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13233 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13234 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13235 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13236 /* If the value is zero, assume it is uninitialized. */
13237 if (eep_config.max_dvc_qng == 0) {
13238 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13239 } else {
13240 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13245 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13246 * set 'max_dvc_qng' to 'max_host_qng'.
13248 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13249 eep_config.max_dvc_qng = eep_config.max_host_qng;
13253 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
13254 * values based on possibly adjusted EEPROM values.
13256 asc_dvc->max_host_qng = eep_config.max_host_qng;
13257 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13260 * If the EEPROM 'termination' field is set to automatic (0), then set
13261 * the ADV_DVC_CFG 'termination' field to automatic also.
13263 * If the termination is specified with a non-zero 'termination'
13264 * value check that a legal value is set and set the ADV_DVC_CFG
13265 * 'termination' field appropriately.
13267 if (eep_config.termination_se == 0) {
13268 termination = 0; /* auto termination for SE */
13269 } else {
13270 /* Enable manual control with low off / high off. */
13271 if (eep_config.termination_se == 1) {
13272 termination = 0;
13274 /* Enable manual control with low off / high on. */
13275 } else if (eep_config.termination_se == 2) {
13276 termination = TERM_SE_HI;
13278 /* Enable manual control with low on / high on. */
13279 } else if (eep_config.termination_se == 3) {
13280 termination = TERM_SE;
13281 } else {
13283 * The EEPROM 'termination_se' field contains a bad value.
13284 * Use automatic termination instead.
13286 termination = 0;
13287 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13291 if (eep_config.termination_lvd == 0) {
13292 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13293 } else {
13294 /* Enable manual control with low off / high off. */
13295 if (eep_config.termination_lvd == 1) {
13296 asc_dvc->cfg->termination = termination;
13298 /* Enable manual control with low off / high on. */
13299 } else if (eep_config.termination_lvd == 2) {
13300 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13302 /* Enable manual control with low on / high on. */
13303 } else if (eep_config.termination_lvd == 3) {
13304 asc_dvc->cfg->termination = termination | TERM_LVD;
13305 } else {
13307 * The EEPROM 'termination_lvd' field contains a bad value.
13308 * Use automatic termination instead.
13310 asc_dvc->cfg->termination = termination;
13311 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13315 return warn_code;
13319 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
13320 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
13321 * all of this is done.
13323 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
13325 * For a non-fatal error return a warning code. If there are no warnings
13326 * then 0 is returned.
13328 * Note: Chip is stopped on entry.
13330 static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
13332 AdvPortAddr iop_base;
13333 ushort warn_code;
13334 ADVEEP_38C1600_CONFIG eep_config;
13335 uchar tid, termination;
13336 ushort sdtr_speed = 0;
13338 iop_base = asc_dvc->iop_base;
13340 warn_code = 0;
13343 * Read the board's EEPROM configuration.
13345 * Set default values if a bad checksum is found.
13347 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
13348 eep_config.check_sum) {
13349 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
13350 warn_code |= ASC_WARN_EEPROM_CHKSUM;
13353 * Set EEPROM default values.
13355 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
13356 sizeof(ADVEEP_38C1600_CONFIG));
13358 if (PCI_FUNC(pdev->devfn) != 0) {
13359 u8 ints;
13361 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60
13362 * and old Mac system booting problem. The Expansion
13363 * ROM must be disabled in Function 1 for these systems
13365 eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
13367 * Clear the INTAB (bit 11) if the GPIO 0 input
13368 * indicates the Function 1 interrupt line is wired
13369 * to INTB.
13371 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
13372 * 1 - Function 1 interrupt line wired to INT A.
13373 * 0 - Function 1 interrupt line wired to INT B.
13375 * Note: Function 0 is always wired to INTA.
13376 * Put all 5 GPIO bits in input mode and then read
13377 * their input values.
13379 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
13380 ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
13381 if ((ints & 0x01) == 0)
13382 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
13386 * Assume the 6 byte board serial number that was read from
13387 * EEPROM is correct even if the EEPROM checksum failed.
13389 eep_config.serial_number_word3 =
13390 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
13391 eep_config.serial_number_word2 =
13392 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
13393 eep_config.serial_number_word1 =
13394 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
13396 AdvSet38C1600EEPConfig(iop_base, &eep_config);
13400 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13401 * EEPROM configuration that was read.
13403 * This is the mapping of EEPROM fields to Adv Library fields.
13405 asc_dvc->wdtr_able = eep_config.wdtr_able;
13406 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13407 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13408 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13409 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13410 asc_dvc->ppr_able = 0;
13411 asc_dvc->tagqng_able = eep_config.tagqng_able;
13412 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13413 asc_dvc->max_host_qng = eep_config.max_host_qng;
13414 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13415 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
13416 asc_dvc->start_motor = eep_config.start_motor;
13417 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13418 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13419 asc_dvc->no_scam = eep_config.scam_tolerant;
13422 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13423 * are set, then set an 'sdtr_able' bit for it.
13425 asc_dvc->sdtr_able = 0;
13426 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
13427 if (tid == 0) {
13428 sdtr_speed = asc_dvc->sdtr_speed1;
13429 } else if (tid == 4) {
13430 sdtr_speed = asc_dvc->sdtr_speed2;
13431 } else if (tid == 8) {
13432 sdtr_speed = asc_dvc->sdtr_speed3;
13433 } else if (tid == 12) {
13434 sdtr_speed = asc_dvc->sdtr_speed4;
13436 if (sdtr_speed & ASC_MAX_TID) {
13437 asc_dvc->sdtr_able |= (1 << tid);
13439 sdtr_speed >>= 4;
13443 * Set the host maximum queuing (max. 253, min. 16) and the per device
13444 * maximum queuing (max. 63, min. 4).
13446 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13447 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13448 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13449 /* If the value is zero, assume it is uninitialized. */
13450 if (eep_config.max_host_qng == 0) {
13451 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13452 } else {
13453 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13457 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13458 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13459 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13460 /* If the value is zero, assume it is uninitialized. */
13461 if (eep_config.max_dvc_qng == 0) {
13462 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13463 } else {
13464 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13469 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13470 * set 'max_dvc_qng' to 'max_host_qng'.
13472 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13473 eep_config.max_dvc_qng = eep_config.max_host_qng;
13477 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
13478 * values based on possibly adjusted EEPROM values.
13480 asc_dvc->max_host_qng = eep_config.max_host_qng;
13481 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13484 * If the EEPROM 'termination' field is set to automatic (0), then set
13485 * the ASC_DVC_CFG 'termination' field to automatic also.
13487 * If the termination is specified with a non-zero 'termination'
13488 * value check that a legal value is set and set the ASC_DVC_CFG
13489 * 'termination' field appropriately.
13491 if (eep_config.termination_se == 0) {
13492 termination = 0; /* auto termination for SE */
13493 } else {
13494 /* Enable manual control with low off / high off. */
13495 if (eep_config.termination_se == 1) {
13496 termination = 0;
13498 /* Enable manual control with low off / high on. */
13499 } else if (eep_config.termination_se == 2) {
13500 termination = TERM_SE_HI;
13502 /* Enable manual control with low on / high on. */
13503 } else if (eep_config.termination_se == 3) {
13504 termination = TERM_SE;
13505 } else {
13507 * The EEPROM 'termination_se' field contains a bad value.
13508 * Use automatic termination instead.
13510 termination = 0;
13511 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13515 if (eep_config.termination_lvd == 0) {
13516 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13517 } else {
13518 /* Enable manual control with low off / high off. */
13519 if (eep_config.termination_lvd == 1) {
13520 asc_dvc->cfg->termination = termination;
13522 /* Enable manual control with low off / high on. */
13523 } else if (eep_config.termination_lvd == 2) {
13524 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13526 /* Enable manual control with low on / high on. */
13527 } else if (eep_config.termination_lvd == 3) {
13528 asc_dvc->cfg->termination = termination | TERM_LVD;
13529 } else {
13531 * The EEPROM 'termination_lvd' field contains a bad value.
13532 * Use automatic termination instead.
13534 asc_dvc->cfg->termination = termination;
13535 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13539 return warn_code;
13543 * Initialize the ADV_DVC_VAR structure.
13545 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13547 * For a non-fatal error return a warning code. If there are no warnings
13548 * then 0 is returned.
13550 static int __devinit
13551 AdvInitGetConfig(struct pci_dev *pdev, asc_board_t *boardp)
13553 ADV_DVC_VAR *asc_dvc = &boardp->dvc_var.adv_dvc_var;
13554 unsigned short warn_code = 0;
13555 AdvPortAddr iop_base = asc_dvc->iop_base;
13556 u16 cmd;
13557 int status;
13559 asc_dvc->err_code = 0;
13562 * Save the state of the PCI Configuration Command Register
13563 * "Parity Error Response Control" Bit. If the bit is clear (0),
13564 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13565 * DMA parity errors.
13567 asc_dvc->cfg->control_flag = 0;
13568 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
13569 if ((cmd & PCI_COMMAND_PARITY) == 0)
13570 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
13572 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
13573 ADV_LIB_VERSION_MINOR;
13574 asc_dvc->cfg->chip_version =
13575 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13577 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
13578 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13579 (ushort)ADV_CHIP_ID_BYTE);
13581 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
13582 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13583 (ushort)ADV_CHIP_ID_WORD);
13586 * Reset the chip to start and allow register writes.
13588 if (AdvFindSignature(iop_base) == 0) {
13589 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13590 return ADV_ERROR;
13591 } else {
13593 * The caller must set 'chip_type' to a valid setting.
13595 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13596 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13597 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13598 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13599 return ADV_ERROR;
13603 * Reset Chip.
13605 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13606 ADV_CTRL_REG_CMD_RESET);
13607 mdelay(100);
13608 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13609 ADV_CTRL_REG_CMD_WR_IO_REG);
13611 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13612 status = AdvInitFrom38C1600EEP(asc_dvc);
13613 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13614 status = AdvInitFrom38C0800EEP(asc_dvc);
13615 } else {
13616 status = AdvInitFrom3550EEP(asc_dvc);
13618 warn_code |= status;
13621 if (warn_code != 0) {
13622 ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
13623 boardp->id, warn_code);
13626 if (asc_dvc->err_code) {
13627 ASC_PRINT2("AdvInitGetConfig: board %d error: err_code 0x%x\n",
13628 boardp->id, asc_dvc->err_code);
13631 return asc_dvc->err_code;
13633 #endif
13635 static struct scsi_host_template advansys_template = {
13636 .proc_name = DRV_NAME,
13637 #ifdef CONFIG_PROC_FS
13638 .proc_info = advansys_proc_info,
13639 #endif
13640 .name = DRV_NAME,
13641 .info = advansys_info,
13642 .queuecommand = advansys_queuecommand,
13643 .eh_bus_reset_handler = advansys_reset,
13644 .bios_param = advansys_biosparam,
13645 .slave_configure = advansys_slave_configure,
13647 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
13648 * must be set. The flag will be cleared in advansys_board_found
13649 * for non-ISA adapters.
13651 .unchecked_isa_dma = 1,
13653 * All adapters controlled by this driver are capable of large
13654 * scatter-gather lists. According to the mid-level SCSI documentation
13655 * this obviates any performance gain provided by setting
13656 * 'use_clustering'. But empirically while CPU utilization is increased
13657 * by enabling clustering, I/O throughput increases as well.
13659 .use_clustering = ENABLE_CLUSTERING,
13662 static int __devinit
13663 advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
13665 int req_cnt = 0;
13666 adv_req_t *reqp = NULL;
13667 int sg_cnt = 0;
13668 adv_sgblk_t *sgp;
13669 int warn_code, err_code;
13672 * Allocate buffer carrier structures. The total size
13673 * is about 4 KB, so allocate all at once.
13675 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
13676 ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
13678 if (!boardp->carrp)
13679 goto kmalloc_failed;
13682 * Allocate up to 'max_host_qng' request structures for the Wide
13683 * board. The total size is about 16 KB, so allocate all at once.
13684 * If the allocation fails decrement and try again.
13686 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
13687 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
13689 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
13690 "bytes %lu\n", reqp, req_cnt,
13691 (ulong)sizeof(adv_req_t) * req_cnt);
13693 if (reqp)
13694 break;
13697 if (!reqp)
13698 goto kmalloc_failed;
13700 boardp->orig_reqp = reqp;
13703 * Allocate up to ADV_TOT_SG_BLOCK request structures for
13704 * the Wide board. Each structure is about 136 bytes.
13706 boardp->adv_sgblkp = NULL;
13707 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
13708 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
13710 if (!sgp)
13711 break;
13713 sgp->next_sgblkp = boardp->adv_sgblkp;
13714 boardp->adv_sgblkp = sgp;
13718 ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
13719 sg_cnt, sizeof(adv_sgblk_t),
13720 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
13722 if (!boardp->adv_sgblkp)
13723 goto kmalloc_failed;
13725 adv_dvc_varp->carrier_buf = boardp->carrp;
13728 * Point 'adv_reqp' to the request structures and
13729 * link them together.
13731 req_cnt--;
13732 reqp[req_cnt].next_reqp = NULL;
13733 for (; req_cnt > 0; req_cnt--) {
13734 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
13736 boardp->adv_reqp = &reqp[0];
13738 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
13739 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
13740 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
13741 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
13742 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
13743 "\n");
13744 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
13745 } else {
13746 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
13747 "\n");
13748 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
13750 err_code = adv_dvc_varp->err_code;
13752 if (warn_code || err_code) {
13753 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
13754 " error 0x%x\n", boardp->id, warn_code, err_code);
13757 goto exit;
13759 kmalloc_failed:
13760 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
13761 "failed\n", boardp->id);
13762 err_code = ADV_ERROR;
13763 exit:
13764 return err_code;
13767 static void advansys_wide_free_mem(asc_board_t *boardp)
13769 kfree(boardp->carrp);
13770 boardp->carrp = NULL;
13771 kfree(boardp->orig_reqp);
13772 boardp->orig_reqp = boardp->adv_reqp = NULL;
13773 while (boardp->adv_sgblkp) {
13774 adv_sgblk_t *sgp = boardp->adv_sgblkp;
13775 boardp->adv_sgblkp = sgp->next_sgblkp;
13776 kfree(sgp);
13780 static int __devinit advansys_board_found(struct Scsi_Host *shost,
13781 unsigned int iop, int bus_type)
13783 struct pci_dev *pdev;
13784 asc_board_t *boardp;
13785 ASC_DVC_VAR *asc_dvc_varp = NULL;
13786 ADV_DVC_VAR *adv_dvc_varp = NULL;
13787 int share_irq, warn_code, ret;
13789 boardp = ASC_BOARDP(shost);
13790 boardp->id = asc_board_count++;
13791 spin_lock_init(&boardp->lock);
13792 pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL;
13794 if (ASC_NARROW_BOARD(boardp)) {
13795 ASC_DBG(1, "advansys_board_found: narrow board\n");
13796 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
13797 asc_dvc_varp->bus_type = bus_type;
13798 asc_dvc_varp->drv_ptr = boardp;
13799 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
13800 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
13801 asc_dvc_varp->iop_base = iop;
13802 } else {
13803 #ifdef CONFIG_PCI
13804 ASC_DBG(1, "advansys_board_found: wide board\n");
13805 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
13806 adv_dvc_varp->drv_ptr = boardp;
13807 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
13808 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
13809 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
13810 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
13811 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
13812 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
13813 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
13814 } else {
13815 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
13816 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
13819 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
13820 boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
13821 boardp->asc_n_io_port);
13822 if (!boardp->ioremap_addr) {
13823 ASC_PRINT3
13824 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
13825 boardp->id, pci_resource_start(pdev, 1),
13826 boardp->asc_n_io_port);
13827 ret = -ENODEV;
13828 goto err_shost;
13830 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
13831 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
13832 adv_dvc_varp->iop_base);
13835 * Even though it isn't used to access wide boards, other
13836 * than for the debug line below, save I/O Port address so
13837 * that it can be reported.
13839 boardp->ioport = iop;
13841 ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, "
13842 "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1),
13843 (ushort)inpw(iop));
13844 #endif /* CONFIG_PCI */
13847 #ifdef CONFIG_PROC_FS
13849 * Allocate buffer for printing information from
13850 * /proc/scsi/advansys/[0...].
13852 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
13853 if (!boardp->prtbuf) {
13854 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
13855 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
13856 ret = -ENOMEM;
13857 goto err_unmap;
13859 #endif /* CONFIG_PROC_FS */
13861 if (ASC_NARROW_BOARD(boardp)) {
13863 * Set the board bus type and PCI IRQ before
13864 * calling AscInitGetConfig().
13866 switch (asc_dvc_varp->bus_type) {
13867 #ifdef CONFIG_ISA
13868 case ASC_IS_ISA:
13869 shost->unchecked_isa_dma = TRUE;
13870 share_irq = 0;
13871 break;
13872 case ASC_IS_VL:
13873 shost->unchecked_isa_dma = FALSE;
13874 share_irq = 0;
13875 break;
13876 case ASC_IS_EISA:
13877 shost->unchecked_isa_dma = FALSE;
13878 share_irq = IRQF_SHARED;
13879 break;
13880 #endif /* CONFIG_ISA */
13881 #ifdef CONFIG_PCI
13882 case ASC_IS_PCI:
13883 shost->unchecked_isa_dma = FALSE;
13884 share_irq = IRQF_SHARED;
13885 break;
13886 #endif /* CONFIG_PCI */
13887 default:
13888 ASC_PRINT2
13889 ("advansys_board_found: board %d: unknown adapter type: %d\n",
13890 boardp->id, asc_dvc_varp->bus_type);
13891 shost->unchecked_isa_dma = TRUE;
13892 share_irq = 0;
13893 break;
13897 * NOTE: AscInitGetConfig() may change the board's
13898 * bus_type value. The bus_type value should no
13899 * longer be used. If the bus_type field must be
13900 * referenced only use the bit-wise AND operator "&".
13902 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
13903 ret = AscInitGetConfig(boardp) ? -ENODEV : 0;
13904 } else {
13905 #ifdef CONFIG_PCI
13907 * For Wide boards set PCI information before calling
13908 * AdvInitGetConfig().
13910 shost->unchecked_isa_dma = FALSE;
13911 share_irq = IRQF_SHARED;
13912 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
13914 ret = AdvInitGetConfig(pdev, boardp) ? -ENODEV : 0;
13915 #endif /* CONFIG_PCI */
13918 if (ret)
13919 goto err_free_proc;
13922 * Save the EEPROM configuration so that it can be displayed
13923 * from /proc/scsi/advansys/[0...].
13925 if (ASC_NARROW_BOARD(boardp)) {
13927 ASCEEP_CONFIG *ep;
13930 * Set the adapter's target id bit in the 'init_tidmask' field.
13932 boardp->init_tidmask |=
13933 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
13936 * Save EEPROM settings for the board.
13938 ep = &boardp->eep_config.asc_eep;
13940 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
13941 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
13942 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
13943 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
13944 ep->start_motor = asc_dvc_varp->start_motor;
13945 ep->cntl = asc_dvc_varp->dvc_cntl;
13946 ep->no_scam = asc_dvc_varp->no_scam;
13947 ep->max_total_qng = asc_dvc_varp->max_total_qng;
13948 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
13949 /* 'max_tag_qng' is set to the same value for every device. */
13950 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
13951 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
13952 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
13953 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
13954 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
13955 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
13956 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
13959 * Modify board configuration.
13961 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
13962 ret = AscInitSetConfig(pdev, boardp) ? -ENODEV : 0;
13963 if (ret)
13964 goto err_free_proc;
13965 } else {
13966 ADVEEP_3550_CONFIG *ep_3550;
13967 ADVEEP_38C0800_CONFIG *ep_38C0800;
13968 ADVEEP_38C1600_CONFIG *ep_38C1600;
13971 * Save Wide EEP Configuration Information.
13973 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
13974 ep_3550 = &boardp->eep_config.adv_3550_eep;
13976 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
13977 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
13978 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
13979 ep_3550->termination = adv_dvc_varp->cfg->termination;
13980 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
13981 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
13982 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
13983 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
13984 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
13985 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
13986 ep_3550->start_motor = adv_dvc_varp->start_motor;
13987 ep_3550->scsi_reset_delay =
13988 adv_dvc_varp->scsi_reset_wait;
13989 ep_3550->serial_number_word1 =
13990 adv_dvc_varp->cfg->serial1;
13991 ep_3550->serial_number_word2 =
13992 adv_dvc_varp->cfg->serial2;
13993 ep_3550->serial_number_word3 =
13994 adv_dvc_varp->cfg->serial3;
13995 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
13996 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
13998 ep_38C0800->adapter_scsi_id =
13999 adv_dvc_varp->chip_scsi_id;
14000 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
14001 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14002 ep_38C0800->termination_lvd =
14003 adv_dvc_varp->cfg->termination;
14004 ep_38C0800->disc_enable =
14005 adv_dvc_varp->cfg->disc_enable;
14006 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
14007 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
14008 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
14009 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
14010 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
14011 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
14012 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
14013 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
14014 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
14015 ep_38C0800->scsi_reset_delay =
14016 adv_dvc_varp->scsi_reset_wait;
14017 ep_38C0800->serial_number_word1 =
14018 adv_dvc_varp->cfg->serial1;
14019 ep_38C0800->serial_number_word2 =
14020 adv_dvc_varp->cfg->serial2;
14021 ep_38C0800->serial_number_word3 =
14022 adv_dvc_varp->cfg->serial3;
14023 } else {
14024 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
14026 ep_38C1600->adapter_scsi_id =
14027 adv_dvc_varp->chip_scsi_id;
14028 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
14029 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14030 ep_38C1600->termination_lvd =
14031 adv_dvc_varp->cfg->termination;
14032 ep_38C1600->disc_enable =
14033 adv_dvc_varp->cfg->disc_enable;
14034 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
14035 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
14036 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
14037 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
14038 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
14039 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
14040 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
14041 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
14042 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
14043 ep_38C1600->scsi_reset_delay =
14044 adv_dvc_varp->scsi_reset_wait;
14045 ep_38C1600->serial_number_word1 =
14046 adv_dvc_varp->cfg->serial1;
14047 ep_38C1600->serial_number_word2 =
14048 adv_dvc_varp->cfg->serial2;
14049 ep_38C1600->serial_number_word3 =
14050 adv_dvc_varp->cfg->serial3;
14054 * Set the adapter's target id bit in the 'init_tidmask' field.
14056 boardp->init_tidmask |=
14057 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
14061 * Channels are numbered beginning with 0. For AdvanSys one host
14062 * structure supports one channel. Multi-channel boards have a
14063 * separate host structure for each channel.
14065 shost->max_channel = 0;
14066 if (ASC_NARROW_BOARD(boardp)) {
14067 shost->max_id = ASC_MAX_TID + 1;
14068 shost->max_lun = ASC_MAX_LUN + 1;
14069 shost->max_cmd_len = ASC_MAX_CDB_LEN;
14071 shost->io_port = asc_dvc_varp->iop_base;
14072 boardp->asc_n_io_port = ASC_IOADR_GAP;
14073 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
14075 /* Set maximum number of queues the adapter can handle. */
14076 shost->can_queue = asc_dvc_varp->max_total_qng;
14077 } else {
14078 shost->max_id = ADV_MAX_TID + 1;
14079 shost->max_lun = ADV_MAX_LUN + 1;
14080 shost->max_cmd_len = ADV_MAX_CDB_LEN;
14083 * Save the I/O Port address and length even though
14084 * I/O ports are not used to access Wide boards.
14085 * Instead the Wide boards are accessed with
14086 * PCI Memory Mapped I/O.
14088 shost->io_port = iop;
14090 shost->this_id = adv_dvc_varp->chip_scsi_id;
14092 /* Set maximum number of queues the adapter can handle. */
14093 shost->can_queue = adv_dvc_varp->max_host_qng;
14097 * Following v1.3.89, 'cmd_per_lun' is no longer needed
14098 * and should be set to zero.
14100 * But because of a bug introduced in v1.3.89 if the driver is
14101 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
14102 * SCSI function 'allocate_device' will panic. To allow the driver
14103 * to work as a module in these kernels set 'cmd_per_lun' to 1.
14105 * Note: This is wrong. cmd_per_lun should be set to the depth
14106 * you want on untagged devices always.
14107 #ifdef MODULE
14109 shost->cmd_per_lun = 1;
14110 /* #else
14111 shost->cmd_per_lun = 0;
14112 #endif */
14115 * Set the maximum number of scatter-gather elements the
14116 * adapter can handle.
14118 if (ASC_NARROW_BOARD(boardp)) {
14120 * Allow two commands with 'sg_tablesize' scatter-gather
14121 * elements to be executed simultaneously. This value is
14122 * the theoretical hardware limit. It may be decreased
14123 * below.
14125 shost->sg_tablesize =
14126 (((asc_dvc_varp->max_total_qng - 2) / 2) *
14127 ASC_SG_LIST_PER_Q) + 1;
14128 } else {
14129 shost->sg_tablesize = ADV_MAX_SG_LIST;
14133 * The value of 'sg_tablesize' can not exceed the SCSI
14134 * mid-level driver definition of SG_ALL. SG_ALL also
14135 * must not be exceeded, because it is used to define the
14136 * size of the scatter-gather table in 'struct asc_sg_head'.
14138 if (shost->sg_tablesize > SG_ALL) {
14139 shost->sg_tablesize = SG_ALL;
14142 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
14144 /* BIOS start address. */
14145 if (ASC_NARROW_BOARD(boardp)) {
14146 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
14147 asc_dvc_varp->bus_type);
14148 } else {
14150 * Fill-in BIOS board variables. The Wide BIOS saves
14151 * information in LRAM that is used by the driver.
14153 AdvReadWordLram(adv_dvc_varp->iop_base,
14154 BIOS_SIGNATURE, boardp->bios_signature);
14155 AdvReadWordLram(adv_dvc_varp->iop_base,
14156 BIOS_VERSION, boardp->bios_version);
14157 AdvReadWordLram(adv_dvc_varp->iop_base,
14158 BIOS_CODESEG, boardp->bios_codeseg);
14159 AdvReadWordLram(adv_dvc_varp->iop_base,
14160 BIOS_CODELEN, boardp->bios_codelen);
14162 ASC_DBG2(1,
14163 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
14164 boardp->bios_signature, boardp->bios_version);
14166 ASC_DBG2(1,
14167 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
14168 boardp->bios_codeseg, boardp->bios_codelen);
14171 * If the BIOS saved a valid signature, then fill in
14172 * the BIOS code segment base address.
14174 if (boardp->bios_signature == 0x55AA) {
14176 * Convert x86 realmode code segment to a linear
14177 * address by shifting left 4.
14179 shost->base = ((ulong)boardp->bios_codeseg << 4);
14180 } else {
14181 shost->base = 0;
14186 * Register Board Resources - I/O Port, DMA, IRQ
14189 /* Register DMA Channel for Narrow boards. */
14190 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
14191 #ifdef CONFIG_ISA
14192 if (ASC_NARROW_BOARD(boardp)) {
14193 /* Register DMA channel for ISA bus. */
14194 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
14195 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
14196 ret = request_dma(shost->dma_channel, DRV_NAME);
14197 if (ret) {
14198 ASC_PRINT3
14199 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
14200 boardp->id, shost->dma_channel, ret);
14201 goto err_free_proc;
14203 AscEnableIsaDma(shost->dma_channel);
14206 #endif /* CONFIG_ISA */
14208 /* Register IRQ Number. */
14209 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", boardp->irq);
14211 ret = request_irq(boardp->irq, advansys_interrupt, share_irq,
14212 DRV_NAME, shost);
14214 if (ret) {
14215 if (ret == -EBUSY) {
14216 ASC_PRINT2
14217 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
14218 boardp->id, boardp->irq);
14219 } else if (ret == -EINVAL) {
14220 ASC_PRINT2
14221 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
14222 boardp->id, boardp->irq);
14223 } else {
14224 ASC_PRINT3
14225 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
14226 boardp->id, boardp->irq, ret);
14228 goto err_free_dma;
14232 * Initialize board RISC chip and enable interrupts.
14234 if (ASC_NARROW_BOARD(boardp)) {
14235 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
14236 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
14238 if (warn_code || asc_dvc_varp->err_code) {
14239 ASC_PRINT4("advansys_board_found: board %d error: "
14240 "init_state 0x%x, warn 0x%x, error 0x%x\n",
14241 boardp->id, asc_dvc_varp->init_state,
14242 warn_code, asc_dvc_varp->err_code);
14243 if (asc_dvc_varp->err_code)
14244 ret = -ENODEV;
14246 } else {
14247 if (advansys_wide_init_chip(boardp, adv_dvc_varp))
14248 ret = -ENODEV;
14251 if (ret)
14252 goto err_free_wide_mem;
14254 ASC_DBG_PRT_SCSI_HOST(2, shost);
14256 ret = scsi_add_host(shost, boardp->dev);
14257 if (ret)
14258 goto err_free_wide_mem;
14260 scsi_scan_host(shost);
14261 return 0;
14263 err_free_wide_mem:
14264 advansys_wide_free_mem(boardp);
14265 free_irq(boardp->irq, shost);
14266 err_free_dma:
14267 if (shost->dma_channel != NO_ISA_DMA)
14268 free_dma(shost->dma_channel);
14269 err_free_proc:
14270 kfree(boardp->prtbuf);
14271 err_unmap:
14272 if (boardp->ioremap_addr)
14273 iounmap(boardp->ioremap_addr);
14274 err_shost:
14275 return ret;
14279 * advansys_release()
14281 * Release resources allocated for a single AdvanSys adapter.
14283 static int advansys_release(struct Scsi_Host *shost)
14285 asc_board_t *boardp;
14287 ASC_DBG(1, "advansys_release: begin\n");
14288 scsi_remove_host(shost);
14289 boardp = ASC_BOARDP(shost);
14290 free_irq(boardp->irq, shost);
14291 if (shost->dma_channel != NO_ISA_DMA) {
14292 ASC_DBG(1, "advansys_release: free_dma()\n");
14293 free_dma(shost->dma_channel);
14295 if (!ASC_NARROW_BOARD(boardp)) {
14296 iounmap(boardp->ioremap_addr);
14297 advansys_wide_free_mem(boardp);
14299 kfree(boardp->prtbuf);
14300 scsi_host_put(shost);
14301 ASC_DBG(1, "advansys_release: end\n");
14302 return 0;
14305 #define ASC_IOADR_TABLE_MAX_IX 11
14307 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
14308 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
14309 0x0210, 0x0230, 0x0250, 0x0330
14313 * The ISA IRQ number is found in bits 2 and 3 of the CfgLsw. It decodes as:
14314 * 00: 10
14315 * 01: 11
14316 * 10: 12
14317 * 11: 15
14319 static unsigned int __devinit advansys_isa_irq_no(PortAddr iop_base)
14321 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
14322 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x03) + 10;
14323 if (chip_irq == 13)
14324 chip_irq = 15;
14325 return chip_irq;
14328 static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
14330 int err = -ENODEV;
14331 PortAddr iop_base = _asc_def_iop_base[id];
14332 struct Scsi_Host *shost;
14333 struct asc_board *board;
14335 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
14336 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
14337 iop_base);
14338 return -ENODEV;
14340 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
14341 if (!AscFindSignature(iop_base))
14342 goto release_region;
14343 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
14344 goto release_region;
14346 err = -ENOMEM;
14347 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14348 if (!shost)
14349 goto release_region;
14351 board = ASC_BOARDP(shost);
14352 board->irq = advansys_isa_irq_no(iop_base);
14353 board->dev = dev;
14355 err = advansys_board_found(shost, iop_base, ASC_IS_ISA);
14356 if (err)
14357 goto free_host;
14359 dev_set_drvdata(dev, shost);
14360 return 0;
14362 free_host:
14363 scsi_host_put(shost);
14364 release_region:
14365 release_region(iop_base, ASC_IOADR_GAP);
14366 return err;
14369 static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
14371 int ioport = _asc_def_iop_base[id];
14372 advansys_release(dev_get_drvdata(dev));
14373 release_region(ioport, ASC_IOADR_GAP);
14374 return 0;
14377 static struct isa_driver advansys_isa_driver = {
14378 .probe = advansys_isa_probe,
14379 .remove = __devexit_p(advansys_isa_remove),
14380 .driver = {
14381 .owner = THIS_MODULE,
14382 .name = DRV_NAME,
14387 * The VLB IRQ number is found in bits 2 to 4 of the CfgLsw. It decodes as:
14388 * 000: invalid
14389 * 001: 10
14390 * 010: 11
14391 * 011: 12
14392 * 100: invalid
14393 * 101: 14
14394 * 110: 15
14395 * 111: invalid
14397 static unsigned int __devinit advansys_vlb_irq_no(PortAddr iop_base)
14399 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
14400 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x07) + 9;
14401 if ((chip_irq < 10) || (chip_irq == 13) || (chip_irq > 15))
14402 return 0;
14403 return chip_irq;
14406 static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
14408 int err = -ENODEV;
14409 PortAddr iop_base = _asc_def_iop_base[id];
14410 struct Scsi_Host *shost;
14411 struct asc_board *board;
14413 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
14414 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
14415 iop_base);
14416 return -ENODEV;
14418 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
14419 if (!AscFindSignature(iop_base))
14420 goto release_region;
14422 * I don't think this condition can actually happen, but the old
14423 * driver did it, and the chances of finding a VLB setup in 2007
14424 * to do testing with is slight to none.
14426 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
14427 goto release_region;
14429 err = -ENOMEM;
14430 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14431 if (!shost)
14432 goto release_region;
14434 board = ASC_BOARDP(shost);
14435 board->irq = advansys_vlb_irq_no(iop_base);
14436 board->dev = dev;
14438 err = advansys_board_found(shost, iop_base, ASC_IS_VL);
14439 if (err)
14440 goto free_host;
14442 dev_set_drvdata(dev, shost);
14443 return 0;
14445 free_host:
14446 scsi_host_put(shost);
14447 release_region:
14448 release_region(iop_base, ASC_IOADR_GAP);
14449 return -ENODEV;
14452 static struct isa_driver advansys_vlb_driver = {
14453 .probe = advansys_vlb_probe,
14454 .remove = __devexit_p(advansys_isa_remove),
14455 .driver = {
14456 .owner = THIS_MODULE,
14457 .name = "advansys_vlb",
14461 static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
14462 { "ABP7401" },
14463 { "ABP7501" },
14464 { "" }
14467 MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
14470 * EISA is a little more tricky than PCI; each EISA device may have two
14471 * channels, and this driver is written to make each channel its own Scsi_Host
14473 struct eisa_scsi_data {
14474 struct Scsi_Host *host[2];
14478 * The EISA IRQ number is found in bits 8 to 10 of the CfgLsw. It decodes as:
14479 * 000: 10
14480 * 001: 11
14481 * 010: 12
14482 * 011: invalid
14483 * 100: 14
14484 * 101: 15
14485 * 110: invalid
14486 * 111: invalid
14488 static unsigned int __devinit advansys_eisa_irq_no(struct eisa_device *edev)
14490 unsigned short cfg_lsw = inw(edev->base_addr + 0xc86);
14491 unsigned int chip_irq = ((cfg_lsw >> 8) & 0x07) + 10;
14492 if ((chip_irq == 13) || (chip_irq > 15))
14493 return 0;
14494 return chip_irq;
14497 static int __devinit advansys_eisa_probe(struct device *dev)
14499 int i, ioport, irq = 0;
14500 int err;
14501 struct eisa_device *edev = to_eisa_device(dev);
14502 struct eisa_scsi_data *data;
14504 err = -ENOMEM;
14505 data = kzalloc(sizeof(*data), GFP_KERNEL);
14506 if (!data)
14507 goto fail;
14508 ioport = edev->base_addr + 0xc30;
14510 err = -ENODEV;
14511 for (i = 0; i < 2; i++, ioport += 0x20) {
14512 struct asc_board *board;
14513 struct Scsi_Host *shost;
14514 if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) {
14515 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
14516 ioport + ASC_IOADR_GAP - 1);
14517 continue;
14519 if (!AscFindSignature(ioport)) {
14520 release_region(ioport, ASC_IOADR_GAP);
14521 continue;
14525 * I don't know why we need to do this for EISA chips, but
14526 * not for any others. It looks to be equivalent to
14527 * AscGetChipCfgMsw, but I may have overlooked something,
14528 * so I'm not converting it until I get an EISA board to
14529 * test with.
14531 inw(ioport + 4);
14533 if (!irq)
14534 irq = advansys_eisa_irq_no(edev);
14536 err = -ENOMEM;
14537 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14538 if (!shost)
14539 goto release_region;
14541 board = ASC_BOARDP(shost);
14542 board->irq = irq;
14543 board->dev = dev;
14545 err = advansys_board_found(shost, ioport, ASC_IS_EISA);
14546 if (!err) {
14547 data->host[i] = shost;
14548 continue;
14551 scsi_host_put(shost);
14552 release_region:
14553 release_region(ioport, ASC_IOADR_GAP);
14554 break;
14557 if (err)
14558 goto free_data;
14559 dev_set_drvdata(dev, data);
14560 return 0;
14562 free_data:
14563 kfree(data->host[0]);
14564 kfree(data->host[1]);
14565 kfree(data);
14566 fail:
14567 return err;
14570 static __devexit int advansys_eisa_remove(struct device *dev)
14572 int i;
14573 struct eisa_scsi_data *data = dev_get_drvdata(dev);
14575 for (i = 0; i < 2; i++) {
14576 int ioport;
14577 struct Scsi_Host *shost = data->host[i];
14578 if (!shost)
14579 continue;
14580 ioport = shost->io_port;
14581 advansys_release(shost);
14582 release_region(ioport, ASC_IOADR_GAP);
14585 kfree(data);
14586 return 0;
14589 static struct eisa_driver advansys_eisa_driver = {
14590 .id_table = advansys_eisa_table,
14591 .driver = {
14592 .name = DRV_NAME,
14593 .probe = advansys_eisa_probe,
14594 .remove = __devexit_p(advansys_eisa_remove),
14598 /* PCI Devices supported by this driver */
14599 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
14600 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
14601 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14602 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
14603 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14604 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
14605 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14606 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
14607 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14608 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
14609 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14610 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
14611 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14615 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
14617 static void __devinit advansys_set_latency(struct pci_dev *pdev)
14619 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
14620 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
14621 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
14622 } else {
14623 u8 latency;
14624 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
14625 if (latency < 0x20)
14626 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
14630 static int __devinit
14631 advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14633 int err, ioport;
14634 struct Scsi_Host *shost;
14635 struct asc_board *board;
14637 err = pci_enable_device(pdev);
14638 if (err)
14639 goto fail;
14640 err = pci_request_regions(pdev, DRV_NAME);
14641 if (err)
14642 goto disable_device;
14643 pci_set_master(pdev);
14644 advansys_set_latency(pdev);
14646 err = -ENODEV;
14647 if (pci_resource_len(pdev, 0) == 0)
14648 goto release_region;
14650 ioport = pci_resource_start(pdev, 0);
14652 err = -ENOMEM;
14653 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14654 if (!shost)
14655 goto release_region;
14657 board = ASC_BOARDP(shost);
14658 board->irq = pdev->irq;
14659 board->dev = &pdev->dev;
14661 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
14662 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
14663 pdev->device == PCI_DEVICE_ID_38C1600_REV1) {
14664 board->flags |= ASC_IS_WIDE_BOARD;
14667 err = advansys_board_found(shost, ioport, ASC_IS_PCI);
14668 if (err)
14669 goto free_host;
14671 pci_set_drvdata(pdev, shost);
14672 return 0;
14674 free_host:
14675 scsi_host_put(shost);
14676 release_region:
14677 pci_release_regions(pdev);
14678 disable_device:
14679 pci_disable_device(pdev);
14680 fail:
14681 return err;
14684 static void __devexit advansys_pci_remove(struct pci_dev *pdev)
14686 advansys_release(pci_get_drvdata(pdev));
14687 pci_release_regions(pdev);
14688 pci_disable_device(pdev);
14691 static struct pci_driver advansys_pci_driver = {
14692 .name = DRV_NAME,
14693 .id_table = advansys_pci_tbl,
14694 .probe = advansys_pci_probe,
14695 .remove = __devexit_p(advansys_pci_remove),
14698 static int __init advansys_init(void)
14700 int error;
14702 error = isa_register_driver(&advansys_isa_driver,
14703 ASC_IOADR_TABLE_MAX_IX);
14704 if (error)
14705 goto fail;
14707 error = isa_register_driver(&advansys_vlb_driver,
14708 ASC_IOADR_TABLE_MAX_IX);
14709 if (error)
14710 goto unregister_isa;
14712 error = eisa_driver_register(&advansys_eisa_driver);
14713 if (error)
14714 goto unregister_vlb;
14716 error = pci_register_driver(&advansys_pci_driver);
14717 if (error)
14718 goto unregister_eisa;
14720 return 0;
14722 unregister_eisa:
14723 eisa_driver_unregister(&advansys_eisa_driver);
14724 unregister_vlb:
14725 isa_unregister_driver(&advansys_vlb_driver);
14726 unregister_isa:
14727 isa_unregister_driver(&advansys_isa_driver);
14728 fail:
14729 return error;
14732 static void __exit advansys_exit(void)
14734 pci_unregister_driver(&advansys_pci_driver);
14735 eisa_driver_unregister(&advansys_eisa_driver);
14736 isa_unregister_driver(&advansys_vlb_driver);
14737 isa_unregister_driver(&advansys_isa_driver);
14740 module_init(advansys_init);
14741 module_exit(advansys_exit);
14743 MODULE_LICENSE("GPL");