[SCSI] advansys: Sort out debug macros
[linux-2.6/btrfs-unstable.git] / drivers / scsi / advansys.c
blob6bd8e835ea0f769d65b2f6673d66c3f7c5be7317
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 #undef ADVANSYS_DEBUG
81 * Portable Data Types
83 * Any instance where a 32-bit long or pointer type is assumed
84 * for precision or HW defined structures, the following define
85 * types must be used. In Linux the char, short, and int types
86 * are all consistent at 8, 16, and 32 bits respectively. Pointers
87 * and long types are 64 bits on Alpha and UltraSPARC.
89 #define ASC_PADDR __u32 /* Physical/Bus address data type. */
90 #define ASC_VADDR __u32 /* Virtual address data type. */
91 #define ASC_DCNT __u32 /* Unsigned Data count type. */
92 #define ASC_SDCNT __s32 /* Signed Data count type. */
95 * These macros are used to convert a virtual address to a
96 * 32-bit value. This currently can be used on Linux Alpha
97 * which uses 64-bit virtual address but a 32-bit bus address.
98 * This is likely to break in the future, but doing this now
99 * will give us time to change the HW and FW to handle 64-bit
100 * addresses.
102 #define ASC_VADDR_TO_U32 virt_to_bus
103 #define ASC_U32_TO_VADDR bus_to_virt
105 typedef unsigned char uchar;
107 #ifndef TRUE
108 #define TRUE (1)
109 #endif
110 #ifndef FALSE
111 #define FALSE (0)
112 #endif
114 #define ERR (-1)
115 #define UW_ERR (uint)(0xFFFF)
116 #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
118 #define PCI_VENDOR_ID_ASP 0x10cd
119 #define PCI_DEVICE_ID_ASP_1200A 0x1100
120 #define PCI_DEVICE_ID_ASP_ABP940 0x1200
121 #define PCI_DEVICE_ID_ASP_ABP940U 0x1300
122 #define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
123 #define PCI_DEVICE_ID_38C0800_REV1 0x2500
124 #define PCI_DEVICE_ID_38C1600_REV1 0x2700
127 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
128 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
129 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
130 * SRB structure.
132 #define CC_VERY_LONG_SG_LIST 0
133 #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
135 #define PortAddr unsigned short /* port address size */
136 #define inp(port) inb(port)
137 #define outp(port, byte) outb((byte), (port))
139 #define inpw(port) inw(port)
140 #define outpw(port, word) outw((word), (port))
142 #define ASC_MAX_SG_QUEUE 7
143 #define ASC_MAX_SG_LIST 255
145 #define ASC_CS_TYPE unsigned short
147 #define ASC_IS_ISA (0x0001)
148 #define ASC_IS_ISAPNP (0x0081)
149 #define ASC_IS_EISA (0x0002)
150 #define ASC_IS_PCI (0x0004)
151 #define ASC_IS_PCI_ULTRA (0x0104)
152 #define ASC_IS_PCMCIA (0x0008)
153 #define ASC_IS_MCA (0x0020)
154 #define ASC_IS_VL (0x0040)
155 #define ASC_IS_WIDESCSI_16 (0x0100)
156 #define ASC_IS_WIDESCSI_32 (0x0200)
157 #define ASC_IS_BIG_ENDIAN (0x8000)
159 #define ASC_CHIP_MIN_VER_VL (0x01)
160 #define ASC_CHIP_MAX_VER_VL (0x07)
161 #define ASC_CHIP_MIN_VER_PCI (0x09)
162 #define ASC_CHIP_MAX_VER_PCI (0x0F)
163 #define ASC_CHIP_VER_PCI_BIT (0x08)
164 #define ASC_CHIP_MIN_VER_ISA (0x11)
165 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
166 #define ASC_CHIP_MAX_VER_ISA (0x27)
167 #define ASC_CHIP_VER_ISA_BIT (0x30)
168 #define ASC_CHIP_VER_ISAPNP_BIT (0x20)
169 #define ASC_CHIP_VER_ASYN_BUG (0x21)
170 #define ASC_CHIP_VER_PCI 0x08
171 #define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
172 #define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
173 #define ASC_CHIP_MIN_VER_EISA (0x41)
174 #define ASC_CHIP_MAX_VER_EISA (0x47)
175 #define ASC_CHIP_VER_EISA_BIT (0x40)
176 #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
177 #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
178 #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
179 #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
181 #define ASC_SCSI_ID_BITS 3
182 #define ASC_SCSI_TIX_TYPE uchar
183 #define ASC_ALL_DEVICE_BIT_SET 0xFF
184 #define ASC_SCSI_BIT_ID_TYPE uchar
185 #define ASC_MAX_TID 7
186 #define ASC_MAX_LUN 7
187 #define ASC_SCSI_WIDTH_BIT_SET 0xFF
188 #define ASC_MAX_SENSE_LEN 32
189 #define ASC_MIN_SENSE_LEN 14
190 #define ASC_SCSI_RESET_HOLD_TIME_US 60
193 * Narrow boards only support 12-byte commands, while wide boards
194 * extend to 16-byte commands.
196 #define ASC_MAX_CDB_LEN 12
197 #define ADV_MAX_CDB_LEN 16
199 #define MS_SDTR_LEN 0x03
200 #define MS_WDTR_LEN 0x02
202 #define ASC_SG_LIST_PER_Q 7
203 #define QS_FREE 0x00
204 #define QS_READY 0x01
205 #define QS_DISC1 0x02
206 #define QS_DISC2 0x04
207 #define QS_BUSY 0x08
208 #define QS_ABORTED 0x40
209 #define QS_DONE 0x80
210 #define QC_NO_CALLBACK 0x01
211 #define QC_SG_SWAP_QUEUE 0x02
212 #define QC_SG_HEAD 0x04
213 #define QC_DATA_IN 0x08
214 #define QC_DATA_OUT 0x10
215 #define QC_URGENT 0x20
216 #define QC_MSG_OUT 0x40
217 #define QC_REQ_SENSE 0x80
218 #define QCSG_SG_XFER_LIST 0x02
219 #define QCSG_SG_XFER_MORE 0x04
220 #define QCSG_SG_XFER_END 0x08
221 #define QD_IN_PROGRESS 0x00
222 #define QD_NO_ERROR 0x01
223 #define QD_ABORTED_BY_HOST 0x02
224 #define QD_WITH_ERROR 0x04
225 #define QD_INVALID_REQUEST 0x80
226 #define QD_INVALID_HOST_NUM 0x81
227 #define QD_INVALID_DEVICE 0x82
228 #define QD_ERR_INTERNAL 0xFF
229 #define QHSTA_NO_ERROR 0x00
230 #define QHSTA_M_SEL_TIMEOUT 0x11
231 #define QHSTA_M_DATA_OVER_RUN 0x12
232 #define QHSTA_M_DATA_UNDER_RUN 0x12
233 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
234 #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
235 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
236 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
237 #define QHSTA_D_HOST_ABORT_FAILED 0x23
238 #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
239 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
240 #define QHSTA_D_ASPI_NO_BUF_POOL 0x26
241 #define QHSTA_M_WTM_TIMEOUT 0x41
242 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
243 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
244 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
245 #define QHSTA_M_TARGET_STATUS_BUSY 0x45
246 #define QHSTA_M_BAD_TAG_CODE 0x46
247 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
248 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
249 #define QHSTA_D_LRAM_CMP_ERROR 0x81
250 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
251 #define ASC_FLAG_SCSIQ_REQ 0x01
252 #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
253 #define ASC_FLAG_BIOS_ASYNC_IO 0x04
254 #define ASC_FLAG_SRB_LINEAR_ADDR 0x08
255 #define ASC_FLAG_WIN16 0x10
256 #define ASC_FLAG_WIN32 0x20
257 #define ASC_FLAG_ISA_OVER_16MB 0x40
258 #define ASC_FLAG_DOS_VM_CALLBACK 0x80
259 #define ASC_TAG_FLAG_EXTRA_BYTES 0x10
260 #define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
261 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
262 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
263 #define ASC_SCSIQ_CPY_BEG 4
264 #define ASC_SCSIQ_SGHD_CPY_BEG 2
265 #define ASC_SCSIQ_B_FWD 0
266 #define ASC_SCSIQ_B_BWD 1
267 #define ASC_SCSIQ_B_STATUS 2
268 #define ASC_SCSIQ_B_QNO 3
269 #define ASC_SCSIQ_B_CNTL 4
270 #define ASC_SCSIQ_B_SG_QUEUE_CNT 5
271 #define ASC_SCSIQ_D_DATA_ADDR 8
272 #define ASC_SCSIQ_D_DATA_CNT 12
273 #define ASC_SCSIQ_B_SENSE_LEN 20
274 #define ASC_SCSIQ_DONE_INFO_BEG 22
275 #define ASC_SCSIQ_D_SRBPTR 22
276 #define ASC_SCSIQ_B_TARGET_IX 26
277 #define ASC_SCSIQ_B_CDB_LEN 28
278 #define ASC_SCSIQ_B_TAG_CODE 29
279 #define ASC_SCSIQ_W_VM_ID 30
280 #define ASC_SCSIQ_DONE_STATUS 32
281 #define ASC_SCSIQ_HOST_STATUS 33
282 #define ASC_SCSIQ_SCSI_STATUS 34
283 #define ASC_SCSIQ_CDB_BEG 36
284 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
285 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
286 #define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
287 #define ASC_SCSIQ_B_SG_WK_QP 49
288 #define ASC_SCSIQ_B_SG_WK_IX 50
289 #define ASC_SCSIQ_W_ALT_DC1 52
290 #define ASC_SCSIQ_B_LIST_CNT 6
291 #define ASC_SCSIQ_B_CUR_LIST_CNT 7
292 #define ASC_SGQ_B_SG_CNTL 4
293 #define ASC_SGQ_B_SG_HEAD_QP 5
294 #define ASC_SGQ_B_SG_LIST_CNT 6
295 #define ASC_SGQ_B_SG_CUR_LIST_CNT 7
296 #define ASC_SGQ_LIST_BEG 8
297 #define ASC_DEF_SCSI1_QNG 4
298 #define ASC_MAX_SCSI1_QNG 4
299 #define ASC_DEF_SCSI2_QNG 16
300 #define ASC_MAX_SCSI2_QNG 32
301 #define ASC_TAG_CODE_MASK 0x23
302 #define ASC_STOP_REQ_RISC_STOP 0x01
303 #define ASC_STOP_ACK_RISC_STOP 0x03
304 #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
305 #define ASC_STOP_CLEAN_UP_DISC_Q 0x20
306 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
307 #define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
308 #define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
309 #define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
310 #define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
311 #define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
312 #define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
313 #define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
315 typedef struct asc_scsiq_1 {
316 uchar status;
317 uchar q_no;
318 uchar cntl;
319 uchar sg_queue_cnt;
320 uchar target_id;
321 uchar target_lun;
322 ASC_PADDR data_addr;
323 ASC_DCNT data_cnt;
324 ASC_PADDR sense_addr;
325 uchar sense_len;
326 uchar extra_bytes;
327 } ASC_SCSIQ_1;
329 typedef struct asc_scsiq_2 {
330 ASC_VADDR srb_ptr;
331 uchar target_ix;
332 uchar flag;
333 uchar cdb_len;
334 uchar tag_code;
335 ushort vm_id;
336 } ASC_SCSIQ_2;
338 typedef struct asc_scsiq_3 {
339 uchar done_stat;
340 uchar host_stat;
341 uchar scsi_stat;
342 uchar scsi_msg;
343 } ASC_SCSIQ_3;
345 typedef struct asc_scsiq_4 {
346 uchar cdb[ASC_MAX_CDB_LEN];
347 uchar y_first_sg_list_qp;
348 uchar y_working_sg_qp;
349 uchar y_working_sg_ix;
350 uchar y_res;
351 ushort x_req_count;
352 ushort x_reconnect_rtn;
353 ASC_PADDR x_saved_data_addr;
354 ASC_DCNT x_saved_data_cnt;
355 } ASC_SCSIQ_4;
357 typedef struct asc_q_done_info {
358 ASC_SCSIQ_2 d2;
359 ASC_SCSIQ_3 d3;
360 uchar q_status;
361 uchar q_no;
362 uchar cntl;
363 uchar sense_len;
364 uchar extra_bytes;
365 uchar res;
366 ASC_DCNT remain_bytes;
367 } ASC_QDONE_INFO;
369 typedef struct asc_sg_list {
370 ASC_PADDR addr;
371 ASC_DCNT bytes;
372 } ASC_SG_LIST;
374 typedef struct asc_sg_head {
375 ushort entry_cnt;
376 ushort queue_cnt;
377 ushort entry_to_copy;
378 ushort res;
379 ASC_SG_LIST sg_list[0];
380 } ASC_SG_HEAD;
382 typedef struct asc_scsi_q {
383 ASC_SCSIQ_1 q1;
384 ASC_SCSIQ_2 q2;
385 uchar *cdbptr;
386 ASC_SG_HEAD *sg_head;
387 ushort remain_sg_entry_cnt;
388 ushort next_sg_index;
389 } ASC_SCSI_Q;
391 typedef struct asc_scsi_req_q {
392 ASC_SCSIQ_1 r1;
393 ASC_SCSIQ_2 r2;
394 uchar *cdbptr;
395 ASC_SG_HEAD *sg_head;
396 uchar *sense_ptr;
397 ASC_SCSIQ_3 r3;
398 uchar cdb[ASC_MAX_CDB_LEN];
399 uchar sense[ASC_MIN_SENSE_LEN];
400 } ASC_SCSI_REQ_Q;
402 typedef struct asc_scsi_bios_req_q {
403 ASC_SCSIQ_1 r1;
404 ASC_SCSIQ_2 r2;
405 uchar *cdbptr;
406 ASC_SG_HEAD *sg_head;
407 uchar *sense_ptr;
408 ASC_SCSIQ_3 r3;
409 uchar cdb[ASC_MAX_CDB_LEN];
410 uchar sense[ASC_MIN_SENSE_LEN];
411 } ASC_SCSI_BIOS_REQ_Q;
413 typedef struct asc_risc_q {
414 uchar fwd;
415 uchar bwd;
416 ASC_SCSIQ_1 i1;
417 ASC_SCSIQ_2 i2;
418 ASC_SCSIQ_3 i3;
419 ASC_SCSIQ_4 i4;
420 } ASC_RISC_Q;
422 typedef struct asc_sg_list_q {
423 uchar seq_no;
424 uchar q_no;
425 uchar cntl;
426 uchar sg_head_qp;
427 uchar sg_list_cnt;
428 uchar sg_cur_list_cnt;
429 } ASC_SG_LIST_Q;
431 typedef struct asc_risc_sg_list_q {
432 uchar fwd;
433 uchar bwd;
434 ASC_SG_LIST_Q sg;
435 ASC_SG_LIST sg_list[7];
436 } ASC_RISC_SG_LIST_Q;
438 #define ASCQ_ERR_Q_STATUS 0x0D
439 #define ASCQ_ERR_CUR_QNG 0x17
440 #define ASCQ_ERR_SG_Q_LINKS 0x18
441 #define ASCQ_ERR_ISR_RE_ENTRY 0x1A
442 #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
443 #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
446 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
448 #define ASC_WARN_NO_ERROR 0x0000
449 #define ASC_WARN_IO_PORT_ROTATE 0x0001
450 #define ASC_WARN_EEPROM_CHKSUM 0x0002
451 #define ASC_WARN_IRQ_MODIFIED 0x0004
452 #define ASC_WARN_AUTO_CONFIG 0x0008
453 #define ASC_WARN_CMD_QNG_CONFLICT 0x0010
454 #define ASC_WARN_EEPROM_RECOVER 0x0020
455 #define ASC_WARN_CFG_MSW_RECOVER 0x0040
458 * Error code values are set in {ASC/ADV}_DVC_VAR 'err_code'.
460 #define ASC_IERR_NO_CARRIER 0x0001 /* No more carrier memory */
461 #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
462 #define ASC_IERR_SET_PC_ADDR 0x0004
463 #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
464 #define ASC_IERR_ILLEGAL_CONNECTION 0x0010 /* Illegal cable connection */
465 #define ASC_IERR_SINGLE_END_DEVICE 0x0020 /* SE device on DIFF bus */
466 #define ASC_IERR_REVERSED_CABLE 0x0040 /* Narrow flat cable reversed */
467 #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
468 #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD device on LVD port */
469 #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
470 #define ASC_IERR_NO_BUS_TYPE 0x0400
471 #define ASC_IERR_BIST_PRE_TEST 0x0800 /* BIST pre-test error */
472 #define ASC_IERR_BIST_RAM_TEST 0x1000 /* BIST RAM test error */
473 #define ASC_IERR_BAD_CHIPTYPE 0x2000 /* Invalid chip_type setting */
475 #define ASC_DEF_MAX_TOTAL_QNG (0xF0)
476 #define ASC_MIN_TAG_Q_PER_DVC (0x04)
477 #define ASC_MIN_FREE_Q (0x02)
478 #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
479 #define ASC_MAX_TOTAL_QNG 240
480 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
481 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
482 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
483 #define ASC_MAX_INRAM_TAG_QNG 16
484 #define ASC_IOADR_GAP 0x10
485 #define ASC_MAX_SYN_XFER_NO 16
486 #define ASC_SYN_MAX_OFFSET 0x0F
487 #define ASC_DEF_SDTR_OFFSET 0x0F
488 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
489 #define SYN_XFER_NS_0 25
490 #define SYN_XFER_NS_1 30
491 #define SYN_XFER_NS_2 35
492 #define SYN_XFER_NS_3 40
493 #define SYN_XFER_NS_4 50
494 #define SYN_XFER_NS_5 60
495 #define SYN_XFER_NS_6 70
496 #define SYN_XFER_NS_7 85
497 #define SYN_ULTRA_XFER_NS_0 12
498 #define SYN_ULTRA_XFER_NS_1 19
499 #define SYN_ULTRA_XFER_NS_2 25
500 #define SYN_ULTRA_XFER_NS_3 32
501 #define SYN_ULTRA_XFER_NS_4 38
502 #define SYN_ULTRA_XFER_NS_5 44
503 #define SYN_ULTRA_XFER_NS_6 50
504 #define SYN_ULTRA_XFER_NS_7 57
505 #define SYN_ULTRA_XFER_NS_8 63
506 #define SYN_ULTRA_XFER_NS_9 69
507 #define SYN_ULTRA_XFER_NS_10 75
508 #define SYN_ULTRA_XFER_NS_11 82
509 #define SYN_ULTRA_XFER_NS_12 88
510 #define SYN_ULTRA_XFER_NS_13 94
511 #define SYN_ULTRA_XFER_NS_14 100
512 #define SYN_ULTRA_XFER_NS_15 107
514 typedef struct ext_msg {
515 uchar msg_type;
516 uchar msg_len;
517 uchar msg_req;
518 union {
519 struct {
520 uchar sdtr_xfer_period;
521 uchar sdtr_req_ack_offset;
522 } sdtr;
523 struct {
524 uchar wdtr_width;
525 } wdtr;
526 struct {
527 uchar mdp_b3;
528 uchar mdp_b2;
529 uchar mdp_b1;
530 uchar mdp_b0;
531 } mdp;
532 } u_ext_msg;
533 uchar res;
534 } EXT_MSG;
536 #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
537 #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
538 #define wdtr_width u_ext_msg.wdtr.wdtr_width
539 #define mdp_b3 u_ext_msg.mdp_b3
540 #define mdp_b2 u_ext_msg.mdp_b2
541 #define mdp_b1 u_ext_msg.mdp_b1
542 #define mdp_b0 u_ext_msg.mdp_b0
544 typedef struct asc_dvc_cfg {
545 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
546 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
547 ASC_SCSI_BIT_ID_TYPE disc_enable;
548 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
549 uchar chip_scsi_id;
550 uchar isa_dma_speed;
551 uchar isa_dma_channel;
552 uchar chip_version;
553 ushort mcode_date;
554 ushort mcode_version;
555 uchar max_tag_qng[ASC_MAX_TID + 1];
556 uchar *overrun_buf;
557 uchar sdtr_period_offset[ASC_MAX_TID + 1];
558 uchar adapter_info[6];
559 } ASC_DVC_CFG;
561 #define ASC_DEF_DVC_CNTL 0xFFFF
562 #define ASC_DEF_CHIP_SCSI_ID 7
563 #define ASC_DEF_ISA_DMA_SPEED 4
564 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001
565 #define ASC_INIT_STATE_END_GET_CFG 0x0002
566 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004
567 #define ASC_INIT_STATE_END_SET_CFG 0x0008
568 #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
569 #define ASC_INIT_STATE_END_LOAD_MC 0x0020
570 #define ASC_INIT_STATE_BEG_INQUIRY 0x0040
571 #define ASC_INIT_STATE_END_INQUIRY 0x0080
572 #define ASC_INIT_RESET_SCSI_DONE 0x0100
573 #define ASC_INIT_STATE_WITHOUT_EEP 0x8000
574 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001
575 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
576 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
577 #define ASC_MIN_TAGGED_CMD 7
578 #define ASC_MAX_SCSI_RESET_WAIT 30
580 struct asc_dvc_var; /* Forward Declaration. */
582 typedef struct asc_dvc_var {
583 PortAddr iop_base;
584 ushort err_code;
585 ushort dvc_cntl;
586 ushort bug_fix_cntl;
587 ushort bus_type;
588 ASC_SCSI_BIT_ID_TYPE init_sdtr;
589 ASC_SCSI_BIT_ID_TYPE sdtr_done;
590 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
591 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
592 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
593 ASC_SCSI_BIT_ID_TYPE start_motor;
594 uchar scsi_reset_wait;
595 uchar chip_no;
596 char is_in_int;
597 uchar max_total_qng;
598 uchar cur_total_qng;
599 uchar in_critical_cnt;
600 uchar last_q_shortage;
601 ushort init_state;
602 uchar cur_dvc_qng[ASC_MAX_TID + 1];
603 uchar max_dvc_qng[ASC_MAX_TID + 1];
604 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
605 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
606 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
607 ASC_DVC_CFG *cfg;
608 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
609 char redo_scam;
610 ushort res2;
611 uchar dos_int13_table[ASC_MAX_TID + 1];
612 ASC_DCNT max_dma_count;
613 ASC_SCSI_BIT_ID_TYPE no_scam;
614 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
615 uchar max_sdtr_index;
616 uchar host_init_sdtr_index;
617 struct asc_board *drv_ptr;
618 ASC_DCNT uc_break;
619 } ASC_DVC_VAR;
621 typedef struct asc_dvc_inq_info {
622 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
623 } ASC_DVC_INQ_INFO;
625 typedef struct asc_cap_info {
626 ASC_DCNT lba;
627 ASC_DCNT blk_size;
628 } ASC_CAP_INFO;
630 typedef struct asc_cap_info_array {
631 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
632 } ASC_CAP_INFO_ARRAY;
634 #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
635 #define ASC_MCNTL_NULL_TARGET (ushort)0x0002
636 #define ASC_CNTL_INITIATOR (ushort)0x0001
637 #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
638 #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
639 #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
640 #define ASC_CNTL_NO_SCAM (ushort)0x0010
641 #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
642 #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
643 #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
644 #define ASC_CNTL_RESET_SCSI (ushort)0x0200
645 #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
646 #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
647 #define ASC_CNTL_SCSI_PARITY (ushort)0x1000
648 #define ASC_CNTL_BURST_MODE (ushort)0x2000
649 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
650 #define ASC_EEP_DVC_CFG_BEG_VL 2
651 #define ASC_EEP_MAX_DVC_ADDR_VL 15
652 #define ASC_EEP_DVC_CFG_BEG 32
653 #define ASC_EEP_MAX_DVC_ADDR 45
654 #define ASC_EEP_MAX_RETRY 20
657 * These macros keep the chip SCSI id and ISA DMA speed
658 * bitfields in board order. C bitfields aren't portable
659 * between big and little-endian platforms so they are
660 * not used.
663 #define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
664 #define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
665 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
666 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
667 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
668 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
670 typedef struct asceep_config {
671 ushort cfg_lsw;
672 ushort cfg_msw;
673 uchar init_sdtr;
674 uchar disc_enable;
675 uchar use_cmd_qng;
676 uchar start_motor;
677 uchar max_total_qng;
678 uchar max_tag_qng;
679 uchar bios_scan;
680 uchar power_up_wait;
681 uchar no_scam;
682 uchar id_speed; /* low order 4 bits is chip scsi id */
683 /* high order 4 bits is isa dma speed */
684 uchar dos_int13_table[ASC_MAX_TID + 1];
685 uchar adapter_info[6];
686 ushort cntl;
687 ushort chksum;
688 } ASCEEP_CONFIG;
690 #define ASC_EEP_CMD_READ 0x80
691 #define ASC_EEP_CMD_WRITE 0x40
692 #define ASC_EEP_CMD_WRITE_ABLE 0x30
693 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
694 #define ASC_OVERRUN_BSIZE 0x00000048UL
695 #define ASCV_MSGOUT_BEG 0x0000
696 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
697 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
698 #define ASCV_BREAK_SAVED_CODE (ushort)0x0006
699 #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
700 #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
701 #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
702 #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
703 #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
704 #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
705 #define ASCV_BREAK_ADDR (ushort)0x0028
706 #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
707 #define ASCV_BREAK_CONTROL (ushort)0x002C
708 #define ASCV_BREAK_HIT_COUNT (ushort)0x002E
710 #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
711 #define ASCV_MCODE_CHKSUM_W (ushort)0x0032
712 #define ASCV_MCODE_SIZE_W (ushort)0x0034
713 #define ASCV_STOP_CODE_B (ushort)0x0036
714 #define ASCV_DVC_ERR_CODE_B (ushort)0x0037
715 #define ASCV_OVERRUN_PADDR_D (ushort)0x0038
716 #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
717 #define ASCV_HALTCODE_W (ushort)0x0040
718 #define ASCV_CHKSUM_W (ushort)0x0042
719 #define ASCV_MC_DATE_W (ushort)0x0044
720 #define ASCV_MC_VER_W (ushort)0x0046
721 #define ASCV_NEXTRDY_B (ushort)0x0048
722 #define ASCV_DONENEXT_B (ushort)0x0049
723 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
724 #define ASCV_SCSIBUSY_B (ushort)0x004B
725 #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
726 #define ASCV_CURCDB_B (ushort)0x004D
727 #define ASCV_RCLUN_B (ushort)0x004E
728 #define ASCV_BUSY_QHEAD_B (ushort)0x004F
729 #define ASCV_DISC1_QHEAD_B (ushort)0x0050
730 #define ASCV_DISC_ENABLE_B (ushort)0x0052
731 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
732 #define ASCV_HOSTSCSI_ID_B (ushort)0x0055
733 #define ASCV_MCODE_CNTL_B (ushort)0x0056
734 #define ASCV_NULL_TARGET_B (ushort)0x0057
735 #define ASCV_FREE_Q_HEAD_W (ushort)0x0058
736 #define ASCV_DONE_Q_TAIL_W (ushort)0x005A
737 #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
738 #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
739 #define ASCV_HOST_FLAG_B (ushort)0x005D
740 #define ASCV_TOTAL_READY_Q_B (ushort)0x0064
741 #define ASCV_VER_SERIAL_B (ushort)0x0065
742 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
743 #define ASCV_WTM_FLAG_B (ushort)0x0068
744 #define ASCV_RISC_FLAG_B (ushort)0x006A
745 #define ASCV_REQ_SG_LIST_QP (ushort)0x006B
746 #define ASC_HOST_FLAG_IN_ISR 0x01
747 #define ASC_HOST_FLAG_ACK_INT 0x02
748 #define ASC_RISC_FLAG_GEN_INT 0x01
749 #define ASC_RISC_FLAG_REQ_SG_LIST 0x02
750 #define IOP_CTRL (0x0F)
751 #define IOP_STATUS (0x0E)
752 #define IOP_INT_ACK IOP_STATUS
753 #define IOP_REG_IFC (0x0D)
754 #define IOP_SYN_OFFSET (0x0B)
755 #define IOP_EXTRA_CONTROL (0x0D)
756 #define IOP_REG_PC (0x0C)
757 #define IOP_RAM_ADDR (0x0A)
758 #define IOP_RAM_DATA (0x08)
759 #define IOP_EEP_DATA (0x06)
760 #define IOP_EEP_CMD (0x07)
761 #define IOP_VERSION (0x03)
762 #define IOP_CONFIG_HIGH (0x04)
763 #define IOP_CONFIG_LOW (0x02)
764 #define IOP_SIG_BYTE (0x01)
765 #define IOP_SIG_WORD (0x00)
766 #define IOP_REG_DC1 (0x0E)
767 #define IOP_REG_DC0 (0x0C)
768 #define IOP_REG_SB (0x0B)
769 #define IOP_REG_DA1 (0x0A)
770 #define IOP_REG_DA0 (0x08)
771 #define IOP_REG_SC (0x09)
772 #define IOP_DMA_SPEED (0x07)
773 #define IOP_REG_FLAG (0x07)
774 #define IOP_FIFO_H (0x06)
775 #define IOP_FIFO_L (0x04)
776 #define IOP_REG_ID (0x05)
777 #define IOP_REG_QP (0x03)
778 #define IOP_REG_IH (0x02)
779 #define IOP_REG_IX (0x01)
780 #define IOP_REG_AX (0x00)
781 #define IFC_REG_LOCK (0x00)
782 #define IFC_REG_UNLOCK (0x09)
783 #define IFC_WR_EN_FILTER (0x10)
784 #define IFC_RD_NO_EEPROM (0x10)
785 #define IFC_SLEW_RATE (0x20)
786 #define IFC_ACT_NEG (0x40)
787 #define IFC_INP_FILTER (0x80)
788 #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
789 #define SC_SEL (uchar)(0x80)
790 #define SC_BSY (uchar)(0x40)
791 #define SC_ACK (uchar)(0x20)
792 #define SC_REQ (uchar)(0x10)
793 #define SC_ATN (uchar)(0x08)
794 #define SC_IO (uchar)(0x04)
795 #define SC_CD (uchar)(0x02)
796 #define SC_MSG (uchar)(0x01)
797 #define SEC_SCSI_CTL (uchar)(0x80)
798 #define SEC_ACTIVE_NEGATE (uchar)(0x40)
799 #define SEC_SLEW_RATE (uchar)(0x20)
800 #define SEC_ENABLE_FILTER (uchar)(0x10)
801 #define ASC_HALT_EXTMSG_IN (ushort)0x8000
802 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
803 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
804 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
805 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
806 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
807 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
808 #define ASC_MAX_QNO 0xF8
809 #define ASC_DATA_SEC_BEG (ushort)0x0080
810 #define ASC_DATA_SEC_END (ushort)0x0080
811 #define ASC_CODE_SEC_BEG (ushort)0x0080
812 #define ASC_CODE_SEC_END (ushort)0x0080
813 #define ASC_QADR_BEG (0x4000)
814 #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
815 #define ASC_QADR_END (ushort)0x7FFF
816 #define ASC_QLAST_ADR (ushort)0x7FC0
817 #define ASC_QBLK_SIZE 0x40
818 #define ASC_BIOS_DATA_QBEG 0xF8
819 #define ASC_MIN_ACTIVE_QNO 0x01
820 #define ASC_QLINK_END 0xFF
821 #define ASC_EEPROM_WORDS 0x10
822 #define ASC_MAX_MGS_LEN 0x10
823 #define ASC_BIOS_ADDR_DEF 0xDC00
824 #define ASC_BIOS_SIZE 0x3800
825 #define ASC_BIOS_RAM_OFF 0x3800
826 #define ASC_BIOS_RAM_SIZE 0x800
827 #define ASC_BIOS_MIN_ADDR 0xC000
828 #define ASC_BIOS_MAX_ADDR 0xEC00
829 #define ASC_BIOS_BANK_SIZE 0x0400
830 #define ASC_MCODE_START_ADDR 0x0080
831 #define ASC_CFG0_HOST_INT_ON 0x0020
832 #define ASC_CFG0_BIOS_ON 0x0040
833 #define ASC_CFG0_VERA_BURST_ON 0x0080
834 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
835 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
836 #define ASC_CFG1_LRAM_8BITS_ON 0x0800
837 #define ASC_CFG_MSW_CLR_MASK 0x3080
838 #define CSW_TEST1 (ASC_CS_TYPE)0x8000
839 #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
840 #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
841 #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
842 #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
843 #define CSW_TEST2 (ASC_CS_TYPE)0x0400
844 #define CSW_TEST3 (ASC_CS_TYPE)0x0200
845 #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
846 #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
847 #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
848 #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
849 #define CSW_HALTED (ASC_CS_TYPE)0x0010
850 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
851 #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
852 #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
853 #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
854 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
855 #define CIW_INT_ACK (ASC_CS_TYPE)0x0100
856 #define CIW_TEST1 (ASC_CS_TYPE)0x0200
857 #define CIW_TEST2 (ASC_CS_TYPE)0x0400
858 #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
859 #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
860 #define CC_CHIP_RESET (uchar)0x80
861 #define CC_SCSI_RESET (uchar)0x40
862 #define CC_HALT (uchar)0x20
863 #define CC_SINGLE_STEP (uchar)0x10
864 #define CC_DMA_ABLE (uchar)0x08
865 #define CC_TEST (uchar)0x04
866 #define CC_BANK_ONE (uchar)0x02
867 #define CC_DIAG (uchar)0x01
868 #define ASC_1000_ID0W 0x04C1
869 #define ASC_1000_ID0W_FIX 0x00C1
870 #define ASC_1000_ID1B 0x25
871 #define ASC_EISA_REV_IOP_MASK (0x0C83)
872 #define ASC_EISA_CFG_IOP_MASK (0x0C86)
873 #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
874 #define INS_HALTINT (ushort)0x6281
875 #define INS_HALT (ushort)0x6280
876 #define INS_SINT (ushort)0x6200
877 #define INS_RFLAG_WTM (ushort)0x7380
878 #define ASC_MC_SAVE_CODE_WSIZE 0x500
879 #define ASC_MC_SAVE_DATA_WSIZE 0x40
881 typedef struct asc_mc_saved {
882 ushort data[ASC_MC_SAVE_DATA_WSIZE];
883 ushort code[ASC_MC_SAVE_CODE_WSIZE];
884 } ASC_MC_SAVED;
886 #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
887 #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
888 #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
889 #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
890 #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
891 #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
892 #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
893 #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
894 #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
895 #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
896 #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data))
897 #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id))
898 #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data)
899 #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id))
900 #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
901 #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
902 #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
903 #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
904 #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
905 #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
906 #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
907 #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
908 #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
909 #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
910 #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
911 #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
912 #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
913 #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
914 #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
915 #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
916 #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
917 #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
918 #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
919 #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
920 #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
921 #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
922 #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
923 #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
924 #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
925 #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
926 #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
927 #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
928 #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
929 #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
930 #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
931 #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
932 #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
933 #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
934 #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
935 #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
936 #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
937 #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
938 #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
939 #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
940 #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
941 #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
942 #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
943 #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
944 #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
945 #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
946 #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
947 #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
948 #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
949 #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
950 #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
951 #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
952 #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
953 #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
956 * Portable Data Types
958 * Any instance where a 32-bit long or pointer type is assumed
959 * for precision or HW defined structures, the following define
960 * types must be used. In Linux the char, short, and int types
961 * are all consistent at 8, 16, and 32 bits respectively. Pointers
962 * and long types are 64 bits on Alpha and UltraSPARC.
964 #define ADV_PADDR __u32 /* Physical address data type. */
965 #define ADV_VADDR __u32 /* Virtual address data type. */
966 #define ADV_DCNT __u32 /* Unsigned Data count type. */
967 #define ADV_SDCNT __s32 /* Signed Data count type. */
970 * These macros are used to convert a virtual address to a
971 * 32-bit value. This currently can be used on Linux Alpha
972 * which uses 64-bit virtual address but a 32-bit bus address.
973 * This is likely to break in the future, but doing this now
974 * will give us time to change the HW and FW to handle 64-bit
975 * addresses.
977 #define ADV_VADDR_TO_U32 virt_to_bus
978 #define ADV_U32_TO_VADDR bus_to_virt
980 #define AdvPortAddr void __iomem * /* Virtual memory address size */
983 * Define Adv Library required memory access macros.
985 #define ADV_MEM_READB(addr) readb(addr)
986 #define ADV_MEM_READW(addr) readw(addr)
987 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
988 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
989 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
991 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
994 * Define total number of simultaneous maximum element scatter-gather
995 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
996 * maximum number of outstanding commands per wide host adapter. Each
997 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
998 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
999 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
1000 * structures or 255 scatter-gather elements.
1003 #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
1006 * Define Adv Library required maximum number of scatter-gather
1007 * elements per request.
1009 #define ADV_MAX_SG_LIST 255
1011 /* Number of SG blocks needed. */
1012 #define ADV_NUM_SG_BLOCK \
1013 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1015 /* Total contiguous memory needed for SG blocks. */
1016 #define ADV_SG_TOTAL_MEM_SIZE \
1017 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
1019 #define ADV_PAGE_SIZE PAGE_SIZE
1021 #define ADV_NUM_PAGE_CROSSING \
1022 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1024 #define ADV_EEP_DVC_CFG_BEGIN (0x00)
1025 #define ADV_EEP_DVC_CFG_END (0x15)
1026 #define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1027 #define ADV_EEP_MAX_WORD_ADDR (0x1E)
1029 #define ADV_EEP_DELAY_MS 100
1031 #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
1032 #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1034 * For the ASC3550 Bit 13 is Termination Polarity control bit.
1035 * For later ICs Bit 13 controls whether the CIS (Card Information
1036 * Service Section) is loaded from EEPROM.
1038 #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
1039 #define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1041 * ASC38C1600 Bit 11
1043 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1044 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1045 * Function 0 will specify INT B.
1047 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1048 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1049 * Function 1 will specify INT A.
1051 #define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
1053 typedef struct adveep_3550_config {
1054 /* Word Offset, Description */
1056 ushort cfg_lsw; /* 00 power up initialization */
1057 /* bit 13 set - Term Polarity Control */
1058 /* bit 14 set - BIOS Enable */
1059 /* bit 15 set - Big Endian Mode */
1060 ushort cfg_msw; /* 01 unused */
1061 ushort disc_enable; /* 02 disconnect enable */
1062 ushort wdtr_able; /* 03 Wide DTR able */
1063 ushort sdtr_able; /* 04 Synchronous DTR able */
1064 ushort start_motor; /* 05 send start up motor */
1065 ushort tagqng_able; /* 06 tag queuing able */
1066 ushort bios_scan; /* 07 BIOS device control */
1067 ushort scam_tolerant; /* 08 no scam */
1069 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1070 uchar bios_boot_delay; /* power up wait */
1072 uchar scsi_reset_delay; /* 10 reset delay */
1073 uchar bios_id_lun; /* first boot device scsi id & lun */
1074 /* high nibble is lun */
1075 /* low nibble is scsi id */
1077 uchar termination; /* 11 0 - automatic */
1078 /* 1 - low off / high off */
1079 /* 2 - low off / high on */
1080 /* 3 - low on / high on */
1081 /* There is no low on / high off */
1083 uchar reserved1; /* reserved byte (not used) */
1085 ushort bios_ctrl; /* 12 BIOS control bits */
1086 /* bit 0 BIOS don't act as initiator. */
1087 /* bit 1 BIOS > 1 GB support */
1088 /* bit 2 BIOS > 2 Disk Support */
1089 /* bit 3 BIOS don't support removables */
1090 /* bit 4 BIOS support bootable CD */
1091 /* bit 5 BIOS scan enabled */
1092 /* bit 6 BIOS support multiple LUNs */
1093 /* bit 7 BIOS display of message */
1094 /* bit 8 SCAM disabled */
1095 /* bit 9 Reset SCSI bus during init. */
1096 /* bit 10 */
1097 /* bit 11 No verbose initialization. */
1098 /* bit 12 SCSI parity enabled */
1099 /* bit 13 */
1100 /* bit 14 */
1101 /* bit 15 */
1102 ushort ultra_able; /* 13 ULTRA speed able */
1103 ushort reserved2; /* 14 reserved */
1104 uchar max_host_qng; /* 15 maximum host queuing */
1105 uchar max_dvc_qng; /* maximum per device queuing */
1106 ushort dvc_cntl; /* 16 control bit for driver */
1107 ushort bug_fix; /* 17 control bit for bug fix */
1108 ushort serial_number_word1; /* 18 Board serial number word 1 */
1109 ushort serial_number_word2; /* 19 Board serial number word 2 */
1110 ushort serial_number_word3; /* 20 Board serial number word 3 */
1111 ushort check_sum; /* 21 EEP check sum */
1112 uchar oem_name[16]; /* 22 OEM name */
1113 ushort dvc_err_code; /* 30 last device driver error code */
1114 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1115 ushort adv_err_addr; /* 32 last uc error address */
1116 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1117 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1118 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1119 ushort num_of_err; /* 36 number of error */
1120 } ADVEEP_3550_CONFIG;
1122 typedef struct adveep_38C0800_config {
1123 /* Word Offset, Description */
1125 ushort cfg_lsw; /* 00 power up initialization */
1126 /* bit 13 set - Load CIS */
1127 /* bit 14 set - BIOS Enable */
1128 /* bit 15 set - Big Endian Mode */
1129 ushort cfg_msw; /* 01 unused */
1130 ushort disc_enable; /* 02 disconnect enable */
1131 ushort wdtr_able; /* 03 Wide DTR able */
1132 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1133 ushort start_motor; /* 05 send start up motor */
1134 ushort tagqng_able; /* 06 tag queuing able */
1135 ushort bios_scan; /* 07 BIOS device control */
1136 ushort scam_tolerant; /* 08 no scam */
1138 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1139 uchar bios_boot_delay; /* power up wait */
1141 uchar scsi_reset_delay; /* 10 reset delay */
1142 uchar bios_id_lun; /* first boot device scsi id & lun */
1143 /* high nibble is lun */
1144 /* low nibble is scsi id */
1146 uchar termination_se; /* 11 0 - automatic */
1147 /* 1 - low off / high off */
1148 /* 2 - low off / high on */
1149 /* 3 - low on / high on */
1150 /* There is no low on / high off */
1152 uchar termination_lvd; /* 11 0 - automatic */
1153 /* 1 - low off / high off */
1154 /* 2 - low off / high on */
1155 /* 3 - low on / high on */
1156 /* There is no low on / high off */
1158 ushort bios_ctrl; /* 12 BIOS control bits */
1159 /* bit 0 BIOS don't act as initiator. */
1160 /* bit 1 BIOS > 1 GB support */
1161 /* bit 2 BIOS > 2 Disk Support */
1162 /* bit 3 BIOS don't support removables */
1163 /* bit 4 BIOS support bootable CD */
1164 /* bit 5 BIOS scan enabled */
1165 /* bit 6 BIOS support multiple LUNs */
1166 /* bit 7 BIOS display of message */
1167 /* bit 8 SCAM disabled */
1168 /* bit 9 Reset SCSI bus during init. */
1169 /* bit 10 */
1170 /* bit 11 No verbose initialization. */
1171 /* bit 12 SCSI parity enabled */
1172 /* bit 13 */
1173 /* bit 14 */
1174 /* bit 15 */
1175 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1176 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1177 uchar max_host_qng; /* 15 maximum host queueing */
1178 uchar max_dvc_qng; /* maximum per device queuing */
1179 ushort dvc_cntl; /* 16 control bit for driver */
1180 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1181 ushort serial_number_word1; /* 18 Board serial number word 1 */
1182 ushort serial_number_word2; /* 19 Board serial number word 2 */
1183 ushort serial_number_word3; /* 20 Board serial number word 3 */
1184 ushort check_sum; /* 21 EEP check sum */
1185 uchar oem_name[16]; /* 22 OEM name */
1186 ushort dvc_err_code; /* 30 last device driver error code */
1187 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1188 ushort adv_err_addr; /* 32 last uc error address */
1189 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1190 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1191 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1192 ushort reserved36; /* 36 reserved */
1193 ushort reserved37; /* 37 reserved */
1194 ushort reserved38; /* 38 reserved */
1195 ushort reserved39; /* 39 reserved */
1196 ushort reserved40; /* 40 reserved */
1197 ushort reserved41; /* 41 reserved */
1198 ushort reserved42; /* 42 reserved */
1199 ushort reserved43; /* 43 reserved */
1200 ushort reserved44; /* 44 reserved */
1201 ushort reserved45; /* 45 reserved */
1202 ushort reserved46; /* 46 reserved */
1203 ushort reserved47; /* 47 reserved */
1204 ushort reserved48; /* 48 reserved */
1205 ushort reserved49; /* 49 reserved */
1206 ushort reserved50; /* 50 reserved */
1207 ushort reserved51; /* 51 reserved */
1208 ushort reserved52; /* 52 reserved */
1209 ushort reserved53; /* 53 reserved */
1210 ushort reserved54; /* 54 reserved */
1211 ushort reserved55; /* 55 reserved */
1212 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1213 ushort cisprt_msw; /* 57 CIS PTR MSW */
1214 ushort subsysvid; /* 58 SubSystem Vendor ID */
1215 ushort subsysid; /* 59 SubSystem ID */
1216 ushort reserved60; /* 60 reserved */
1217 ushort reserved61; /* 61 reserved */
1218 ushort reserved62; /* 62 reserved */
1219 ushort reserved63; /* 63 reserved */
1220 } ADVEEP_38C0800_CONFIG;
1222 typedef struct adveep_38C1600_config {
1223 /* Word Offset, Description */
1225 ushort cfg_lsw; /* 00 power up initialization */
1226 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
1227 /* clear - Func. 0 INTA, Func. 1 INTB */
1228 /* bit 13 set - Load CIS */
1229 /* bit 14 set - BIOS Enable */
1230 /* bit 15 set - Big Endian Mode */
1231 ushort cfg_msw; /* 01 unused */
1232 ushort disc_enable; /* 02 disconnect enable */
1233 ushort wdtr_able; /* 03 Wide DTR able */
1234 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1235 ushort start_motor; /* 05 send start up motor */
1236 ushort tagqng_able; /* 06 tag queuing able */
1237 ushort bios_scan; /* 07 BIOS device control */
1238 ushort scam_tolerant; /* 08 no scam */
1240 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1241 uchar bios_boot_delay; /* power up wait */
1243 uchar scsi_reset_delay; /* 10 reset delay */
1244 uchar bios_id_lun; /* first boot device scsi id & lun */
1245 /* high nibble is lun */
1246 /* low nibble is scsi id */
1248 uchar termination_se; /* 11 0 - automatic */
1249 /* 1 - low off / high off */
1250 /* 2 - low off / high on */
1251 /* 3 - low on / high on */
1252 /* There is no low on / high off */
1254 uchar termination_lvd; /* 11 0 - automatic */
1255 /* 1 - low off / high off */
1256 /* 2 - low off / high on */
1257 /* 3 - low on / high on */
1258 /* There is no low on / high off */
1260 ushort bios_ctrl; /* 12 BIOS control bits */
1261 /* bit 0 BIOS don't act as initiator. */
1262 /* bit 1 BIOS > 1 GB support */
1263 /* bit 2 BIOS > 2 Disk Support */
1264 /* bit 3 BIOS don't support removables */
1265 /* bit 4 BIOS support bootable CD */
1266 /* bit 5 BIOS scan enabled */
1267 /* bit 6 BIOS support multiple LUNs */
1268 /* bit 7 BIOS display of message */
1269 /* bit 8 SCAM disabled */
1270 /* bit 9 Reset SCSI bus during init. */
1271 /* bit 10 Basic Integrity Checking disabled */
1272 /* bit 11 No verbose initialization. */
1273 /* bit 12 SCSI parity enabled */
1274 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
1275 /* bit 14 */
1276 /* bit 15 */
1277 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1278 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1279 uchar max_host_qng; /* 15 maximum host queueing */
1280 uchar max_dvc_qng; /* maximum per device queuing */
1281 ushort dvc_cntl; /* 16 control bit for driver */
1282 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1283 ushort serial_number_word1; /* 18 Board serial number word 1 */
1284 ushort serial_number_word2; /* 19 Board serial number word 2 */
1285 ushort serial_number_word3; /* 20 Board serial number word 3 */
1286 ushort check_sum; /* 21 EEP check sum */
1287 uchar oem_name[16]; /* 22 OEM name */
1288 ushort dvc_err_code; /* 30 last device driver error code */
1289 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1290 ushort adv_err_addr; /* 32 last uc error address */
1291 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1292 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1293 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1294 ushort reserved36; /* 36 reserved */
1295 ushort reserved37; /* 37 reserved */
1296 ushort reserved38; /* 38 reserved */
1297 ushort reserved39; /* 39 reserved */
1298 ushort reserved40; /* 40 reserved */
1299 ushort reserved41; /* 41 reserved */
1300 ushort reserved42; /* 42 reserved */
1301 ushort reserved43; /* 43 reserved */
1302 ushort reserved44; /* 44 reserved */
1303 ushort reserved45; /* 45 reserved */
1304 ushort reserved46; /* 46 reserved */
1305 ushort reserved47; /* 47 reserved */
1306 ushort reserved48; /* 48 reserved */
1307 ushort reserved49; /* 49 reserved */
1308 ushort reserved50; /* 50 reserved */
1309 ushort reserved51; /* 51 reserved */
1310 ushort reserved52; /* 52 reserved */
1311 ushort reserved53; /* 53 reserved */
1312 ushort reserved54; /* 54 reserved */
1313 ushort reserved55; /* 55 reserved */
1314 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1315 ushort cisprt_msw; /* 57 CIS PTR MSW */
1316 ushort subsysvid; /* 58 SubSystem Vendor ID */
1317 ushort subsysid; /* 59 SubSystem ID */
1318 ushort reserved60; /* 60 reserved */
1319 ushort reserved61; /* 61 reserved */
1320 ushort reserved62; /* 62 reserved */
1321 ushort reserved63; /* 63 reserved */
1322 } ADVEEP_38C1600_CONFIG;
1325 * EEPROM Commands
1327 #define ASC_EEP_CMD_DONE 0x0200
1329 /* bios_ctrl */
1330 #define BIOS_CTRL_BIOS 0x0001
1331 #define BIOS_CTRL_EXTENDED_XLAT 0x0002
1332 #define BIOS_CTRL_GT_2_DISK 0x0004
1333 #define BIOS_CTRL_BIOS_REMOVABLE 0x0008
1334 #define BIOS_CTRL_BOOTABLE_CD 0x0010
1335 #define BIOS_CTRL_MULTIPLE_LUN 0x0040
1336 #define BIOS_CTRL_DISPLAY_MSG 0x0080
1337 #define BIOS_CTRL_NO_SCAM 0x0100
1338 #define BIOS_CTRL_RESET_SCSI_BUS 0x0200
1339 #define BIOS_CTRL_INIT_VERBOSE 0x0800
1340 #define BIOS_CTRL_SCSI_PARITY 0x1000
1341 #define BIOS_CTRL_AIPP_DIS 0x2000
1343 #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
1345 #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1348 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
1349 * a special 16K Adv Library and Microcode version. After the issue is
1350 * resolved, should restore 32K support.
1352 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
1354 #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1357 * Byte I/O register address from base of 'iop_base'.
1359 #define IOPB_INTR_STATUS_REG 0x00
1360 #define IOPB_CHIP_ID_1 0x01
1361 #define IOPB_INTR_ENABLES 0x02
1362 #define IOPB_CHIP_TYPE_REV 0x03
1363 #define IOPB_RES_ADDR_4 0x04
1364 #define IOPB_RES_ADDR_5 0x05
1365 #define IOPB_RAM_DATA 0x06
1366 #define IOPB_RES_ADDR_7 0x07
1367 #define IOPB_FLAG_REG 0x08
1368 #define IOPB_RES_ADDR_9 0x09
1369 #define IOPB_RISC_CSR 0x0A
1370 #define IOPB_RES_ADDR_B 0x0B
1371 #define IOPB_RES_ADDR_C 0x0C
1372 #define IOPB_RES_ADDR_D 0x0D
1373 #define IOPB_SOFT_OVER_WR 0x0E
1374 #define IOPB_RES_ADDR_F 0x0F
1375 #define IOPB_MEM_CFG 0x10
1376 #define IOPB_RES_ADDR_11 0x11
1377 #define IOPB_GPIO_DATA 0x12
1378 #define IOPB_RES_ADDR_13 0x13
1379 #define IOPB_FLASH_PAGE 0x14
1380 #define IOPB_RES_ADDR_15 0x15
1381 #define IOPB_GPIO_CNTL 0x16
1382 #define IOPB_RES_ADDR_17 0x17
1383 #define IOPB_FLASH_DATA 0x18
1384 #define IOPB_RES_ADDR_19 0x19
1385 #define IOPB_RES_ADDR_1A 0x1A
1386 #define IOPB_RES_ADDR_1B 0x1B
1387 #define IOPB_RES_ADDR_1C 0x1C
1388 #define IOPB_RES_ADDR_1D 0x1D
1389 #define IOPB_RES_ADDR_1E 0x1E
1390 #define IOPB_RES_ADDR_1F 0x1F
1391 #define IOPB_DMA_CFG0 0x20
1392 #define IOPB_DMA_CFG1 0x21
1393 #define IOPB_TICKLE 0x22
1394 #define IOPB_DMA_REG_WR 0x23
1395 #define IOPB_SDMA_STATUS 0x24
1396 #define IOPB_SCSI_BYTE_CNT 0x25
1397 #define IOPB_HOST_BYTE_CNT 0x26
1398 #define IOPB_BYTE_LEFT_TO_XFER 0x27
1399 #define IOPB_BYTE_TO_XFER_0 0x28
1400 #define IOPB_BYTE_TO_XFER_1 0x29
1401 #define IOPB_BYTE_TO_XFER_2 0x2A
1402 #define IOPB_BYTE_TO_XFER_3 0x2B
1403 #define IOPB_ACC_GRP 0x2C
1404 #define IOPB_RES_ADDR_2D 0x2D
1405 #define IOPB_DEV_ID 0x2E
1406 #define IOPB_RES_ADDR_2F 0x2F
1407 #define IOPB_SCSI_DATA 0x30
1408 #define IOPB_RES_ADDR_31 0x31
1409 #define IOPB_RES_ADDR_32 0x32
1410 #define IOPB_SCSI_DATA_HSHK 0x33
1411 #define IOPB_SCSI_CTRL 0x34
1412 #define IOPB_RES_ADDR_35 0x35
1413 #define IOPB_RES_ADDR_36 0x36
1414 #define IOPB_RES_ADDR_37 0x37
1415 #define IOPB_RAM_BIST 0x38
1416 #define IOPB_PLL_TEST 0x39
1417 #define IOPB_PCI_INT_CFG 0x3A
1418 #define IOPB_RES_ADDR_3B 0x3B
1419 #define IOPB_RFIFO_CNT 0x3C
1420 #define IOPB_RES_ADDR_3D 0x3D
1421 #define IOPB_RES_ADDR_3E 0x3E
1422 #define IOPB_RES_ADDR_3F 0x3F
1425 * Word I/O register address from base of 'iop_base'.
1427 #define IOPW_CHIP_ID_0 0x00 /* CID0 */
1428 #define IOPW_CTRL_REG 0x02 /* CC */
1429 #define IOPW_RAM_ADDR 0x04 /* LA */
1430 #define IOPW_RAM_DATA 0x06 /* LD */
1431 #define IOPW_RES_ADDR_08 0x08
1432 #define IOPW_RISC_CSR 0x0A /* CSR */
1433 #define IOPW_SCSI_CFG0 0x0C /* CFG0 */
1434 #define IOPW_SCSI_CFG1 0x0E /* CFG1 */
1435 #define IOPW_RES_ADDR_10 0x10
1436 #define IOPW_SEL_MASK 0x12 /* SM */
1437 #define IOPW_RES_ADDR_14 0x14
1438 #define IOPW_FLASH_ADDR 0x16 /* FA */
1439 #define IOPW_RES_ADDR_18 0x18
1440 #define IOPW_EE_CMD 0x1A /* EC */
1441 #define IOPW_EE_DATA 0x1C /* ED */
1442 #define IOPW_SFIFO_CNT 0x1E /* SFC */
1443 #define IOPW_RES_ADDR_20 0x20
1444 #define IOPW_Q_BASE 0x22 /* QB */
1445 #define IOPW_QP 0x24 /* QP */
1446 #define IOPW_IX 0x26 /* IX */
1447 #define IOPW_SP 0x28 /* SP */
1448 #define IOPW_PC 0x2A /* PC */
1449 #define IOPW_RES_ADDR_2C 0x2C
1450 #define IOPW_RES_ADDR_2E 0x2E
1451 #define IOPW_SCSI_DATA 0x30 /* SD */
1452 #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
1453 #define IOPW_SCSI_CTRL 0x34 /* SC */
1454 #define IOPW_HSHK_CFG 0x36 /* HCFG */
1455 #define IOPW_SXFR_STATUS 0x36 /* SXS */
1456 #define IOPW_SXFR_CNTL 0x38 /* SXL */
1457 #define IOPW_SXFR_CNTH 0x3A /* SXH */
1458 #define IOPW_RES_ADDR_3C 0x3C
1459 #define IOPW_RFIFO_DATA 0x3E /* RFD */
1462 * Doubleword I/O register address from base of 'iop_base'.
1464 #define IOPDW_RES_ADDR_0 0x00
1465 #define IOPDW_RAM_DATA 0x04
1466 #define IOPDW_RES_ADDR_8 0x08
1467 #define IOPDW_RES_ADDR_C 0x0C
1468 #define IOPDW_RES_ADDR_10 0x10
1469 #define IOPDW_COMMA 0x14
1470 #define IOPDW_COMMB 0x18
1471 #define IOPDW_RES_ADDR_1C 0x1C
1472 #define IOPDW_SDMA_ADDR0 0x20
1473 #define IOPDW_SDMA_ADDR1 0x24
1474 #define IOPDW_SDMA_COUNT 0x28
1475 #define IOPDW_SDMA_ERROR 0x2C
1476 #define IOPDW_RDMA_ADDR0 0x30
1477 #define IOPDW_RDMA_ADDR1 0x34
1478 #define IOPDW_RDMA_COUNT 0x38
1479 #define IOPDW_RDMA_ERROR 0x3C
1481 #define ADV_CHIP_ID_BYTE 0x25
1482 #define ADV_CHIP_ID_WORD 0x04C1
1484 #define ADV_INTR_ENABLE_HOST_INTR 0x01
1485 #define ADV_INTR_ENABLE_SEL_INTR 0x02
1486 #define ADV_INTR_ENABLE_DPR_INTR 0x04
1487 #define ADV_INTR_ENABLE_RTA_INTR 0x08
1488 #define ADV_INTR_ENABLE_RMA_INTR 0x10
1489 #define ADV_INTR_ENABLE_RST_INTR 0x20
1490 #define ADV_INTR_ENABLE_DPE_INTR 0x40
1491 #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
1493 #define ADV_INTR_STATUS_INTRA 0x01
1494 #define ADV_INTR_STATUS_INTRB 0x02
1495 #define ADV_INTR_STATUS_INTRC 0x04
1497 #define ADV_RISC_CSR_STOP (0x0000)
1498 #define ADV_RISC_TEST_COND (0x2000)
1499 #define ADV_RISC_CSR_RUN (0x4000)
1500 #define ADV_RISC_CSR_SINGLE_STEP (0x8000)
1502 #define ADV_CTRL_REG_HOST_INTR 0x0100
1503 #define ADV_CTRL_REG_SEL_INTR 0x0200
1504 #define ADV_CTRL_REG_DPR_INTR 0x0400
1505 #define ADV_CTRL_REG_RTA_INTR 0x0800
1506 #define ADV_CTRL_REG_RMA_INTR 0x1000
1507 #define ADV_CTRL_REG_RES_BIT14 0x2000
1508 #define ADV_CTRL_REG_DPE_INTR 0x4000
1509 #define ADV_CTRL_REG_POWER_DONE 0x8000
1510 #define ADV_CTRL_REG_ANY_INTR 0xFF00
1512 #define ADV_CTRL_REG_CMD_RESET 0x00C6
1513 #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
1514 #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
1515 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
1516 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
1518 #define ADV_TICKLE_NOP 0x00
1519 #define ADV_TICKLE_A 0x01
1520 #define ADV_TICKLE_B 0x02
1521 #define ADV_TICKLE_C 0x03
1523 #define AdvIsIntPending(port) \
1524 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
1527 * SCSI_CFG0 Register bit definitions
1529 #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
1530 #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
1531 #define EVEN_PARITY 0x1000 /* Select Even Parity */
1532 #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
1533 #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
1534 #define PRIM_MODE 0x0100 /* Primitive SCSI mode */
1535 #define SCAM_EN 0x0080 /* Enable SCAM selection */
1536 #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
1537 #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
1538 #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
1539 #define OUR_ID 0x000F /* SCSI ID */
1542 * SCSI_CFG1 Register bit definitions
1544 #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
1545 #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
1546 #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
1547 #define FILTER_SEL 0x0C00 /* Filter Period Selection */
1548 #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
1549 #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
1550 #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
1551 #define ACTIVE_DBL 0x0200 /* Disable Active Negation */
1552 #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
1553 #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
1554 #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
1555 #define TERM_CTL 0x0030 /* External SCSI Termination Bits */
1556 #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
1557 #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
1558 #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
1561 * Addendum for ASC-38C0800 Chip
1563 * The ASC-38C1600 Chip uses the same definitions except that the
1564 * bus mode override bits [12:10] have been moved to byte register
1565 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
1566 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
1567 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
1568 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
1569 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
1571 #define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
1572 #define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
1573 #define HVD 0x1000 /* HVD Device Detect */
1574 #define LVD 0x0800 /* LVD Device Detect */
1575 #define SE 0x0400 /* SE Device Detect */
1576 #define TERM_LVD 0x00C0 /* LVD Termination Bits */
1577 #define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
1578 #define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
1579 #define TERM_SE 0x0030 /* SE Termination Bits */
1580 #define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
1581 #define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
1582 #define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
1583 #define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
1584 #define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
1585 #define C_DET_SE 0x0003 /* SE Cable Detect Bits */
1586 #define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
1587 #define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
1589 #define CABLE_ILLEGAL_A 0x7
1590 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
1592 #define CABLE_ILLEGAL_B 0xB
1593 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
1596 * MEM_CFG Register bit definitions
1598 #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
1599 #define FAST_EE_CLK 0x20 /* Diagnostic Bit */
1600 #define RAM_SZ 0x1C /* Specify size of RAM to RISC */
1601 #define RAM_SZ_2KB 0x00 /* 2 KB */
1602 #define RAM_SZ_4KB 0x04 /* 4 KB */
1603 #define RAM_SZ_8KB 0x08 /* 8 KB */
1604 #define RAM_SZ_16KB 0x0C /* 16 KB */
1605 #define RAM_SZ_32KB 0x10 /* 32 KB */
1606 #define RAM_SZ_64KB 0x14 /* 64 KB */
1609 * DMA_CFG0 Register bit definitions
1611 * This register is only accessible to the host.
1613 #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
1614 #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
1615 #define FIFO_THRESH_16B 0x00 /* 16 bytes */
1616 #define FIFO_THRESH_32B 0x20 /* 32 bytes */
1617 #define FIFO_THRESH_48B 0x30 /* 48 bytes */
1618 #define FIFO_THRESH_64B 0x40 /* 64 bytes */
1619 #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
1620 #define FIFO_THRESH_96B 0x60 /* 96 bytes */
1621 #define FIFO_THRESH_112B 0x70 /* 112 bytes */
1622 #define START_CTL 0x0C /* DMA start conditions */
1623 #define START_CTL_TH 0x00 /* Wait threshold level (default) */
1624 #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
1625 #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
1626 #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
1627 #define READ_CMD 0x03 /* Memory Read Method */
1628 #define READ_CMD_MR 0x00 /* Memory Read */
1629 #define READ_CMD_MRL 0x02 /* Memory Read Long */
1630 #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
1633 * ASC-38C0800 RAM BIST Register bit definitions
1635 #define RAM_TEST_MODE 0x80
1636 #define PRE_TEST_MODE 0x40
1637 #define NORMAL_MODE 0x00
1638 #define RAM_TEST_DONE 0x10
1639 #define RAM_TEST_STATUS 0x0F
1640 #define RAM_TEST_HOST_ERROR 0x08
1641 #define RAM_TEST_INTRAM_ERROR 0x04
1642 #define RAM_TEST_RISC_ERROR 0x02
1643 #define RAM_TEST_SCSI_ERROR 0x01
1644 #define RAM_TEST_SUCCESS 0x00
1645 #define PRE_TEST_VALUE 0x05
1646 #define NORMAL_VALUE 0x00
1649 * ASC38C1600 Definitions
1651 * IOPB_PCI_INT_CFG Bit Field Definitions
1654 #define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
1657 * Bit 1 can be set to change the interrupt for the Function to operate in
1658 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
1659 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
1660 * mode, otherwise the operating mode is undefined.
1662 #define TOTEMPOLE 0x02
1665 * Bit 0 can be used to change the Int Pin for the Function. The value is
1666 * 0 by default for both Functions with Function 0 using INT A and Function
1667 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
1668 * INT A is used.
1670 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
1671 * value specified in the PCI Configuration Space.
1673 #define INTAB 0x01
1676 * Adv Library Status Definitions
1678 #define ADV_TRUE 1
1679 #define ADV_FALSE 0
1680 #define ADV_SUCCESS 1
1681 #define ADV_BUSY 0
1682 #define ADV_ERROR (-1)
1685 * ADV_DVC_VAR 'warn_code' values
1687 #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
1688 #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
1689 #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
1690 #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
1692 #define ADV_MAX_TID 15 /* max. target identifier */
1693 #define ADV_MAX_LUN 7 /* max. logical unit number */
1696 * Fixed locations of microcode operating variables.
1698 #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
1699 #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
1700 #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
1701 #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
1702 #define ASC_MC_VERSION_NUM 0x003A /* microcode number */
1703 #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
1704 #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
1705 #define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
1706 #define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
1707 #define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
1708 #define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
1709 #define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
1710 #define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
1711 #define ASC_MC_CHIP_TYPE 0x009A
1712 #define ASC_MC_INTRB_CODE 0x009B
1713 #define ASC_MC_WDTR_ABLE 0x009C
1714 #define ASC_MC_SDTR_ABLE 0x009E
1715 #define ASC_MC_TAGQNG_ABLE 0x00A0
1716 #define ASC_MC_DISC_ENABLE 0x00A2
1717 #define ASC_MC_IDLE_CMD_STATUS 0x00A4
1718 #define ASC_MC_IDLE_CMD 0x00A6
1719 #define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
1720 #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
1721 #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
1722 #define ASC_MC_DEFAULT_MEM_CFG 0x00B0
1723 #define ASC_MC_DEFAULT_SEL_MASK 0x00B2
1724 #define ASC_MC_SDTR_DONE 0x00B6
1725 #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
1726 #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
1727 #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
1728 #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
1729 #define ASC_MC_WDTR_DONE 0x0124
1730 #define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
1731 #define ASC_MC_ICQ 0x0160
1732 #define ASC_MC_IRQ 0x0164
1733 #define ASC_MC_PPR_ABLE 0x017A
1736 * BIOS LRAM variable absolute offsets.
1738 #define BIOS_CODESEG 0x54
1739 #define BIOS_CODELEN 0x56
1740 #define BIOS_SIGNATURE 0x58
1741 #define BIOS_VERSION 0x5A
1744 * Microcode Control Flags
1746 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
1747 * and handled by the microcode.
1749 #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
1750 #define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
1753 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
1755 #define HSHK_CFG_WIDE_XFR 0x8000
1756 #define HSHK_CFG_RATE 0x0F00
1757 #define HSHK_CFG_OFFSET 0x001F
1759 #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
1760 #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
1761 #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
1762 #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
1764 #define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
1765 #define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
1766 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
1767 #define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
1768 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
1770 #define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
1771 #define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
1772 #define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
1773 #define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
1774 #define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
1776 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
1777 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
1779 #define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
1780 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
1783 * All fields here are accessed by the board microcode and need to be
1784 * little-endian.
1786 typedef struct adv_carr_t {
1787 ADV_VADDR carr_va; /* Carrier Virtual Address */
1788 ADV_PADDR carr_pa; /* Carrier Physical Address */
1789 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
1791 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
1793 * next_vpa [3:1] Reserved Bits
1794 * next_vpa [0] Done Flag set in Response Queue.
1796 ADV_VADDR next_vpa;
1797 } ADV_CARR_T;
1800 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
1802 #define ASC_NEXT_VPA_MASK 0xFFFFFFF0
1804 #define ASC_RQ_DONE 0x00000001
1805 #define ASC_RQ_GOOD 0x00000002
1806 #define ASC_CQ_STOPPER 0x00000000
1808 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
1810 #define ADV_CARRIER_NUM_PAGE_CROSSING \
1811 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
1812 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1814 #define ADV_CARRIER_BUFSIZE \
1815 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
1818 * ASC_SCSI_REQ_Q 'a_flag' definitions
1820 * The Adv Library should limit use to the lower nibble (4 bits) of
1821 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
1823 #define ADV_POLL_REQUEST 0x01 /* poll for request completion */
1824 #define ADV_SCSIQ_DONE 0x02 /* request done */
1825 #define ADV_DONT_RETRY 0x08 /* don't do retry */
1827 #define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
1828 #define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
1829 #define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
1832 * Adapter temporary configuration structure
1834 * This structure can be discarded after initialization. Don't add
1835 * fields here needed after initialization.
1837 * Field naming convention:
1839 * *_enable indicates the field enables or disables a feature. The
1840 * value of the field is never reset.
1842 typedef struct adv_dvc_cfg {
1843 ushort disc_enable; /* enable disconnection */
1844 uchar chip_version; /* chip version */
1845 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
1846 ushort control_flag; /* Microcode Control Flag */
1847 ushort mcode_date; /* Microcode date */
1848 ushort mcode_version; /* Microcode version */
1849 ushort serial1; /* EEPROM serial number word 1 */
1850 ushort serial2; /* EEPROM serial number word 2 */
1851 ushort serial3; /* EEPROM serial number word 3 */
1852 } ADV_DVC_CFG;
1854 struct adv_dvc_var;
1855 struct adv_scsi_req_q;
1858 * Adapter operation variable structure.
1860 * One structure is required per host adapter.
1862 * Field naming convention:
1864 * *_able indicates both whether a feature should be enabled or disabled
1865 * and whether a device isi capable of the feature. At initialization
1866 * this field may be set, but later if a device is found to be incapable
1867 * of the feature, the field is cleared.
1869 typedef struct adv_dvc_var {
1870 AdvPortAddr iop_base; /* I/O port address */
1871 ushort err_code; /* fatal error code */
1872 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
1873 ushort wdtr_able; /* try WDTR for a device */
1874 ushort sdtr_able; /* try SDTR for a device */
1875 ushort ultra_able; /* try SDTR Ultra speed for a device */
1876 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
1877 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
1878 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
1879 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
1880 ushort tagqng_able; /* try tagged queuing with a device */
1881 ushort ppr_able; /* PPR message capable per TID bitmask. */
1882 uchar max_dvc_qng; /* maximum number of tagged commands per device */
1883 ushort start_motor; /* start motor command allowed */
1884 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
1885 uchar chip_no; /* should be assigned by caller */
1886 uchar max_host_qng; /* maximum number of Q'ed command allowed */
1887 ushort no_scam; /* scam_tolerant of EEPROM */
1888 struct asc_board *drv_ptr; /* driver pointer to private structure */
1889 uchar chip_scsi_id; /* chip SCSI target ID */
1890 uchar chip_type;
1891 uchar bist_err_code;
1892 ADV_CARR_T *carrier_buf;
1893 ADV_CARR_T *carr_freelist; /* Carrier free list. */
1894 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
1895 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
1896 ushort carr_pending_cnt; /* Count of pending carriers. */
1898 * Note: The following fields will not be used after initialization. The
1899 * driver may discard the buffer after initialization is done.
1901 ADV_DVC_CFG *cfg; /* temporary configuration structure */
1902 } ADV_DVC_VAR;
1904 #define NO_OF_SG_PER_BLOCK 15
1906 typedef struct asc_sg_block {
1907 uchar reserved1;
1908 uchar reserved2;
1909 uchar reserved3;
1910 uchar sg_cnt; /* Valid entries in block. */
1911 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
1912 struct {
1913 ADV_PADDR sg_addr; /* SG element address. */
1914 ADV_DCNT sg_count; /* SG element count. */
1915 } sg_list[NO_OF_SG_PER_BLOCK];
1916 } ADV_SG_BLOCK;
1919 * ADV_SCSI_REQ_Q - microcode request structure
1921 * All fields in this structure up to byte 60 are used by the microcode.
1922 * The microcode makes assumptions about the size and ordering of fields
1923 * in this structure. Do not change the structure definition here without
1924 * coordinating the change with the microcode.
1926 * All fields accessed by microcode must be maintained in little_endian
1927 * order.
1929 typedef struct adv_scsi_req_q {
1930 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
1931 uchar target_cmd;
1932 uchar target_id; /* Device target identifier. */
1933 uchar target_lun; /* Device target logical unit number. */
1934 ADV_PADDR data_addr; /* Data buffer physical address. */
1935 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
1936 ADV_PADDR sense_addr;
1937 ADV_PADDR carr_pa;
1938 uchar mflag;
1939 uchar sense_len;
1940 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
1941 uchar scsi_cntl;
1942 uchar done_status; /* Completion status. */
1943 uchar scsi_status; /* SCSI status byte. */
1944 uchar host_status; /* Ucode host status. */
1945 uchar sg_working_ix;
1946 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
1947 ADV_PADDR sg_real_addr; /* SG list physical address. */
1948 ADV_PADDR scsiq_rptr;
1949 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
1950 ADV_VADDR scsiq_ptr;
1951 ADV_VADDR carr_va;
1953 * End of microcode structure - 60 bytes. The rest of the structure
1954 * is used by the Adv Library and ignored by the microcode.
1956 ADV_VADDR srb_ptr;
1957 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
1958 char *vdata_addr; /* Data buffer virtual address. */
1959 uchar a_flag;
1960 uchar pad[2]; /* Pad out to a word boundary. */
1961 } ADV_SCSI_REQ_Q;
1964 * Microcode idle loop commands
1966 #define IDLE_CMD_COMPLETED 0
1967 #define IDLE_CMD_STOP_CHIP 0x0001
1968 #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
1969 #define IDLE_CMD_SEND_INT 0x0004
1970 #define IDLE_CMD_ABORT 0x0008
1971 #define IDLE_CMD_DEVICE_RESET 0x0010
1972 #define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
1973 #define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
1974 #define IDLE_CMD_SCSIREQ 0x0080
1976 #define IDLE_CMD_STATUS_SUCCESS 0x0001
1977 #define IDLE_CMD_STATUS_FAILURE 0x0002
1980 * AdvSendIdleCmd() flag definitions.
1982 #define ADV_NOWAIT 0x01
1985 * Wait loop time out values.
1987 #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
1988 #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
1989 #define SCSI_MAX_RETRY 10 /* retry count */
1991 #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
1992 #define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
1993 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
1994 #define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
1996 #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
1998 /* Read byte from a register. */
1999 #define AdvReadByteRegister(iop_base, reg_off) \
2000 (ADV_MEM_READB((iop_base) + (reg_off)))
2002 /* Write byte to a register. */
2003 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
2004 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
2006 /* Read word (2 bytes) from a register. */
2007 #define AdvReadWordRegister(iop_base, reg_off) \
2008 (ADV_MEM_READW((iop_base) + (reg_off)))
2010 /* Write word (2 bytes) to a register. */
2011 #define AdvWriteWordRegister(iop_base, reg_off, word) \
2012 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
2014 /* Write dword (4 bytes) to a register. */
2015 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
2016 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
2018 /* Read byte from LRAM. */
2019 #define AdvReadByteLram(iop_base, addr, byte) \
2020 do { \
2021 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2022 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
2023 } while (0)
2025 /* Write byte to LRAM. */
2026 #define AdvWriteByteLram(iop_base, addr, byte) \
2027 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2028 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
2030 /* Read word (2 bytes) from LRAM. */
2031 #define AdvReadWordLram(iop_base, addr, word) \
2032 do { \
2033 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2034 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
2035 } while (0)
2037 /* Write word (2 bytes) to LRAM. */
2038 #define AdvWriteWordLram(iop_base, addr, word) \
2039 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2040 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2042 /* Write little-endian double word (4 bytes) to LRAM */
2043 /* Because of unspecified C language ordering don't use auto-increment. */
2044 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
2045 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2046 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2047 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
2048 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
2049 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2050 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
2052 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
2053 #define AdvReadWordAutoIncLram(iop_base) \
2054 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
2056 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
2057 #define AdvWriteWordAutoIncLram(iop_base, word) \
2058 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2061 * Define macro to check for Condor signature.
2063 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
2064 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
2066 #define AdvFindSignature(iop_base) \
2067 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
2068 ADV_CHIP_ID_BYTE) && \
2069 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
2070 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
2073 * Define macro to Return the version number of the chip at 'iop_base'.
2075 * The second parameter 'bus_type' is currently unused.
2077 #define AdvGetChipVersion(iop_base, bus_type) \
2078 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
2081 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
2082 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
2084 * If the request has not yet been sent to the device it will simply be
2085 * aborted from RISC memory. If the request is disconnected it will be
2086 * aborted on reselection by sending an Abort Message to the target ID.
2088 * Return value:
2089 * ADV_TRUE(1) - Queue was successfully aborted.
2090 * ADV_FALSE(0) - Queue was not found on the active queue list.
2092 #define AdvAbortQueue(asc_dvc, scsiq) \
2093 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
2094 (ADV_DCNT) (scsiq))
2097 * Send a Bus Device Reset Message to the specified target ID.
2099 * All outstanding commands will be purged if sending the
2100 * Bus Device Reset Message is successful.
2102 * Return Value:
2103 * ADV_TRUE(1) - All requests on the target are purged.
2104 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
2105 * are not purged.
2107 #define AdvResetDevice(asc_dvc, target_id) \
2108 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
2109 (ADV_DCNT) (target_id))
2112 * SCSI Wide Type definition.
2114 #define ADV_SCSI_BIT_ID_TYPE ushort
2117 * AdvInitScsiTarget() 'cntl_flag' options.
2119 #define ADV_SCAN_LUN 0x01
2120 #define ADV_CAPINFO_NOLUN 0x02
2123 * Convert target id to target id bit mask.
2125 #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
2128 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
2131 #define QD_NO_STATUS 0x00 /* Request not completed yet. */
2132 #define QD_NO_ERROR 0x01
2133 #define QD_ABORTED_BY_HOST 0x02
2134 #define QD_WITH_ERROR 0x04
2136 #define QHSTA_NO_ERROR 0x00
2137 #define QHSTA_M_SEL_TIMEOUT 0x11
2138 #define QHSTA_M_DATA_OVER_RUN 0x12
2139 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
2140 #define QHSTA_M_QUEUE_ABORTED 0x15
2141 #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
2142 #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
2143 #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
2144 #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
2145 #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
2146 #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
2147 #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
2148 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
2149 #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
2150 #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
2151 #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
2152 #define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
2153 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
2154 #define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
2155 #define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
2156 #define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
2157 #define QHSTA_M_WTM_TIMEOUT 0x41
2158 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
2159 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
2160 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
2161 #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
2162 #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
2163 #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
2166 * DvcGetPhyAddr() flag arguments
2168 #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
2169 #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
2170 #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
2171 #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
2172 #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
2173 #define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
2175 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
2176 #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
2177 #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
2178 #define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
2181 * Total contiguous memory needed for driver SG blocks.
2183 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
2184 * number of scatter-gather elements the driver supports in a
2185 * single request.
2188 #define ADV_SG_LIST_MAX_BYTE_SIZE \
2189 (sizeof(ADV_SG_BLOCK) * \
2190 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
2192 /* struct asc_board flags */
2193 #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
2195 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
2197 #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
2199 #define ASC_INFO_SIZE 128 /* advansys_info() line size */
2201 #ifdef CONFIG_PROC_FS
2202 /* /proc/scsi/advansys/[0...] related definitions */
2203 #define ASC_PRTBUF_SIZE 2048
2204 #define ASC_PRTLINE_SIZE 160
2206 #define ASC_PRT_NEXT() \
2207 if (cp) { \
2208 totlen += len; \
2209 leftlen -= len; \
2210 if (leftlen == 0) { \
2211 return totlen; \
2213 cp += len; \
2215 #endif /* CONFIG_PROC_FS */
2217 /* Asc Library return codes */
2218 #define ASC_TRUE 1
2219 #define ASC_FALSE 0
2220 #define ASC_NOERROR 1
2221 #define ASC_BUSY 0
2222 #define ASC_ERROR (-1)
2224 /* struct scsi_cmnd function return codes */
2225 #define STATUS_BYTE(byte) (byte)
2226 #define MSG_BYTE(byte) ((byte) << 8)
2227 #define HOST_BYTE(byte) ((byte) << 16)
2228 #define DRIVER_BYTE(byte) ((byte) << 24)
2230 #define ASC_STATS(shost, counter) ASC_STATS_ADD(shost, counter, 1)
2231 #ifndef ADVANSYS_STATS
2232 #define ASC_STATS_ADD(shost, counter, count)
2233 #else /* ADVANSYS_STATS */
2234 #define ASC_STATS_ADD(shost, counter, count) \
2235 (((struct asc_board *) shost_priv(shost))->asc_stats.counter += (count))
2236 #endif /* ADVANSYS_STATS */
2238 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
2240 /* If the result wraps when calculating tenths, return 0. */
2241 #define ASC_TENTHS(num, den) \
2242 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
2243 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
2246 * Display a message to the console.
2248 #define ASC_PRINT(s) \
2250 printk("advansys: "); \
2251 printk(s); \
2254 #define ASC_PRINT1(s, a1) \
2256 printk("advansys: "); \
2257 printk((s), (a1)); \
2260 #define ASC_PRINT2(s, a1, a2) \
2262 printk("advansys: "); \
2263 printk((s), (a1), (a2)); \
2266 #define ASC_PRINT3(s, a1, a2, a3) \
2268 printk("advansys: "); \
2269 printk((s), (a1), (a2), (a3)); \
2272 #define ASC_PRINT4(s, a1, a2, a3, a4) \
2274 printk("advansys: "); \
2275 printk((s), (a1), (a2), (a3), (a4)); \
2278 #ifndef ADVANSYS_DEBUG
2280 #define ASC_DBG(lvl, s...)
2281 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2282 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
2283 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2284 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
2285 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2286 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
2287 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
2288 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
2289 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2291 #else /* ADVANSYS_DEBUG */
2294 * Debugging Message Levels:
2295 * 0: Errors Only
2296 * 1: High-Level Tracing
2297 * 2-N: Verbose Tracing
2300 #define ASC_DBG(lvl, format, arg...) { \
2301 if (asc_dbglvl >= (lvl)) \
2302 printk(KERN_DEBUG "%s: %s: " format, DRV_NAME, \
2303 __FUNCTION__ , ## arg); \
2306 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2308 if (asc_dbglvl >= (lvl)) { \
2309 asc_prt_scsi_host(s); \
2313 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
2315 if (asc_dbglvl >= (lvl)) { \
2316 asc_prt_asc_scsi_q(scsiqp); \
2320 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
2322 if (asc_dbglvl >= (lvl)) { \
2323 asc_prt_asc_qdone_info(qdone); \
2327 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
2329 if (asc_dbglvl >= (lvl)) { \
2330 asc_prt_adv_scsi_req_q(scsiqp); \
2334 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2336 if (asc_dbglvl >= (lvl)) { \
2337 asc_prt_hex((name), (start), (length)); \
2341 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2342 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2344 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2345 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2347 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2348 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2349 #endif /* ADVANSYS_DEBUG */
2351 #ifdef ADVANSYS_STATS
2353 /* Per board statistics structure */
2354 struct asc_stats {
2355 /* Driver Entrypoint Statistics */
2356 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
2357 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
2358 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
2359 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
2360 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
2361 ADV_DCNT done; /* # calls to request's scsi_done function */
2362 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
2363 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
2364 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
2365 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
2366 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
2367 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
2368 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
2369 ADV_DCNT exe_unknown; /* # unknown returns. */
2370 /* Data Transfer Statistics */
2371 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
2372 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
2373 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
2374 ADV_DCNT sg_elem; /* # scatter-gather elements */
2375 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
2377 #endif /* ADVANSYS_STATS */
2380 * Adv Library Request Structures
2382 * The following two structures are used to process Wide Board requests.
2384 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
2385 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
2386 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
2387 * Mid-Level SCSI request structure.
2389 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
2390 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
2391 * up to 255 scatter-gather elements may be used per request or
2392 * ADV_SCSI_REQ_Q.
2394 * Both structures must be 32 byte aligned.
2396 typedef struct adv_sgblk {
2397 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
2398 uchar align[32]; /* Sgblock structure padding. */
2399 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
2400 } adv_sgblk_t;
2402 typedef struct adv_req {
2403 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
2404 uchar align[32]; /* Request structure padding. */
2405 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
2406 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
2407 struct adv_req *next_reqp; /* Next Request Structure. */
2408 } adv_req_t;
2411 * Structure allocated for each board.
2413 * This structure is allocated by scsi_host_alloc() at the end
2414 * of the 'Scsi_Host' structure starting at the 'hostdata'
2415 * field. It is guaranteed to be allocated from DMA-able memory.
2417 struct asc_board {
2418 struct device *dev;
2419 int id; /* Board Id */
2420 uint flags; /* Board flags */
2421 unsigned int irq;
2422 union {
2423 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
2424 ADV_DVC_VAR adv_dvc_var; /* Wide board */
2425 } dvc_var;
2426 union {
2427 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
2428 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
2429 } dvc_cfg;
2430 ushort asc_n_io_port; /* Number I/O ports. */
2431 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
2432 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
2433 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
2434 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
2435 union {
2436 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
2437 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
2438 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
2439 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
2440 } eep_config;
2441 ulong last_reset; /* Saved last reset time */
2442 spinlock_t lock; /* Board spinlock */
2443 /* /proc/scsi/advansys/[0...] */
2444 char *prtbuf; /* /proc print buffer */
2445 #ifdef ADVANSYS_STATS
2446 struct asc_stats asc_stats; /* Board statistics */
2447 #endif /* ADVANSYS_STATS */
2449 * The following fields are used only for Narrow Boards.
2451 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
2453 * The following fields are used only for Wide Boards.
2455 void __iomem *ioremap_addr; /* I/O Memory remap address. */
2456 ushort ioport; /* I/O Port address. */
2457 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
2458 adv_req_t *orig_reqp; /* adv_req_t memory block. */
2459 adv_req_t *adv_reqp; /* Request structures. */
2460 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
2461 ushort bios_signature; /* BIOS Signature. */
2462 ushort bios_version; /* BIOS Version. */
2463 ushort bios_codeseg; /* BIOS Code Segment. */
2464 ushort bios_codelen; /* BIOS Code Segment Length. */
2467 #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
2468 dvc_var.adv_dvc_var)
2469 #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
2471 /* Number of boards detected in system. */
2472 static int asc_board_count;
2474 /* Overrun buffer used by all narrow boards. */
2475 static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
2477 #ifdef ADVANSYS_DEBUG
2478 static int asc_dbglvl = 3;
2481 * asc_prt_asc_dvc_var()
2483 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
2485 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
2487 printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
2488 "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
2490 printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
2491 (unsigned)h->init_sdtr);
2493 printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
2494 "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
2495 (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
2496 (unsigned)h->chip_no);
2498 printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
2499 "%u,\n", (unsigned)h->queue_full_or_busy,
2500 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2502 printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
2503 "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
2504 (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
2505 (unsigned)h->in_critical_cnt);
2507 printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
2508 "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
2509 (unsigned)h->init_state, (unsigned)h->no_scam,
2510 (unsigned)h->pci_fix_asyn_xfer);
2512 printk(" cfg 0x%lx\n", (ulong)h->cfg);
2516 * asc_prt_asc_dvc_cfg()
2518 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
2520 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
2522 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
2523 h->can_tagged_qng, h->cmd_qng_enabled);
2524 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
2525 h->disc_enable, h->sdtr_enable);
2527 printk(" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, "
2528 "chip_version %d,\n", h->chip_scsi_id, h->isa_dma_speed,
2529 h->isa_dma_channel, h->chip_version);
2531 printk(" mcode_date 0x%x, mcode_version %d, overrun_buf 0x%p\n",
2532 h->mcode_date, h->mcode_version, h->overrun_buf);
2536 * asc_prt_adv_dvc_var()
2538 * Display an ADV_DVC_VAR structure.
2540 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
2542 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
2544 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
2545 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
2547 printk(" sdtr_able 0x%x, wdtr_able 0x%x\n",
2548 (unsigned)h->sdtr_able, (unsigned)h->wdtr_able);
2550 printk(" start_motor 0x%x, scsi_reset_wait 0x%x\n",
2551 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2553 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
2554 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
2555 (ulong)h->carr_freelist);
2557 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
2558 (ulong)h->icq_sp, (ulong)h->irq_sp);
2560 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
2561 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
2563 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
2564 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
2568 * asc_prt_adv_dvc_cfg()
2570 * Display an ADV_DVC_CFG structure.
2572 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
2574 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
2576 printk(" disc_enable 0x%x, termination 0x%x\n",
2577 h->disc_enable, h->termination);
2579 printk(" chip_version 0x%x, mcode_date 0x%x\n",
2580 h->chip_version, h->mcode_date);
2582 printk(" mcode_version 0x%x, control_flag 0x%x\n",
2583 h->mcode_version, h->control_flag);
2587 * asc_prt_scsi_host()
2589 static void asc_prt_scsi_host(struct Scsi_Host *s)
2591 struct asc_board *boardp = shost_priv(s);
2593 printk("Scsi_Host at addr 0x%p, device %s\n", s, boardp->dev->bus_id);
2594 printk(" host_busy %u, host_no %d, last_reset %d,\n",
2595 s->host_busy, s->host_no, (unsigned)s->last_reset);
2597 printk(" base 0x%lx, io_port 0x%lx, irq %d,\n",
2598 (ulong)s->base, (ulong)s->io_port, boardp->irq);
2600 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
2601 s->dma_channel, s->this_id, s->can_queue);
2603 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
2604 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
2606 if (ASC_NARROW_BOARD(boardp)) {
2607 asc_prt_asc_dvc_var(&boardp->dvc_var.asc_dvc_var);
2608 asc_prt_asc_dvc_cfg(&boardp->dvc_cfg.asc_dvc_cfg);
2609 } else {
2610 asc_prt_adv_dvc_var(&boardp->dvc_var.adv_dvc_var);
2611 asc_prt_adv_dvc_cfg(&boardp->dvc_cfg.adv_dvc_cfg);
2616 * asc_prt_hex()
2618 * Print hexadecimal output in 4 byte groupings 32 bytes
2619 * or 8 double-words per line.
2621 static void asc_prt_hex(char *f, uchar *s, int l)
2623 int i;
2624 int j;
2625 int k;
2626 int m;
2628 printk("%s: (%d bytes)\n", f, l);
2630 for (i = 0; i < l; i += 32) {
2632 /* Display a maximum of 8 double-words per line. */
2633 if ((k = (l - i) / 4) >= 8) {
2634 k = 8;
2635 m = 0;
2636 } else {
2637 m = (l - i) % 4;
2640 for (j = 0; j < k; j++) {
2641 printk(" %2.2X%2.2X%2.2X%2.2X",
2642 (unsigned)s[i + (j * 4)],
2643 (unsigned)s[i + (j * 4) + 1],
2644 (unsigned)s[i + (j * 4) + 2],
2645 (unsigned)s[i + (j * 4) + 3]);
2648 switch (m) {
2649 case 0:
2650 default:
2651 break;
2652 case 1:
2653 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
2654 break;
2655 case 2:
2656 printk(" %2.2X%2.2X",
2657 (unsigned)s[i + (j * 4)],
2658 (unsigned)s[i + (j * 4) + 1]);
2659 break;
2660 case 3:
2661 printk(" %2.2X%2.2X%2.2X",
2662 (unsigned)s[i + (j * 4) + 1],
2663 (unsigned)s[i + (j * 4) + 2],
2664 (unsigned)s[i + (j * 4) + 3]);
2665 break;
2668 printk("\n");
2673 * asc_prt_asc_scsi_q()
2675 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
2677 ASC_SG_HEAD *sgp;
2678 int i;
2680 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
2682 printk
2683 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
2684 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
2685 q->q2.tag_code);
2687 printk
2688 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2689 (ulong)le32_to_cpu(q->q1.data_addr),
2690 (ulong)le32_to_cpu(q->q1.data_cnt),
2691 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
2693 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
2694 (ulong)q->cdbptr, q->q2.cdb_len,
2695 (ulong)q->sg_head, q->q1.sg_queue_cnt);
2697 if (q->sg_head) {
2698 sgp = q->sg_head;
2699 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
2700 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
2701 sgp->queue_cnt);
2702 for (i = 0; i < sgp->entry_cnt; i++) {
2703 printk(" [%u]: addr 0x%lx, bytes %lu\n",
2704 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
2705 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
2712 * asc_prt_asc_qdone_info()
2714 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
2716 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
2717 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
2718 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
2719 q->d2.tag_code);
2720 printk
2721 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
2722 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
2726 * asc_prt_adv_sgblock()
2728 * Display an ADV_SG_BLOCK structure.
2730 static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
2732 int i;
2734 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
2735 (ulong)b, sgblockno);
2736 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
2737 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
2738 BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK);
2739 if (b->sg_ptr != 0)
2740 BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK);
2741 for (i = 0; i < b->sg_cnt; i++) {
2742 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
2743 i, (ulong)b->sg_list[i].sg_addr,
2744 (ulong)b->sg_list[i].sg_count);
2749 * asc_prt_adv_scsi_req_q()
2751 * Display an ADV_SCSI_REQ_Q structure.
2753 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
2755 int sg_blk_cnt;
2756 struct asc_sg_block *sg_ptr;
2758 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
2760 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
2761 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
2763 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
2764 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
2766 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2767 (ulong)le32_to_cpu(q->data_cnt),
2768 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
2770 printk
2771 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
2772 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
2774 printk(" sg_working_ix 0x%x, target_cmd %u\n",
2775 q->sg_working_ix, q->target_cmd);
2777 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
2778 (ulong)le32_to_cpu(q->scsiq_rptr),
2779 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
2781 /* Display the request's ADV_SG_BLOCK structures. */
2782 if (q->sg_list_ptr != NULL) {
2783 sg_blk_cnt = 0;
2784 while (1) {
2786 * 'sg_ptr' is a physical address. Convert it to a virtual
2787 * address by indexing 'sg_blk_cnt' into the virtual address
2788 * array 'sg_list_ptr'.
2790 * XXX - Assumes all SG physical blocks are virtually contiguous.
2792 sg_ptr =
2793 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
2794 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
2795 if (sg_ptr->sg_ptr == 0) {
2796 break;
2798 sg_blk_cnt++;
2802 #endif /* ADVANSYS_DEBUG */
2805 * advansys_info()
2807 * Return suitable for printing on the console with the argument
2808 * adapter's configuration information.
2810 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
2811 * otherwise the static 'info' array will be overrun.
2813 static const char *advansys_info(struct Scsi_Host *shost)
2815 static char info[ASC_INFO_SIZE];
2816 struct asc_board *boardp = shost_priv(shost);
2817 ASC_DVC_VAR *asc_dvc_varp;
2818 ADV_DVC_VAR *adv_dvc_varp;
2819 char *busname;
2820 char *widename = NULL;
2822 if (ASC_NARROW_BOARD(boardp)) {
2823 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
2824 ASC_DBG(1, "begin\n");
2825 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
2826 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
2827 ASC_IS_ISAPNP) {
2828 busname = "ISA PnP";
2829 } else {
2830 busname = "ISA";
2832 sprintf(info,
2833 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
2834 ASC_VERSION, busname,
2835 (ulong)shost->io_port,
2836 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2837 boardp->irq, shost->dma_channel);
2838 } else {
2839 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
2840 busname = "VL";
2841 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
2842 busname = "EISA";
2843 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
2844 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
2845 == ASC_IS_PCI_ULTRA) {
2846 busname = "PCI Ultra";
2847 } else {
2848 busname = "PCI";
2850 } else {
2851 busname = "?";
2852 ASC_PRINT2("advansys_info: board %d: unknown "
2853 "bus type %d\n", boardp->id,
2854 asc_dvc_varp->bus_type);
2856 sprintf(info,
2857 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
2858 ASC_VERSION, busname, (ulong)shost->io_port,
2859 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2860 boardp->irq);
2862 } else {
2864 * Wide Adapter Information
2866 * Memory-mapped I/O is used instead of I/O space to access
2867 * the adapter, but display the I/O Port range. The Memory
2868 * I/O address is displayed through the driver /proc file.
2870 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
2871 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
2872 widename = "Ultra-Wide";
2873 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
2874 widename = "Ultra2-Wide";
2875 } else {
2876 widename = "Ultra3-Wide";
2878 sprintf(info,
2879 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
2880 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
2881 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, boardp->irq);
2883 BUG_ON(strlen(info) >= ASC_INFO_SIZE);
2884 ASC_DBG(1, "end\n");
2885 return info;
2888 #ifdef CONFIG_PROC_FS
2890 * asc_prt_line()
2892 * If 'cp' is NULL print to the console, otherwise print to a buffer.
2894 * Return 0 if printing to the console, otherwise return the number of
2895 * bytes written to the buffer.
2897 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
2898 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
2900 static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
2902 va_list args;
2903 int ret;
2904 char s[ASC_PRTLINE_SIZE];
2906 va_start(args, fmt);
2907 ret = vsprintf(s, fmt, args);
2908 BUG_ON(ret >= ASC_PRTLINE_SIZE);
2909 if (buf == NULL) {
2910 (void)printk(s);
2911 ret = 0;
2912 } else {
2913 ret = min(buflen, ret);
2914 memcpy(buf, s, ret);
2916 va_end(args);
2917 return ret;
2921 * asc_prt_board_devices()
2923 * Print driver information for devices attached to the board.
2925 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
2926 * cf. asc_prt_line().
2928 * Return the number of characters copied into 'cp'. No more than
2929 * 'cplen' characters will be copied to 'cp'.
2931 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
2933 struct asc_board *boardp = shost_priv(shost);
2934 int leftlen;
2935 int totlen;
2936 int len;
2937 int chip_scsi_id;
2938 int i;
2940 leftlen = cplen;
2941 totlen = len = 0;
2943 len = asc_prt_line(cp, leftlen,
2944 "\nDevice Information for AdvanSys SCSI Host %d:\n",
2945 shost->host_no);
2946 ASC_PRT_NEXT();
2948 if (ASC_NARROW_BOARD(boardp)) {
2949 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
2950 } else {
2951 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
2954 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
2955 ASC_PRT_NEXT();
2956 for (i = 0; i <= ADV_MAX_TID; i++) {
2957 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
2958 len = asc_prt_line(cp, leftlen, " %X,", i);
2959 ASC_PRT_NEXT();
2962 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
2963 ASC_PRT_NEXT();
2965 return totlen;
2969 * Display Wide Board BIOS Information.
2971 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
2973 struct asc_board *boardp = shost_priv(shost);
2974 int leftlen;
2975 int totlen;
2976 int len;
2977 ushort major, minor, letter;
2979 leftlen = cplen;
2980 totlen = len = 0;
2982 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
2983 ASC_PRT_NEXT();
2986 * If the BIOS saved a valid signature, then fill in
2987 * the BIOS code segment base address.
2989 if (boardp->bios_signature != 0x55AA) {
2990 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
2991 ASC_PRT_NEXT();
2992 len = asc_prt_line(cp, leftlen,
2993 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
2994 ASC_PRT_NEXT();
2995 len = asc_prt_line(cp, leftlen,
2996 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
2997 ASC_PRT_NEXT();
2998 } else {
2999 major = (boardp->bios_version >> 12) & 0xF;
3000 minor = (boardp->bios_version >> 8) & 0xF;
3001 letter = (boardp->bios_version & 0xFF);
3003 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
3004 major, minor,
3005 letter >= 26 ? '?' : letter + 'A');
3006 ASC_PRT_NEXT();
3009 * Current available ROM BIOS release is 3.1I for UW
3010 * and 3.2I for U2W. This code doesn't differentiate
3011 * UW and U2W boards.
3013 if (major < 3 || (major <= 3 && minor < 1) ||
3014 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
3015 len = asc_prt_line(cp, leftlen,
3016 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
3017 ASC_PRT_NEXT();
3018 len = asc_prt_line(cp, leftlen,
3019 "ftp://ftp.connectcom.net/pub\n");
3020 ASC_PRT_NEXT();
3024 return totlen;
3028 * Add serial number to information bar if signature AAh
3029 * is found in at bit 15-9 (7 bits) of word 1.
3031 * Serial Number consists fo 12 alpha-numeric digits.
3033 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
3034 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
3035 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
3036 * 5 - Product revision (A-J) Word0: " "
3038 * Signature Word1: 15-9 (7 bits)
3039 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
3040 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
3042 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
3044 * Note 1: Only production cards will have a serial number.
3046 * Note 2: Signature is most significant 7 bits (0xFE).
3048 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
3050 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
3052 ushort w, num;
3054 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
3055 return ASC_FALSE;
3056 } else {
3058 * First word - 6 digits.
3060 w = serialnum[0];
3062 /* Product type - 1st digit. */
3063 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
3064 /* Product type is P=Prototype */
3065 *cp += 0x8;
3067 cp++;
3069 /* Manufacturing location - 2nd digit. */
3070 *cp++ = 'A' + ((w & 0x1C00) >> 10);
3072 /* Product ID - 3rd, 4th digits. */
3073 num = w & 0x3FF;
3074 *cp++ = '0' + (num / 100);
3075 num %= 100;
3076 *cp++ = '0' + (num / 10);
3078 /* Product revision - 5th digit. */
3079 *cp++ = 'A' + (num % 10);
3082 * Second word
3084 w = serialnum[1];
3087 * Year - 6th digit.
3089 * If bit 15 of third word is set, then the
3090 * last digit of the year is greater than 7.
3092 if (serialnum[2] & 0x8000) {
3093 *cp++ = '8' + ((w & 0x1C0) >> 6);
3094 } else {
3095 *cp++ = '0' + ((w & 0x1C0) >> 6);
3098 /* Week of year - 7th, 8th digits. */
3099 num = w & 0x003F;
3100 *cp++ = '0' + num / 10;
3101 num %= 10;
3102 *cp++ = '0' + num;
3105 * Third word
3107 w = serialnum[2] & 0x7FFF;
3109 /* Serial number - 9th digit. */
3110 *cp++ = 'A' + (w / 1000);
3112 /* 10th, 11th, 12th digits. */
3113 num = w % 1000;
3114 *cp++ = '0' + num / 100;
3115 num %= 100;
3116 *cp++ = '0' + num / 10;
3117 num %= 10;
3118 *cp++ = '0' + num;
3120 *cp = '\0'; /* Null Terminate the string. */
3121 return ASC_TRUE;
3126 * asc_prt_asc_board_eeprom()
3128 * Print board EEPROM configuration.
3130 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3131 * cf. asc_prt_line().
3133 * Return the number of characters copied into 'cp'. No more than
3134 * 'cplen' characters will be copied to 'cp'.
3136 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
3138 struct asc_board *boardp = shost_priv(shost);
3139 ASC_DVC_VAR *asc_dvc_varp;
3140 int leftlen;
3141 int totlen;
3142 int len;
3143 ASCEEP_CONFIG *ep;
3144 int i;
3145 #ifdef CONFIG_ISA
3146 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
3147 #endif /* CONFIG_ISA */
3148 uchar serialstr[13];
3150 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3151 ep = &boardp->eep_config.asc_eep;
3153 leftlen = cplen;
3154 totlen = len = 0;
3156 len = asc_prt_line(cp, leftlen,
3157 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3158 shost->host_no);
3159 ASC_PRT_NEXT();
3161 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
3162 == ASC_TRUE) {
3163 len =
3164 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
3165 serialstr);
3166 ASC_PRT_NEXT();
3167 } else {
3168 if (ep->adapter_info[5] == 0xBB) {
3169 len = asc_prt_line(cp, leftlen,
3170 " Default Settings Used for EEPROM-less Adapter.\n");
3171 ASC_PRT_NEXT();
3172 } else {
3173 len = asc_prt_line(cp, leftlen,
3174 " Serial Number Signature Not Present.\n");
3175 ASC_PRT_NEXT();
3179 len = asc_prt_line(cp, leftlen,
3180 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3181 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
3182 ep->max_tag_qng);
3183 ASC_PRT_NEXT();
3185 len = asc_prt_line(cp, leftlen,
3186 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
3187 ASC_PRT_NEXT();
3189 len = asc_prt_line(cp, leftlen, " Target ID: ");
3190 ASC_PRT_NEXT();
3191 for (i = 0; i <= ASC_MAX_TID; i++) {
3192 len = asc_prt_line(cp, leftlen, " %d", i);
3193 ASC_PRT_NEXT();
3195 len = asc_prt_line(cp, leftlen, "\n");
3196 ASC_PRT_NEXT();
3198 len = asc_prt_line(cp, leftlen, " Disconnects: ");
3199 ASC_PRT_NEXT();
3200 for (i = 0; i <= ASC_MAX_TID; i++) {
3201 len = asc_prt_line(cp, leftlen, " %c",
3202 (ep->
3203 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3204 'N');
3205 ASC_PRT_NEXT();
3207 len = asc_prt_line(cp, leftlen, "\n");
3208 ASC_PRT_NEXT();
3210 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
3211 ASC_PRT_NEXT();
3212 for (i = 0; i <= ASC_MAX_TID; i++) {
3213 len = asc_prt_line(cp, leftlen, " %c",
3214 (ep->
3215 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3216 'N');
3217 ASC_PRT_NEXT();
3219 len = asc_prt_line(cp, leftlen, "\n");
3220 ASC_PRT_NEXT();
3222 len = asc_prt_line(cp, leftlen, " Start Motor: ");
3223 ASC_PRT_NEXT();
3224 for (i = 0; i <= ASC_MAX_TID; i++) {
3225 len = asc_prt_line(cp, leftlen, " %c",
3226 (ep->
3227 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3228 'N');
3229 ASC_PRT_NEXT();
3231 len = asc_prt_line(cp, leftlen, "\n");
3232 ASC_PRT_NEXT();
3234 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3235 ASC_PRT_NEXT();
3236 for (i = 0; i <= ASC_MAX_TID; i++) {
3237 len = asc_prt_line(cp, leftlen, " %c",
3238 (ep->
3239 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3240 'N');
3241 ASC_PRT_NEXT();
3243 len = asc_prt_line(cp, leftlen, "\n");
3244 ASC_PRT_NEXT();
3246 #ifdef CONFIG_ISA
3247 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3248 len = asc_prt_line(cp, leftlen,
3249 " Host ISA DMA speed: %d MB/S\n",
3250 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
3251 ASC_PRT_NEXT();
3253 #endif /* CONFIG_ISA */
3255 return totlen;
3259 * asc_prt_adv_board_eeprom()
3261 * Print board EEPROM configuration.
3263 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3264 * cf. asc_prt_line().
3266 * Return the number of characters copied into 'cp'. No more than
3267 * 'cplen' characters will be copied to 'cp'.
3269 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
3271 struct asc_board *boardp = shost_priv(shost);
3272 ADV_DVC_VAR *adv_dvc_varp;
3273 int leftlen;
3274 int totlen;
3275 int len;
3276 int i;
3277 char *termstr;
3278 uchar serialstr[13];
3279 ADVEEP_3550_CONFIG *ep_3550 = NULL;
3280 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
3281 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
3282 ushort word;
3283 ushort *wordp;
3284 ushort sdtr_speed = 0;
3286 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3287 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3288 ep_3550 = &boardp->eep_config.adv_3550_eep;
3289 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3290 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
3291 } else {
3292 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
3295 leftlen = cplen;
3296 totlen = len = 0;
3298 len = asc_prt_line(cp, leftlen,
3299 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3300 shost->host_no);
3301 ASC_PRT_NEXT();
3303 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3304 wordp = &ep_3550->serial_number_word1;
3305 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3306 wordp = &ep_38C0800->serial_number_word1;
3307 } else {
3308 wordp = &ep_38C1600->serial_number_word1;
3311 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
3312 len =
3313 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
3314 serialstr);
3315 ASC_PRT_NEXT();
3316 } else {
3317 len = asc_prt_line(cp, leftlen,
3318 " Serial Number Signature Not Present.\n");
3319 ASC_PRT_NEXT();
3322 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3323 len = asc_prt_line(cp, leftlen,
3324 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3325 ep_3550->adapter_scsi_id,
3326 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
3327 ASC_PRT_NEXT();
3328 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3329 len = asc_prt_line(cp, leftlen,
3330 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3331 ep_38C0800->adapter_scsi_id,
3332 ep_38C0800->max_host_qng,
3333 ep_38C0800->max_dvc_qng);
3334 ASC_PRT_NEXT();
3335 } else {
3336 len = asc_prt_line(cp, leftlen,
3337 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3338 ep_38C1600->adapter_scsi_id,
3339 ep_38C1600->max_host_qng,
3340 ep_38C1600->max_dvc_qng);
3341 ASC_PRT_NEXT();
3343 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3344 word = ep_3550->termination;
3345 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3346 word = ep_38C0800->termination_lvd;
3347 } else {
3348 word = ep_38C1600->termination_lvd;
3350 switch (word) {
3351 case 1:
3352 termstr = "Low Off/High Off";
3353 break;
3354 case 2:
3355 termstr = "Low Off/High On";
3356 break;
3357 case 3:
3358 termstr = "Low On/High On";
3359 break;
3360 default:
3361 case 0:
3362 termstr = "Automatic";
3363 break;
3366 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3367 len = asc_prt_line(cp, leftlen,
3368 " termination: %u (%s), bios_ctrl: 0x%x\n",
3369 ep_3550->termination, termstr,
3370 ep_3550->bios_ctrl);
3371 ASC_PRT_NEXT();
3372 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3373 len = asc_prt_line(cp, leftlen,
3374 " termination: %u (%s), bios_ctrl: 0x%x\n",
3375 ep_38C0800->termination_lvd, termstr,
3376 ep_38C0800->bios_ctrl);
3377 ASC_PRT_NEXT();
3378 } else {
3379 len = asc_prt_line(cp, leftlen,
3380 " termination: %u (%s), bios_ctrl: 0x%x\n",
3381 ep_38C1600->termination_lvd, termstr,
3382 ep_38C1600->bios_ctrl);
3383 ASC_PRT_NEXT();
3386 len = asc_prt_line(cp, leftlen, " Target ID: ");
3387 ASC_PRT_NEXT();
3388 for (i = 0; i <= ADV_MAX_TID; i++) {
3389 len = asc_prt_line(cp, leftlen, " %X", i);
3390 ASC_PRT_NEXT();
3392 len = asc_prt_line(cp, leftlen, "\n");
3393 ASC_PRT_NEXT();
3395 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3396 word = ep_3550->disc_enable;
3397 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3398 word = ep_38C0800->disc_enable;
3399 } else {
3400 word = ep_38C1600->disc_enable;
3402 len = asc_prt_line(cp, leftlen, " Disconnects: ");
3403 ASC_PRT_NEXT();
3404 for (i = 0; i <= ADV_MAX_TID; i++) {
3405 len = asc_prt_line(cp, leftlen, " %c",
3406 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3407 ASC_PRT_NEXT();
3409 len = asc_prt_line(cp, leftlen, "\n");
3410 ASC_PRT_NEXT();
3412 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3413 word = ep_3550->tagqng_able;
3414 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3415 word = ep_38C0800->tagqng_able;
3416 } else {
3417 word = ep_38C1600->tagqng_able;
3419 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
3420 ASC_PRT_NEXT();
3421 for (i = 0; i <= ADV_MAX_TID; i++) {
3422 len = asc_prt_line(cp, leftlen, " %c",
3423 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3424 ASC_PRT_NEXT();
3426 len = asc_prt_line(cp, leftlen, "\n");
3427 ASC_PRT_NEXT();
3429 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3430 word = ep_3550->start_motor;
3431 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3432 word = ep_38C0800->start_motor;
3433 } else {
3434 word = ep_38C1600->start_motor;
3436 len = asc_prt_line(cp, leftlen, " Start Motor: ");
3437 ASC_PRT_NEXT();
3438 for (i = 0; i <= ADV_MAX_TID; i++) {
3439 len = asc_prt_line(cp, leftlen, " %c",
3440 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3441 ASC_PRT_NEXT();
3443 len = asc_prt_line(cp, leftlen, "\n");
3444 ASC_PRT_NEXT();
3446 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3447 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3448 ASC_PRT_NEXT();
3449 for (i = 0; i <= ADV_MAX_TID; i++) {
3450 len = asc_prt_line(cp, leftlen, " %c",
3451 (ep_3550->
3452 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
3453 'Y' : 'N');
3454 ASC_PRT_NEXT();
3456 len = asc_prt_line(cp, leftlen, "\n");
3457 ASC_PRT_NEXT();
3460 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3461 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
3462 ASC_PRT_NEXT();
3463 for (i = 0; i <= ADV_MAX_TID; i++) {
3464 len = asc_prt_line(cp, leftlen, " %c",
3465 (ep_3550->
3466 ultra_able & ADV_TID_TO_TIDMASK(i))
3467 ? 'Y' : 'N');
3468 ASC_PRT_NEXT();
3470 len = asc_prt_line(cp, leftlen, "\n");
3471 ASC_PRT_NEXT();
3474 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3475 word = ep_3550->wdtr_able;
3476 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3477 word = ep_38C0800->wdtr_able;
3478 } else {
3479 word = ep_38C1600->wdtr_able;
3481 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
3482 ASC_PRT_NEXT();
3483 for (i = 0; i <= ADV_MAX_TID; i++) {
3484 len = asc_prt_line(cp, leftlen, " %c",
3485 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3486 ASC_PRT_NEXT();
3488 len = asc_prt_line(cp, leftlen, "\n");
3489 ASC_PRT_NEXT();
3491 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
3492 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
3493 len = asc_prt_line(cp, leftlen,
3494 " Synchronous Transfer Speed (Mhz):\n ");
3495 ASC_PRT_NEXT();
3496 for (i = 0; i <= ADV_MAX_TID; i++) {
3497 char *speed_str;
3499 if (i == 0) {
3500 sdtr_speed = adv_dvc_varp->sdtr_speed1;
3501 } else if (i == 4) {
3502 sdtr_speed = adv_dvc_varp->sdtr_speed2;
3503 } else if (i == 8) {
3504 sdtr_speed = adv_dvc_varp->sdtr_speed3;
3505 } else if (i == 12) {
3506 sdtr_speed = adv_dvc_varp->sdtr_speed4;
3508 switch (sdtr_speed & ADV_MAX_TID) {
3509 case 0:
3510 speed_str = "Off";
3511 break;
3512 case 1:
3513 speed_str = " 5";
3514 break;
3515 case 2:
3516 speed_str = " 10";
3517 break;
3518 case 3:
3519 speed_str = " 20";
3520 break;
3521 case 4:
3522 speed_str = " 40";
3523 break;
3524 case 5:
3525 speed_str = " 80";
3526 break;
3527 default:
3528 speed_str = "Unk";
3529 break;
3531 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
3532 ASC_PRT_NEXT();
3533 if (i == 7) {
3534 len = asc_prt_line(cp, leftlen, "\n ");
3535 ASC_PRT_NEXT();
3537 sdtr_speed >>= 4;
3539 len = asc_prt_line(cp, leftlen, "\n");
3540 ASC_PRT_NEXT();
3543 return totlen;
3547 * asc_prt_driver_conf()
3549 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3550 * cf. asc_prt_line().
3552 * Return the number of characters copied into 'cp'. No more than
3553 * 'cplen' characters will be copied to 'cp'.
3555 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
3557 struct asc_board *boardp = shost_priv(shost);
3558 int leftlen;
3559 int totlen;
3560 int len;
3561 int chip_scsi_id;
3563 leftlen = cplen;
3564 totlen = len = 0;
3566 len = asc_prt_line(cp, leftlen,
3567 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
3568 shost->host_no);
3569 ASC_PRT_NEXT();
3571 len = asc_prt_line(cp, leftlen,
3572 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
3573 shost->host_busy, shost->last_reset, shost->max_id,
3574 shost->max_lun, shost->max_channel);
3575 ASC_PRT_NEXT();
3577 len = asc_prt_line(cp, leftlen,
3578 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
3579 shost->unique_id, shost->can_queue, shost->this_id,
3580 shost->sg_tablesize, shost->cmd_per_lun);
3581 ASC_PRT_NEXT();
3583 len = asc_prt_line(cp, leftlen,
3584 " unchecked_isa_dma %d, use_clustering %d\n",
3585 shost->unchecked_isa_dma, shost->use_clustering);
3586 ASC_PRT_NEXT();
3588 len = asc_prt_line(cp, leftlen,
3589 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
3590 boardp->flags, boardp->last_reset, jiffies,
3591 boardp->asc_n_io_port);
3592 ASC_PRT_NEXT();
3594 len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
3595 ASC_PRT_NEXT();
3597 if (ASC_NARROW_BOARD(boardp)) {
3598 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
3599 } else {
3600 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
3603 return totlen;
3607 * asc_prt_asc_board_info()
3609 * Print dynamic board configuration information.
3611 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3612 * cf. asc_prt_line().
3614 * Return the number of characters copied into 'cp'. No more than
3615 * 'cplen' characters will be copied to 'cp'.
3617 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
3619 struct asc_board *boardp = shost_priv(shost);
3620 int chip_scsi_id;
3621 int leftlen;
3622 int totlen;
3623 int len;
3624 ASC_DVC_VAR *v;
3625 ASC_DVC_CFG *c;
3626 int i;
3627 int renegotiate = 0;
3629 v = &boardp->dvc_var.asc_dvc_var;
3630 c = &boardp->dvc_cfg.asc_dvc_cfg;
3631 chip_scsi_id = c->chip_scsi_id;
3633 leftlen = cplen;
3634 totlen = len = 0;
3636 len = asc_prt_line(cp, leftlen,
3637 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3638 shost->host_no);
3639 ASC_PRT_NEXT();
3641 len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, "
3642 "mcode_version 0x%x, err_code %u\n",
3643 c->chip_version, c->mcode_date, c->mcode_version,
3644 v->err_code);
3645 ASC_PRT_NEXT();
3647 /* Current number of commands waiting for the host. */
3648 len = asc_prt_line(cp, leftlen,
3649 " Total Command Pending: %d\n", v->cur_total_qng);
3650 ASC_PRT_NEXT();
3652 len = asc_prt_line(cp, leftlen, " Command Queuing:");
3653 ASC_PRT_NEXT();
3654 for (i = 0; i <= ASC_MAX_TID; i++) {
3655 if ((chip_scsi_id == i) ||
3656 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3657 continue;
3659 len = asc_prt_line(cp, leftlen, " %X:%c",
3661 (v->
3662 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
3663 'Y' : 'N');
3664 ASC_PRT_NEXT();
3666 len = asc_prt_line(cp, leftlen, "\n");
3667 ASC_PRT_NEXT();
3669 /* Current number of commands waiting for a device. */
3670 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
3671 ASC_PRT_NEXT();
3672 for (i = 0; i <= ASC_MAX_TID; i++) {
3673 if ((chip_scsi_id == i) ||
3674 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3675 continue;
3677 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
3678 ASC_PRT_NEXT();
3680 len = asc_prt_line(cp, leftlen, "\n");
3681 ASC_PRT_NEXT();
3683 /* Current limit on number of commands that can be sent to a device. */
3684 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
3685 ASC_PRT_NEXT();
3686 for (i = 0; i <= ASC_MAX_TID; i++) {
3687 if ((chip_scsi_id == i) ||
3688 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3689 continue;
3691 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
3692 ASC_PRT_NEXT();
3694 len = asc_prt_line(cp, leftlen, "\n");
3695 ASC_PRT_NEXT();
3697 /* Indicate whether the device has returned queue full status. */
3698 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
3699 ASC_PRT_NEXT();
3700 for (i = 0; i <= ASC_MAX_TID; i++) {
3701 if ((chip_scsi_id == i) ||
3702 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3703 continue;
3705 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
3706 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
3707 i, boardp->queue_full_cnt[i]);
3708 } else {
3709 len = asc_prt_line(cp, leftlen, " %X:N", i);
3711 ASC_PRT_NEXT();
3713 len = asc_prt_line(cp, leftlen, "\n");
3714 ASC_PRT_NEXT();
3716 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3717 ASC_PRT_NEXT();
3718 for (i = 0; i <= ASC_MAX_TID; i++) {
3719 if ((chip_scsi_id == i) ||
3720 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3721 continue;
3723 len = asc_prt_line(cp, leftlen, " %X:%c",
3725 (v->
3726 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3727 'N');
3728 ASC_PRT_NEXT();
3730 len = asc_prt_line(cp, leftlen, "\n");
3731 ASC_PRT_NEXT();
3733 for (i = 0; i <= ASC_MAX_TID; i++) {
3734 uchar syn_period_ix;
3736 if ((chip_scsi_id == i) ||
3737 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3738 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
3739 continue;
3742 len = asc_prt_line(cp, leftlen, " %X:", i);
3743 ASC_PRT_NEXT();
3745 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
3746 len = asc_prt_line(cp, leftlen, " Asynchronous");
3747 ASC_PRT_NEXT();
3748 } else {
3749 syn_period_ix =
3750 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
3753 len = asc_prt_line(cp, leftlen,
3754 " Transfer Period Factor: %d (%d.%d Mhz),",
3755 v->sdtr_period_tbl[syn_period_ix],
3756 250 /
3757 v->sdtr_period_tbl[syn_period_ix],
3758 ASC_TENTHS(250,
3760 sdtr_period_tbl
3761 [syn_period_ix]));
3762 ASC_PRT_NEXT();
3764 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
3765 boardp->
3766 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
3767 ASC_PRT_NEXT();
3770 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3771 len = asc_prt_line(cp, leftlen, "*\n");
3772 renegotiate = 1;
3773 } else {
3774 len = asc_prt_line(cp, leftlen, "\n");
3776 ASC_PRT_NEXT();
3779 if (renegotiate) {
3780 len = asc_prt_line(cp, leftlen,
3781 " * = Re-negotiation pending before next command.\n");
3782 ASC_PRT_NEXT();
3785 return totlen;
3789 * asc_prt_adv_board_info()
3791 * Print dynamic board configuration information.
3793 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3794 * cf. asc_prt_line().
3796 * Return the number of characters copied into 'cp'. No more than
3797 * 'cplen' characters will be copied to 'cp'.
3799 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
3801 struct asc_board *boardp = shost_priv(shost);
3802 int leftlen;
3803 int totlen;
3804 int len;
3805 int i;
3806 ADV_DVC_VAR *v;
3807 ADV_DVC_CFG *c;
3808 AdvPortAddr iop_base;
3809 ushort chip_scsi_id;
3810 ushort lramword;
3811 uchar lrambyte;
3812 ushort tagqng_able;
3813 ushort sdtr_able, wdtr_able;
3814 ushort wdtr_done, sdtr_done;
3815 ushort period = 0;
3816 int renegotiate = 0;
3818 v = &boardp->dvc_var.adv_dvc_var;
3819 c = &boardp->dvc_cfg.adv_dvc_cfg;
3820 iop_base = v->iop_base;
3821 chip_scsi_id = v->chip_scsi_id;
3823 leftlen = cplen;
3824 totlen = len = 0;
3826 len = asc_prt_line(cp, leftlen,
3827 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3828 shost->host_no);
3829 ASC_PRT_NEXT();
3831 len = asc_prt_line(cp, leftlen,
3832 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
3833 v->iop_base,
3834 AdvReadWordRegister(iop_base,
3835 IOPW_SCSI_CFG1) & CABLE_DETECT,
3836 v->err_code);
3837 ASC_PRT_NEXT();
3839 len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, "
3840 "mcode_version 0x%x\n", c->chip_version,
3841 c->mcode_date, c->mcode_version);
3842 ASC_PRT_NEXT();
3844 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
3845 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
3846 ASC_PRT_NEXT();
3847 for (i = 0; i <= ADV_MAX_TID; i++) {
3848 if ((chip_scsi_id == i) ||
3849 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3850 continue;
3853 len = asc_prt_line(cp, leftlen, " %X:%c",
3855 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3856 'N');
3857 ASC_PRT_NEXT();
3859 len = asc_prt_line(cp, leftlen, "\n");
3860 ASC_PRT_NEXT();
3862 len = asc_prt_line(cp, leftlen, " Queue Limit:");
3863 ASC_PRT_NEXT();
3864 for (i = 0; i <= ADV_MAX_TID; i++) {
3865 if ((chip_scsi_id == i) ||
3866 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3867 continue;
3870 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
3871 lrambyte);
3873 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
3874 ASC_PRT_NEXT();
3876 len = asc_prt_line(cp, leftlen, "\n");
3877 ASC_PRT_NEXT();
3879 len = asc_prt_line(cp, leftlen, " Command Pending:");
3880 ASC_PRT_NEXT();
3881 for (i = 0; i <= ADV_MAX_TID; i++) {
3882 if ((chip_scsi_id == i) ||
3883 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3884 continue;
3887 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
3888 lrambyte);
3890 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
3891 ASC_PRT_NEXT();
3893 len = asc_prt_line(cp, leftlen, "\n");
3894 ASC_PRT_NEXT();
3896 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
3897 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
3898 ASC_PRT_NEXT();
3899 for (i = 0; i <= ADV_MAX_TID; i++) {
3900 if ((chip_scsi_id == i) ||
3901 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3902 continue;
3905 len = asc_prt_line(cp, leftlen, " %X:%c",
3907 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3908 'N');
3909 ASC_PRT_NEXT();
3911 len = asc_prt_line(cp, leftlen, "\n");
3912 ASC_PRT_NEXT();
3914 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
3915 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
3916 ASC_PRT_NEXT();
3917 for (i = 0; i <= ADV_MAX_TID; i++) {
3918 if ((chip_scsi_id == i) ||
3919 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3920 continue;
3923 AdvReadWordLram(iop_base,
3924 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
3925 lramword);
3927 len = asc_prt_line(cp, leftlen, " %X:%d",
3928 i, (lramword & 0x8000) ? 16 : 8);
3929 ASC_PRT_NEXT();
3931 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
3932 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3933 len = asc_prt_line(cp, leftlen, "*");
3934 ASC_PRT_NEXT();
3935 renegotiate = 1;
3938 len = asc_prt_line(cp, leftlen, "\n");
3939 ASC_PRT_NEXT();
3941 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
3942 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
3943 ASC_PRT_NEXT();
3944 for (i = 0; i <= ADV_MAX_TID; i++) {
3945 if ((chip_scsi_id == i) ||
3946 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3947 continue;
3950 len = asc_prt_line(cp, leftlen, " %X:%c",
3952 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3953 'N');
3954 ASC_PRT_NEXT();
3956 len = asc_prt_line(cp, leftlen, "\n");
3957 ASC_PRT_NEXT();
3959 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
3960 for (i = 0; i <= ADV_MAX_TID; i++) {
3962 AdvReadWordLram(iop_base,
3963 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
3964 lramword);
3965 lramword &= ~0x8000;
3967 if ((chip_scsi_id == i) ||
3968 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3969 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
3970 continue;
3973 len = asc_prt_line(cp, leftlen, " %X:", i);
3974 ASC_PRT_NEXT();
3976 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
3977 len = asc_prt_line(cp, leftlen, " Asynchronous");
3978 ASC_PRT_NEXT();
3979 } else {
3980 len =
3981 asc_prt_line(cp, leftlen,
3982 " Transfer Period Factor: ");
3983 ASC_PRT_NEXT();
3985 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
3986 len =
3987 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
3988 ASC_PRT_NEXT();
3989 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
3990 len =
3991 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
3992 ASC_PRT_NEXT();
3993 } else { /* 20 Mhz or below. */
3995 period = (((lramword >> 8) * 25) + 50) / 4;
3997 if (period == 0) { /* Should never happen. */
3998 len =
3999 asc_prt_line(cp, leftlen,
4000 "%d (? Mhz), ");
4001 ASC_PRT_NEXT();
4002 } else {
4003 len = asc_prt_line(cp, leftlen,
4004 "%d (%d.%d Mhz),",
4005 period, 250 / period,
4006 ASC_TENTHS(250,
4007 period));
4008 ASC_PRT_NEXT();
4012 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
4013 lramword & 0x1F);
4014 ASC_PRT_NEXT();
4017 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
4018 len = asc_prt_line(cp, leftlen, "*\n");
4019 renegotiate = 1;
4020 } else {
4021 len = asc_prt_line(cp, leftlen, "\n");
4023 ASC_PRT_NEXT();
4026 if (renegotiate) {
4027 len = asc_prt_line(cp, leftlen,
4028 " * = Re-negotiation pending before next command.\n");
4029 ASC_PRT_NEXT();
4032 return totlen;
4036 * asc_proc_copy()
4038 * Copy proc information to a read buffer taking into account the current
4039 * read offset in the file and the remaining space in the read buffer.
4041 static int
4042 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
4043 char *cp, int cplen)
4045 int cnt = 0;
4047 ASC_DBG(2, "offset %d, advoffset %d, cplen %d\n",
4048 (unsigned)offset, (unsigned)advoffset, cplen);
4049 if (offset <= advoffset) {
4050 /* Read offset below current offset, copy everything. */
4051 cnt = min(cplen, leftlen);
4052 ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n",
4053 (ulong)curbuf, (ulong)cp, cnt);
4054 memcpy(curbuf, cp, cnt);
4055 } else if (offset < advoffset + cplen) {
4056 /* Read offset within current range, partial copy. */
4057 cnt = (advoffset + cplen) - offset;
4058 cp = (cp + cplen) - cnt;
4059 cnt = min(cnt, leftlen);
4060 ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n",
4061 (ulong)curbuf, (ulong)cp, cnt);
4062 memcpy(curbuf, cp, cnt);
4064 return cnt;
4067 #ifdef ADVANSYS_STATS
4069 * asc_prt_board_stats()
4071 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4072 * cf. asc_prt_line().
4074 * Return the number of characters copied into 'cp'. No more than
4075 * 'cplen' characters will be copied to 'cp'.
4077 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
4079 struct asc_board *boardp = shost_priv(shost);
4080 struct asc_stats *s = &boardp->asc_stats;
4082 int leftlen = cplen;
4083 int len, totlen = 0;
4085 len = asc_prt_line(cp, leftlen,
4086 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
4087 shost->host_no);
4088 ASC_PRT_NEXT();
4090 len = asc_prt_line(cp, leftlen,
4091 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
4092 s->queuecommand, s->reset, s->biosparam,
4093 s->interrupt);
4094 ASC_PRT_NEXT();
4096 len = asc_prt_line(cp, leftlen,
4097 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
4098 s->callback, s->done, s->build_error,
4099 s->adv_build_noreq, s->adv_build_nosg);
4100 ASC_PRT_NEXT();
4102 len = asc_prt_line(cp, leftlen,
4103 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
4104 s->exe_noerror, s->exe_busy, s->exe_error,
4105 s->exe_unknown);
4106 ASC_PRT_NEXT();
4109 * Display data transfer statistics.
4111 if (s->cont_cnt > 0) {
4112 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
4113 ASC_PRT_NEXT();
4115 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
4116 s->cont_xfer / 2,
4117 ASC_TENTHS(s->cont_xfer, 2));
4118 ASC_PRT_NEXT();
4120 /* Contiguous transfer average size */
4121 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
4122 (s->cont_xfer / 2) / s->cont_cnt,
4123 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
4124 ASC_PRT_NEXT();
4127 if (s->sg_cnt > 0) {
4129 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
4130 s->sg_cnt, s->sg_elem);
4131 ASC_PRT_NEXT();
4133 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
4134 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
4135 ASC_PRT_NEXT();
4137 /* Scatter gather transfer statistics */
4138 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
4139 s->sg_elem / s->sg_cnt,
4140 ASC_TENTHS(s->sg_elem, s->sg_cnt));
4141 ASC_PRT_NEXT();
4143 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
4144 (s->sg_xfer / 2) / s->sg_elem,
4145 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
4146 ASC_PRT_NEXT();
4148 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
4149 (s->sg_xfer / 2) / s->sg_cnt,
4150 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
4151 ASC_PRT_NEXT();
4155 * Display request queuing statistics.
4157 len = asc_prt_line(cp, leftlen,
4158 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
4159 HZ);
4160 ASC_PRT_NEXT();
4162 return totlen;
4164 #endif /* ADVANSYS_STATS */
4167 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
4169 * *buffer: I/O buffer
4170 * **start: if inout == FALSE pointer into buffer where user read should start
4171 * offset: current offset into a /proc/scsi/advansys/[0...] file
4172 * length: length of buffer
4173 * hostno: Scsi_Host host_no
4174 * inout: TRUE - user is writing; FALSE - user is reading
4176 * Return the number of bytes read from or written to a
4177 * /proc/scsi/advansys/[0...] file.
4179 * Note: This function uses the per board buffer 'prtbuf' which is
4180 * allocated when the board is initialized in advansys_detect(). The
4181 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4182 * used to write to the buffer. The way asc_proc_copy() is written
4183 * if 'prtbuf' is too small it will not be overwritten. Instead the
4184 * user just won't get all the available statistics.
4186 static int
4187 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4188 off_t offset, int length, int inout)
4190 struct asc_board *boardp = shost_priv(shost);
4191 char *cp;
4192 int cplen;
4193 int cnt;
4194 int totcnt;
4195 int leftlen;
4196 char *curbuf;
4197 off_t advoffset;
4199 ASC_DBG(1, "begin\n");
4202 * User write not supported.
4204 if (inout == TRUE)
4205 return -ENOSYS;
4208 * User read of /proc/scsi/advansys/[0...] file.
4211 /* Copy read data starting at the beginning of the buffer. */
4212 *start = buffer;
4213 curbuf = buffer;
4214 advoffset = 0;
4215 totcnt = 0;
4216 leftlen = length;
4219 * Get board configuration information.
4221 * advansys_info() returns the board string from its own static buffer.
4223 cp = (char *)advansys_info(shost);
4224 strcat(cp, "\n");
4225 cplen = strlen(cp);
4226 /* Copy board information. */
4227 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4228 totcnt += cnt;
4229 leftlen -= cnt;
4230 if (leftlen == 0) {
4231 ASC_DBG(1, "totcnt %d\n", totcnt);
4232 return totcnt;
4234 advoffset += cplen;
4235 curbuf += cnt;
4238 * Display Wide Board BIOS Information.
4240 if (!ASC_NARROW_BOARD(boardp)) {
4241 cp = boardp->prtbuf;
4242 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
4243 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4244 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4245 cplen);
4246 totcnt += cnt;
4247 leftlen -= cnt;
4248 if (leftlen == 0) {
4249 ASC_DBG(1, "totcnt %d\n", totcnt);
4250 return totcnt;
4252 advoffset += cplen;
4253 curbuf += cnt;
4257 * Display driver information for each device attached to the board.
4259 cp = boardp->prtbuf;
4260 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
4261 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4262 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4263 totcnt += cnt;
4264 leftlen -= cnt;
4265 if (leftlen == 0) {
4266 ASC_DBG(1, "totcnt %d\n", totcnt);
4267 return totcnt;
4269 advoffset += cplen;
4270 curbuf += cnt;
4273 * Display EEPROM configuration for the board.
4275 cp = boardp->prtbuf;
4276 if (ASC_NARROW_BOARD(boardp)) {
4277 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4278 } else {
4279 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4281 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4282 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4283 totcnt += cnt;
4284 leftlen -= cnt;
4285 if (leftlen == 0) {
4286 ASC_DBG(1, "totcnt %d\n", totcnt);
4287 return totcnt;
4289 advoffset += cplen;
4290 curbuf += cnt;
4293 * Display driver configuration and information for the board.
4295 cp = boardp->prtbuf;
4296 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
4297 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4298 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4299 totcnt += cnt;
4300 leftlen -= cnt;
4301 if (leftlen == 0) {
4302 ASC_DBG(1, "totcnt %d\n", totcnt);
4303 return totcnt;
4305 advoffset += cplen;
4306 curbuf += cnt;
4308 #ifdef ADVANSYS_STATS
4310 * Display driver statistics for the board.
4312 cp = boardp->prtbuf;
4313 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
4314 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4315 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4316 totcnt += cnt;
4317 leftlen -= cnt;
4318 if (leftlen == 0) {
4319 ASC_DBG(1, "totcnt %d\n", totcnt);
4320 return totcnt;
4322 advoffset += cplen;
4323 curbuf += cnt;
4324 #endif /* ADVANSYS_STATS */
4327 * Display Asc Library dynamic configuration information
4328 * for the board.
4330 cp = boardp->prtbuf;
4331 if (ASC_NARROW_BOARD(boardp)) {
4332 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
4333 } else {
4334 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
4336 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4337 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4338 totcnt += cnt;
4339 leftlen -= cnt;
4340 if (leftlen == 0) {
4341 ASC_DBG(1, "totcnt %d\n", totcnt);
4342 return totcnt;
4344 advoffset += cplen;
4345 curbuf += cnt;
4347 ASC_DBG(1, "totcnt %d\n", totcnt);
4349 return totcnt;
4351 #endif /* CONFIG_PROC_FS */
4353 static void asc_scsi_done(struct scsi_cmnd *scp)
4355 struct asc_board *boardp = shost_priv(scp->device->host);
4357 if (scp->use_sg)
4358 dma_unmap_sg(boardp->dev,
4359 (struct scatterlist *)scp->request_buffer,
4360 scp->use_sg, scp->sc_data_direction);
4361 else if (scp->request_bufflen)
4362 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
4363 scp->request_bufflen, scp->sc_data_direction);
4365 ASC_STATS(scp->device->host, done);
4367 scp->scsi_done(scp);
4370 static void AscSetBank(PortAddr iop_base, uchar bank)
4372 uchar val;
4374 val = AscGetChipControl(iop_base) &
4376 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
4377 CC_CHIP_RESET));
4378 if (bank == 1) {
4379 val |= CC_BANK_ONE;
4380 } else if (bank == 2) {
4381 val |= CC_DIAG | CC_BANK_ONE;
4382 } else {
4383 val &= ~CC_BANK_ONE;
4385 AscSetChipControl(iop_base, val);
4386 return;
4389 static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
4391 AscSetBank(iop_base, 1);
4392 AscWriteChipIH(iop_base, ins_code);
4393 AscSetBank(iop_base, 0);
4394 return;
4397 static int AscStartChip(PortAddr iop_base)
4399 AscSetChipControl(iop_base, 0);
4400 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4401 return (0);
4403 return (1);
4406 static int AscStopChip(PortAddr iop_base)
4408 uchar cc_val;
4410 cc_val =
4411 AscGetChipControl(iop_base) &
4412 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
4413 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
4414 AscSetChipIH(iop_base, INS_HALT);
4415 AscSetChipIH(iop_base, INS_RFLAG_WTM);
4416 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
4417 return (0);
4419 return (1);
4422 static int AscIsChipHalted(PortAddr iop_base)
4424 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4425 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
4426 return (1);
4429 return (0);
4432 static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
4434 PortAddr iop_base;
4435 int i = 10;
4437 iop_base = asc_dvc->iop_base;
4438 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
4439 && (i-- > 0)) {
4440 mdelay(100);
4442 AscStopChip(iop_base);
4443 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
4444 udelay(60);
4445 AscSetChipIH(iop_base, INS_RFLAG_WTM);
4446 AscSetChipIH(iop_base, INS_HALT);
4447 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
4448 AscSetChipControl(iop_base, CC_HALT);
4449 mdelay(200);
4450 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
4451 AscSetChipStatus(iop_base, 0);
4452 return (AscIsChipHalted(iop_base));
4455 static int AscFindSignature(PortAddr iop_base)
4457 ushort sig_word;
4459 ASC_DBG(1, "AscGetChipSignatureByte(0x%x) 0x%x\n",
4460 iop_base, AscGetChipSignatureByte(iop_base));
4461 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
4462 ASC_DBG(1, "AscGetChipSignatureWord(0x%x) 0x%x\n",
4463 iop_base, AscGetChipSignatureWord(iop_base));
4464 sig_word = AscGetChipSignatureWord(iop_base);
4465 if ((sig_word == (ushort)ASC_1000_ID0W) ||
4466 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
4467 return (1);
4470 return (0);
4473 static void AscEnableInterrupt(PortAddr iop_base)
4475 ushort cfg;
4477 cfg = AscGetChipCfgLsw(iop_base);
4478 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
4479 return;
4482 static void AscDisableInterrupt(PortAddr iop_base)
4484 ushort cfg;
4486 cfg = AscGetChipCfgLsw(iop_base);
4487 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
4488 return;
4491 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
4493 unsigned char byte_data;
4494 unsigned short word_data;
4496 if (isodd_word(addr)) {
4497 AscSetChipLramAddr(iop_base, addr - 1);
4498 word_data = AscGetChipLramData(iop_base);
4499 byte_data = (word_data >> 8) & 0xFF;
4500 } else {
4501 AscSetChipLramAddr(iop_base, addr);
4502 word_data = AscGetChipLramData(iop_base);
4503 byte_data = word_data & 0xFF;
4505 return byte_data;
4508 static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
4510 ushort word_data;
4512 AscSetChipLramAddr(iop_base, addr);
4513 word_data = AscGetChipLramData(iop_base);
4514 return (word_data);
4517 #if CC_VERY_LONG_SG_LIST
4518 static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
4520 ushort val_low, val_high;
4521 ASC_DCNT dword_data;
4523 AscSetChipLramAddr(iop_base, addr);
4524 val_low = AscGetChipLramData(iop_base);
4525 val_high = AscGetChipLramData(iop_base);
4526 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
4527 return (dword_data);
4529 #endif /* CC_VERY_LONG_SG_LIST */
4531 static void
4532 AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
4534 int i;
4536 AscSetChipLramAddr(iop_base, s_addr);
4537 for (i = 0; i < words; i++) {
4538 AscSetChipLramData(iop_base, set_wval);
4542 static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
4544 AscSetChipLramAddr(iop_base, addr);
4545 AscSetChipLramData(iop_base, word_val);
4546 return;
4549 static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
4551 ushort word_data;
4553 if (isodd_word(addr)) {
4554 addr--;
4555 word_data = AscReadLramWord(iop_base, addr);
4556 word_data &= 0x00FF;
4557 word_data |= (((ushort)byte_val << 8) & 0xFF00);
4558 } else {
4559 word_data = AscReadLramWord(iop_base, addr);
4560 word_data &= 0xFF00;
4561 word_data |= ((ushort)byte_val & 0x00FF);
4563 AscWriteLramWord(iop_base, addr, word_data);
4564 return;
4568 * Copy 2 bytes to LRAM.
4570 * The source data is assumed to be in little-endian order in memory
4571 * and is maintained in little-endian order when written to LRAM.
4573 static void
4574 AscMemWordCopyPtrToLram(PortAddr iop_base,
4575 ushort s_addr, uchar *s_buffer, int words)
4577 int i;
4579 AscSetChipLramAddr(iop_base, s_addr);
4580 for (i = 0; i < 2 * words; i += 2) {
4582 * On a little-endian system the second argument below
4583 * produces a little-endian ushort which is written to
4584 * LRAM in little-endian order. On a big-endian system
4585 * the second argument produces a big-endian ushort which
4586 * is "transparently" byte-swapped by outpw() and written
4587 * in little-endian order to LRAM.
4589 outpw(iop_base + IOP_RAM_DATA,
4590 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
4592 return;
4596 * Copy 4 bytes to LRAM.
4598 * The source data is assumed to be in little-endian order in memory
4599 * and is maintained in little-endian order when writen to LRAM.
4601 static void
4602 AscMemDWordCopyPtrToLram(PortAddr iop_base,
4603 ushort s_addr, uchar *s_buffer, int dwords)
4605 int i;
4607 AscSetChipLramAddr(iop_base, s_addr);
4608 for (i = 0; i < 4 * dwords; i += 4) {
4609 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
4610 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
4612 return;
4616 * Copy 2 bytes from LRAM.
4618 * The source data is assumed to be in little-endian order in LRAM
4619 * and is maintained in little-endian order when written to memory.
4621 static void
4622 AscMemWordCopyPtrFromLram(PortAddr iop_base,
4623 ushort s_addr, uchar *d_buffer, int words)
4625 int i;
4626 ushort word;
4628 AscSetChipLramAddr(iop_base, s_addr);
4629 for (i = 0; i < 2 * words; i += 2) {
4630 word = inpw(iop_base + IOP_RAM_DATA);
4631 d_buffer[i] = word & 0xff;
4632 d_buffer[i + 1] = (word >> 8) & 0xff;
4634 return;
4637 static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
4639 ASC_DCNT sum;
4640 int i;
4642 sum = 0L;
4643 for (i = 0; i < words; i++, s_addr += 2) {
4644 sum += AscReadLramWord(iop_base, s_addr);
4646 return (sum);
4649 static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
4651 uchar i;
4652 ushort s_addr;
4653 PortAddr iop_base;
4654 ushort warn_code;
4656 iop_base = asc_dvc->iop_base;
4657 warn_code = 0;
4658 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
4659 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
4660 64) >> 1));
4661 i = ASC_MIN_ACTIVE_QNO;
4662 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
4663 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4664 (uchar)(i + 1));
4665 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4666 (uchar)(asc_dvc->max_total_qng));
4667 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4668 (uchar)i);
4669 i++;
4670 s_addr += ASC_QBLK_SIZE;
4671 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
4672 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4673 (uchar)(i + 1));
4674 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4675 (uchar)(i - 1));
4676 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4677 (uchar)i);
4679 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4680 (uchar)ASC_QLINK_END);
4681 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4682 (uchar)(asc_dvc->max_total_qng - 1));
4683 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4684 (uchar)asc_dvc->max_total_qng);
4685 i++;
4686 s_addr += ASC_QBLK_SIZE;
4687 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
4688 i++, s_addr += ASC_QBLK_SIZE) {
4689 AscWriteLramByte(iop_base,
4690 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
4691 AscWriteLramByte(iop_base,
4692 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
4693 AscWriteLramByte(iop_base,
4694 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
4696 return warn_code;
4699 static ASC_DCNT
4700 AscLoadMicroCode(PortAddr iop_base,
4701 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
4703 ASC_DCNT chksum;
4704 ushort mcode_word_size;
4705 ushort mcode_chksum;
4707 /* Write the microcode buffer starting at LRAM address 0. */
4708 mcode_word_size = (ushort)(mcode_size >> 1);
4709 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
4710 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
4712 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
4713 ASC_DBG(1, "chksum 0x%lx\n", (ulong)chksum);
4714 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
4715 (ushort)ASC_CODE_SEC_BEG,
4716 (ushort)((mcode_size -
4717 s_addr - (ushort)
4718 ASC_CODE_SEC_BEG) /
4719 2));
4720 ASC_DBG(1, "mcode_chksum 0x%lx\n", (ulong)mcode_chksum);
4721 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
4722 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
4723 return chksum;
4726 /* Microcode buffer is kept after initialization for error recovery. */
4727 static uchar _asc_mcode_buf[] = {
4728 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4729 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
4730 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4731 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4732 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4733 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05,
4734 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4735 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4736 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
4737 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
4738 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04,
4739 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
4740 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
4741 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98,
4742 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00,
4743 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
4744 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
4745 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23,
4746 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04,
4747 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
4748 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
4749 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88,
4750 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00,
4751 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
4752 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
4753 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01,
4754 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8,
4755 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
4756 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
4757 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01,
4758 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33,
4759 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
4760 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
4761 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
4762 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23,
4763 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
4764 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
4765 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
4766 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84,
4767 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
4768 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
4769 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
4770 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46,
4771 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
4772 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
4773 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02,
4774 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82,
4775 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
4776 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
4777 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02,
4778 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23,
4779 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
4780 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
4781 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01,
4782 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02,
4783 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
4784 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
4785 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01,
4786 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
4787 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
4788 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
4789 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39,
4790 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6,
4791 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
4792 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
4793 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42,
4794 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01,
4795 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
4796 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
4797 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33,
4798 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83,
4799 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
4800 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
4801 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83,
4802 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00,
4803 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
4804 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
4805 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42,
4806 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95,
4807 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
4808 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
4809 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32,
4810 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84,
4811 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
4812 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
4813 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95,
4814 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4,
4815 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
4816 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
4817 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84,
4818 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84,
4819 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
4820 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
4821 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2,
4822 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00,
4823 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
4824 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
4825 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04,
4826 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00,
4827 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
4828 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
4829 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE,
4830 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62,
4831 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
4832 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
4833 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC,
4834 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95,
4835 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
4836 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
4837 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01,
4838 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01,
4839 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
4840 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
4841 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01,
4842 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05,
4843 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
4844 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
4845 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85,
4846 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63,
4847 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
4848 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
4849 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85,
4850 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85,
4851 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
4852 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
4853 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23,
4854 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87,
4855 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
4856 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
4857 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33,
4858 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60,
4859 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
4860 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
4861 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA,
4862 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33,
4863 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
4864 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
4865 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67,
4866 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
4867 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
4868 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
4869 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6,
4870 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06,
4871 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
4872 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
4873 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03,
4874 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33,
4875 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
4876 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
4877 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B,
4878 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88,
4879 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
4880 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
4881 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07,
4882 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84,
4883 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
4884 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
4885 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04,
4886 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00,
4887 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
4888 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
4889 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01,
4890 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04,
4891 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
4892 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
4893 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05,
4894 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23,
4895 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
4896 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
4897 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
4898 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
4899 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
4900 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
4901 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43,
4902 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01,
4903 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
4904 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
4905 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95,
4906 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88,
4907 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
4908 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
4909 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09,
4910 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32,
4911 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
4912 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
4913 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
4914 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73,
4915 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
4916 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
4917 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77,
4918 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23,
4919 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
4922 static unsigned short _asc_mcode_size = sizeof(_asc_mcode_buf);
4923 static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
4925 /* Microcode buffer is kept after initialization for error recovery. */
4926 static unsigned char _adv_asc3550_buf[] = {
4927 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
4928 0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00,
4929 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7,
4930 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
4931 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
4932 0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54,
4933 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01,
4934 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
4935 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
4936 0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
4937 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
4938 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
4939 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
4940 0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
4941 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a,
4942 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
4943 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
4944 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00,
4945 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c,
4946 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
4947 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
4948 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10,
4949 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56,
4950 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
4951 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
4952 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00,
4953 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10,
4954 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
4955 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
4956 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55,
4957 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0,
4958 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
4959 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
4960 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01,
4961 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02,
4962 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
4963 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
4964 0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13,
4965 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18,
4966 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
4967 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
4968 0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90,
4969 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10,
4970 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
4971 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
4972 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00,
4973 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
4974 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
4975 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
4976 0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe,
4977 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02,
4978 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
4979 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
4980 0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe,
4981 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
4982 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
4983 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
4984 0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02,
4985 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02,
4986 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
4987 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
4988 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10,
4989 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d,
4990 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
4991 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
4992 0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0,
4993 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe,
4994 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
4995 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
4996 0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d,
4997 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a,
4998 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
4999 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
5000 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03,
5001 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe,
5002 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
5003 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
5004 0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0,
5005 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f,
5006 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
5007 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
5008 0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2,
5009 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11,
5010 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
5011 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
5012 0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe,
5013 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1,
5014 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
5015 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
5016 0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28,
5017 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02,
5018 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
5019 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
5020 0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04,
5021 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe,
5022 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
5023 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
5024 0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c,
5025 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe,
5026 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
5027 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
5028 0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90,
5029 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67,
5030 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
5031 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
5032 0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2,
5033 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04,
5034 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
5035 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
5036 0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05,
5037 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1,
5038 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
5039 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
5040 0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d,
5041 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b,
5042 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
5043 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
5044 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19,
5045 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05,
5046 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
5047 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
5048 0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48,
5049 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d,
5050 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
5051 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
5052 0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4,
5053 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87,
5054 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
5055 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
5056 0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a,
5057 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
5058 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
5059 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
5060 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
5061 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02,
5062 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
5063 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
5064 0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25,
5065 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c,
5066 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
5067 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
5068 0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a,
5069 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80,
5070 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
5071 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
5072 0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
5073 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52,
5074 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
5075 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
5076 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18,
5077 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58,
5078 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
5079 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
5080 0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35,
5081 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0,
5082 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
5083 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
5084 0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10,
5085 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61,
5086 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
5087 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
5088 0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe,
5089 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10,
5090 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
5091 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
5092 0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
5093 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d,
5094 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
5095 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
5096 0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01,
5097 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02,
5098 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
5099 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
5100 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
5101 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77,
5102 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
5103 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
5104 0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05,
5105 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56,
5106 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
5107 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
5108 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59,
5109 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00,
5110 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
5111 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
5112 0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a,
5113 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d,
5114 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
5115 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
5116 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe,
5117 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51,
5118 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
5119 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
5120 0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00,
5121 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33,
5122 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
5123 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
5124 0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe,
5125 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93,
5126 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
5127 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
5128 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0,
5129 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9,
5130 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
5131 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
5132 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd,
5133 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f,
5134 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
5135 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
5136 0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54,
5137 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01,
5138 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
5139 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
5140 0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e,
5141 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01,
5142 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
5143 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
5144 0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02,
5145 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe,
5146 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
5147 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
5148 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35,
5149 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f,
5150 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
5151 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
5152 0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b,
5153 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea,
5154 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
5155 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
5156 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47,
5157 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38,
5158 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
5159 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
5160 0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe,
5161 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce,
5162 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
5163 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
5164 0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe,
5165 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe,
5166 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
5167 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
5168 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4,
5169 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe,
5170 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
5171 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
5172 0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11,
5173 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12,
5174 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
5175 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
5176 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc,
5177 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23,
5178 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
5179 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
5180 0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe,
5181 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
5182 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
5183 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
5184 0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01,
5185 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
5186 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
5187 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
5188 0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76,
5189 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
5190 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
5191 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
5192 0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48,
5193 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08,
5194 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
5195 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
5196 0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0,
5197 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
5198 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
5199 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
5200 0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a,
5201 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
5202 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
5203 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
5204 0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03,
5205 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe,
5206 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
5207 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
5208 0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30,
5209 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16,
5210 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
5211 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
5212 0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01,
5213 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe,
5214 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
5215 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
5216 0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77,
5217 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c,
5218 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
5219 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
5220 0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40,
5221 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1,
5222 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
5223 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
5224 0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe,
5225 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
5226 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
5227 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
5228 0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5,
5229 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c,
5230 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
5231 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
5232 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19,
5233 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e,
5234 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
5235 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
5236 0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49,
5237 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f,
5238 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
5239 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
5240 0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe,
5241 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c,
5242 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
5243 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
5244 0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14,
5245 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a,
5246 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
5247 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
5248 0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe,
5249 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc,
5250 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
5251 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
5252 0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13,
5253 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56,
5254 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
5255 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
5256 0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c,
5257 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00,
5258 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
5259 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
5260 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01,
5261 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f,
5262 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
5263 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
5264 0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2,
5265 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78,
5266 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
5267 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
5268 0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00,
5269 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28,
5270 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
5271 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
5272 0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4,
5273 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe,
5274 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
5275 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
5276 0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe,
5277 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23,
5278 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
5279 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
5280 0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26,
5281 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08,
5282 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
5283 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
5284 0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44,
5285 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e,
5286 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
5287 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
5288 0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03,
5289 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01,
5290 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
5291 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
5292 0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03,
5293 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10,
5294 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
5295 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
5296 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01,
5297 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f,
5298 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
5299 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
5300 0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90,
5301 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe,
5302 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
5303 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
5304 0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
5305 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10,
5306 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
5307 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
5308 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f,
5309 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14,
5310 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
5311 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
5312 0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe,
5313 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe,
5314 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
5315 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
5316 0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17,
5317 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71,
5318 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
5319 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
5320 0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0,
5321 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
5322 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
5323 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
5324 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c,
5325 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17,
5326 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
5327 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
5328 0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73,
5329 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e,
5330 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
5331 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
5332 0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18,
5333 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2,
5334 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
5335 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
5336 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe,
5337 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12,
5338 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
5339 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
5340 0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26,
5341 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93,
5342 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
5343 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
5344 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
5345 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
5348 static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
5349 static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
5351 /* Microcode buffer is kept after initialization for error recovery. */
5352 static unsigned char _adv_asc38C0800_buf[] = {
5353 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
5354 0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19,
5355 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00,
5356 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
5357 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
5358 0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0,
5359 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc,
5360 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
5361 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
5362 0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc,
5363 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54,
5364 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
5365 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
5366 0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80,
5367 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00,
5368 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
5369 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
5370 0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0,
5371 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01,
5372 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
5373 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
5374 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
5375 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11,
5376 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
5377 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
5378 0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc,
5379 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00,
5380 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
5381 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
5382 0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17,
5383 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44,
5384 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
5385 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
5386 0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00,
5387 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00,
5388 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
5389 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
5390 0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f,
5391 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12,
5392 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
5393 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
5394 0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
5395 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10,
5396 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
5397 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
5398 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00,
5399 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5400 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
5401 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
5402 0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe,
5403 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06,
5404 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
5405 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
5406 0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe,
5407 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
5408 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
5409 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
5410 0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02,
5411 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02,
5412 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
5413 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
5414 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10,
5415 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59,
5416 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
5417 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
5418 0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0,
5419 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe,
5420 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
5421 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
5422 0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43,
5423 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54,
5424 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
5425 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
5426 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe,
5427 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02,
5428 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
5429 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
5430 0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe,
5431 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10,
5432 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
5433 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
5434 0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78,
5435 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9,
5436 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
5437 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
5438 0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a,
5439 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d,
5440 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
5441 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
5442 0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda,
5443 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28,
5444 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
5445 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
5446 0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
5447 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04,
5448 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
5449 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
5450 0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62,
5451 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52,
5452 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
5453 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
5454 0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe,
5455 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00,
5456 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
5457 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
5458 0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf,
5459 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08,
5460 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
5461 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
5462 0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe,
5463 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff,
5464 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
5465 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
5466 0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05,
5467 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab,
5468 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
5469 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
5470 0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39,
5471 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2,
5472 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
5473 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
5474 0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18,
5475 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe,
5476 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
5477 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
5478 0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01,
5479 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02,
5480 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
5481 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
5482 0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12,
5483 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2,
5484 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
5485 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
5486 0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05,
5487 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
5488 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
5489 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
5490 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01,
5491 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
5492 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
5493 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
5494 0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d,
5495 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0,
5496 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
5497 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
5498 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14,
5499 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12,
5500 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
5501 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
5502 0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe,
5503 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88,
5504 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
5505 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
5506 0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe,
5507 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b,
5508 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
5509 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
5510 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d,
5511 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08,
5512 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
5513 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
5514 0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06,
5515 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9,
5516 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
5517 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
5518 0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a,
5519 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09,
5520 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
5521 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
5522 0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58,
5523 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe,
5524 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
5525 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
5526 0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe,
5527 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76,
5528 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
5529 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
5530 0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10,
5531 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a,
5532 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
5533 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
5534 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f,
5535 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18,
5536 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
5537 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
5538 0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a,
5539 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09,
5540 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
5541 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
5542 0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a,
5543 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d,
5544 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
5545 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
5546 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe,
5547 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe,
5548 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
5549 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
5550 0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8,
5551 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40,
5552 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
5553 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
5554 0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05,
5555 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe,
5556 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
5557 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
5558 0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32,
5559 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe,
5560 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
5561 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
5562 0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
5563 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe,
5564 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
5565 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
5566 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6,
5567 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe,
5568 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
5569 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
5570 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd,
5571 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb,
5572 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
5573 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
5574 0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05,
5575 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27,
5576 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
5577 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
5578 0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6,
5579 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00,
5580 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
5581 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
5582 0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c,
5583 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe,
5584 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
5585 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
5586 0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09,
5587 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b,
5588 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
5589 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
5590 0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96,
5591 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f,
5592 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
5593 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
5594 0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c,
5595 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
5596 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
5597 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
5598 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41,
5599 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70,
5600 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
5601 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
5602 0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02,
5603 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45,
5604 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
5605 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
5606 0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09,
5607 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe,
5608 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
5609 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
5610 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe,
5611 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41,
5612 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
5613 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
5614 0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00,
5615 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
5616 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
5617 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
5618 0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01,
5619 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01,
5620 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
5621 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
5622 0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24,
5623 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03,
5624 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
5625 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
5626 0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05,
5627 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
5628 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
5629 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
5630 0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f,
5631 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01,
5632 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
5633 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
5634 0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe,
5635 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
5636 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
5637 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
5638 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe,
5639 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
5640 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
5641 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
5642 0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe,
5643 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22,
5644 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
5645 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
5646 0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b,
5647 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f,
5648 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
5649 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
5650 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe,
5651 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe,
5652 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
5653 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
5654 0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe,
5655 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7,
5656 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
5657 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
5658 0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17,
5659 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24,
5660 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
5661 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
5662 0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe,
5663 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c,
5664 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
5665 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
5666 0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01,
5667 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe,
5668 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
5669 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
5670 0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe,
5671 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a,
5672 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
5673 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
5674 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe,
5675 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50,
5676 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
5677 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
5678 0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a,
5679 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d,
5680 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
5681 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
5682 0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a,
5683 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf,
5684 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
5685 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
5686 0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06,
5687 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee,
5688 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
5689 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
5690 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01,
5691 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33,
5692 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
5693 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
5694 0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1,
5695 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15,
5696 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
5697 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
5698 0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01,
5699 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
5700 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
5701 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
5702 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
5703 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58,
5704 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
5705 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
5706 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c,
5707 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd,
5708 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
5709 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
5710 0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15,
5711 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe,
5712 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
5713 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
5714 0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83,
5715 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d,
5716 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
5717 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
5718 0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2,
5719 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90,
5720 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
5721 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
5722 0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e,
5723 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90,
5724 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
5725 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
5726 0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
5727 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16,
5728 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
5729 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
5730 0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
5731 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01,
5732 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
5733 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
5734 0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27,
5735 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d,
5736 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
5737 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
5738 0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8,
5739 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11,
5740 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
5741 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
5742 0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01,
5743 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75,
5744 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
5745 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
5746 0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04,
5747 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03,
5748 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
5749 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
5750 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79,
5751 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35,
5752 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
5753 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
5754 0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c,
5755 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe,
5756 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
5757 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
5758 0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23,
5759 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe,
5760 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
5761 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
5762 0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7,
5763 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04,
5764 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
5765 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
5766 0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2,
5767 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32,
5768 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
5769 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
5770 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11,
5771 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16,
5772 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
5773 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
5774 0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18,
5775 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73,
5776 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
5777 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
5778 0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46,
5779 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04,
5780 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
5781 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
5782 0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10,
5783 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00,
5784 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
5785 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
5786 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e,
5787 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08,
5788 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
5789 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
5790 0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09,
5791 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19,
5792 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
5793 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
5794 0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe,
5795 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0,
5796 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
5797 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
5800 static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
5801 static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
5803 /* Microcode buffer is kept after initialization for error recovery. */
5804 static unsigned char _adv_asc38C1600_buf[] = {
5805 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
5806 0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13,
5807 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff,
5808 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
5809 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
5810 0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4,
5811 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e,
5812 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
5813 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
5814 0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc,
5815 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12,
5816 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
5817 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
5818 0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4,
5819 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01,
5820 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
5821 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
5822 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
5823 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10,
5824 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
5825 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
5826 0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12,
5827 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c,
5828 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
5829 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
5830 0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00,
5831 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10,
5832 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
5833 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
5834 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7,
5835 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00,
5836 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
5837 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
5838 0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46,
5839 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6,
5840 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
5841 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
5842 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01,
5843 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01,
5844 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
5845 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
5846 0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13,
5847 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10,
5848 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
5849 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
5850 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00,
5851 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5852 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
5853 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
5854 0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe,
5855 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c,
5856 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
5857 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
5858 0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05,
5859 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1,
5860 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
5861 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
5862 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60,
5863 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52,
5864 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
5865 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
5866 0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7,
5867 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f,
5868 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
5869 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
5870 0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d,
5871 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe,
5872 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
5873 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
5874 0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec,
5875 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde,
5876 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
5877 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
5878 0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41,
5879 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03,
5880 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
5881 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
5882 0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40,
5883 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0,
5884 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
5885 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
5886 0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28,
5887 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01,
5888 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
5889 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
5890 0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe,
5891 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0,
5892 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
5893 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
5894 0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf,
5895 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a,
5896 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
5897 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
5898 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29,
5899 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00,
5900 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
5901 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
5902 0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13,
5903 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e,
5904 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
5905 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
5906 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe,
5907 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43,
5908 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
5909 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
5910 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe,
5911 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f,
5912 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
5913 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
5914 0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c,
5915 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0,
5916 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
5917 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
5918 0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe,
5919 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f,
5920 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
5921 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
5922 0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba,
5923 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2,
5924 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
5925 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
5926 0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27,
5927 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f,
5928 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
5929 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
5930 0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13,
5931 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06,
5932 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
5933 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
5934 0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13,
5935 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe,
5936 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
5937 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
5938 0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01,
5939 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15,
5940 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
5941 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
5942 0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01,
5943 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95,
5944 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
5945 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
5946 0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe,
5947 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21,
5948 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
5949 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
5950 0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00,
5951 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe,
5952 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
5953 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
5954 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe,
5955 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76,
5956 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
5957 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
5958 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00,
5959 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe,
5960 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
5961 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
5962 0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c,
5963 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08,
5964 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
5965 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
5966 0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe,
5967 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21,
5968 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
5969 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
5970 0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20,
5971 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
5972 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
5973 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
5974 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b,
5975 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12,
5976 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
5977 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
5978 0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90,
5979 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6,
5980 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
5981 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
5982 0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2,
5983 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34,
5984 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
5985 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
5986 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a,
5987 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a,
5988 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
5989 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
5990 0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d,
5991 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76,
5992 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
5993 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
5994 0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe,
5995 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b,
5996 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
5997 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
5998 0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5,
5999 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe,
6000 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
6001 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
6002 0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05,
6003 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06,
6004 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
6005 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
6006 0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42,
6007 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57,
6008 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
6009 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
6010 0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01,
6011 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c,
6012 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
6013 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
6014 0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06,
6015 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7,
6016 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
6017 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
6018 0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe,
6019 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a,
6020 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
6021 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
6022 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e,
6023 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26,
6024 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
6025 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
6026 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef,
6027 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe,
6028 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
6029 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
6030 0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18,
6031 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe,
6032 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
6033 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
6034 0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe,
6035 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe,
6036 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
6037 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
6038 0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12,
6039 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e,
6040 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
6041 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
6042 0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0,
6043 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41,
6044 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
6045 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
6046 0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01,
6047 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81,
6048 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
6049 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
6050 0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe,
6051 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00,
6052 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
6053 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
6054 0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f,
6055 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e,
6056 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
6057 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
6058 0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01,
6059 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d,
6060 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
6061 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
6062 0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
6063 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19,
6064 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
6065 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
6066 0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75,
6067 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d,
6068 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
6069 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
6070 0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e,
6071 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0,
6072 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
6073 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
6074 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe,
6075 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe,
6076 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
6077 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
6078 0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12,
6079 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe,
6080 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
6081 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
6082 0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe,
6083 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec,
6084 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
6085 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
6086 0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3,
6087 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10,
6088 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
6089 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
6090 0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13,
6091 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc,
6092 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
6093 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
6094 0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06,
6095 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83,
6096 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
6097 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
6098 0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c,
6099 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe,
6100 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
6101 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
6102 0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01,
6103 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01,
6104 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
6105 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
6106 0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64,
6107 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe,
6108 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
6109 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
6110 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03,
6111 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07,
6112 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
6113 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
6114 0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe,
6115 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13,
6116 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
6117 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
6118 0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
6119 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10,
6120 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
6121 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
6122 0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
6123 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01,
6124 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
6125 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
6126 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85,
6127 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec,
6128 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
6129 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
6130 0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee,
6131 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d,
6132 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
6133 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
6134 0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42,
6135 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a,
6136 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
6137 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
6138 0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34,
6139 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e,
6140 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
6141 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
6142 0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
6143 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa,
6144 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
6145 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
6146 0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56,
6147 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9,
6148 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
6149 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
6150 0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03,
6151 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e,
6152 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
6153 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
6154 0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13,
6155 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9,
6156 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
6157 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
6158 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d,
6159 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a,
6160 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
6161 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
6162 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45,
6163 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01,
6164 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
6165 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
6166 0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66,
6167 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56,
6168 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
6169 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
6170 0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe,
6171 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05,
6172 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
6173 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
6174 0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b,
6175 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d,
6176 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
6177 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
6178 0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17,
6179 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe,
6180 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
6181 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
6182 0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02,
6183 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30,
6184 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
6185 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
6186 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58,
6187 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01,
6188 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
6189 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
6190 0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a,
6191 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00,
6192 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
6193 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
6194 0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16,
6195 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17,
6196 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
6197 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
6198 0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d,
6199 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04,
6200 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
6201 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
6202 0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16,
6203 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64,
6204 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
6205 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
6206 0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe,
6207 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe,
6208 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
6209 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
6210 0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe,
6211 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7,
6212 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
6213 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
6214 0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9,
6215 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe,
6216 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
6217 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
6218 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01,
6219 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2,
6220 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
6221 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
6222 0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18,
6223 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe,
6224 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
6225 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
6226 0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe,
6227 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10,
6228 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
6229 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
6230 0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe,
6231 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4,
6232 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
6233 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
6234 0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01,
6235 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e,
6236 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
6237 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
6238 0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f,
6239 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
6240 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
6241 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
6242 0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f,
6243 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89,
6244 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
6245 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
6246 0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c,
6247 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e,
6248 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
6249 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
6250 0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09,
6251 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18,
6252 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
6253 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
6254 0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe,
6255 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01,
6256 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
6257 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
6258 0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c,
6259 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d,
6260 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
6261 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
6262 0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01,
6263 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe,
6264 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
6265 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
6266 0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9,
6267 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83,
6268 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
6269 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
6270 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b,
6271 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04,
6272 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
6273 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
6274 0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6,
6275 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c,
6276 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
6277 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
6278 0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83,
6279 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a,
6280 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
6281 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
6282 0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13,
6283 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1,
6284 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
6285 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
6286 0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48,
6287 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f,
6288 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
6289 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
6290 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d,
6291 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30,
6292 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
6293 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
6294 0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31,
6295 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba,
6296 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
6297 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
6298 0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89,
6299 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90,
6300 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
6301 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
6302 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe,
6303 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1,
6304 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
6305 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
6306 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa,
6307 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d,
6308 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
6309 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
6310 0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e,
6311 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99,
6312 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
6313 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
6314 0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80,
6315 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98,
6316 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
6317 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
6318 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b,
6319 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84,
6320 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
6321 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
6322 0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06,
6323 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f,
6324 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6325 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6326 0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6327 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6328 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6329 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6330 0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b,
6331 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e,
6332 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
6335 static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
6336 static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
6338 static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
6340 PortAddr iop_base;
6341 int i;
6342 ushort lram_addr;
6344 iop_base = asc_dvc->iop_base;
6345 AscPutRiscVarFreeQHead(iop_base, 1);
6346 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6347 AscPutVarFreeQHead(iop_base, 1);
6348 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6349 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
6350 (uchar)((int)asc_dvc->max_total_qng + 1));
6351 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
6352 (uchar)((int)asc_dvc->max_total_qng + 2));
6353 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
6354 asc_dvc->max_total_qng);
6355 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
6356 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6357 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
6358 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
6359 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
6360 AscPutQDoneInProgress(iop_base, 0);
6361 lram_addr = ASC_QADR_BEG;
6362 for (i = 0; i < 32; i++, lram_addr += 2) {
6363 AscWriteLramWord(iop_base, lram_addr, 0);
6367 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
6369 int i;
6370 ushort warn_code;
6371 PortAddr iop_base;
6372 ASC_PADDR phy_addr;
6373 ASC_DCNT phy_size;
6375 iop_base = asc_dvc->iop_base;
6376 warn_code = 0;
6377 for (i = 0; i <= ASC_MAX_TID; i++) {
6378 AscPutMCodeInitSDTRAtID(iop_base, i,
6379 asc_dvc->cfg->sdtr_period_offset[i]);
6382 AscInitQLinkVar(asc_dvc);
6383 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
6384 asc_dvc->cfg->disc_enable);
6385 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
6386 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
6388 /* Align overrun buffer on an 8 byte boundary. */
6389 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
6390 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
6391 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
6392 (uchar *)&phy_addr, 1);
6393 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
6394 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
6395 (uchar *)&phy_size, 1);
6397 asc_dvc->cfg->mcode_date =
6398 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
6399 asc_dvc->cfg->mcode_version =
6400 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
6402 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
6403 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
6404 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
6405 return warn_code;
6407 if (AscStartChip(iop_base) != 1) {
6408 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
6409 return warn_code;
6412 return warn_code;
6415 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
6417 ushort warn_code;
6418 PortAddr iop_base;
6420 iop_base = asc_dvc->iop_base;
6421 warn_code = 0;
6422 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
6423 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
6424 AscResetChipAndScsiBus(asc_dvc);
6425 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
6427 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
6428 if (asc_dvc->err_code != 0)
6429 return UW_ERR;
6430 if (!AscFindSignature(asc_dvc->iop_base)) {
6431 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
6432 return warn_code;
6434 AscDisableInterrupt(iop_base);
6435 warn_code |= AscInitLram(asc_dvc);
6436 if (asc_dvc->err_code != 0)
6437 return UW_ERR;
6438 ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)_asc_mcode_chksum);
6439 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
6440 _asc_mcode_size) != _asc_mcode_chksum) {
6441 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
6442 return warn_code;
6444 warn_code |= AscInitMicroCodeVar(asc_dvc);
6445 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
6446 AscEnableInterrupt(iop_base);
6447 return warn_code;
6451 * Load the Microcode
6453 * Write the microcode image to RISC memory starting at address 0.
6455 * The microcode is stored compressed in the following format:
6457 * 254 word (508 byte) table indexed by byte code followed
6458 * by the following byte codes:
6460 * 1-Byte Code:
6461 * 00: Emit word 0 in table.
6462 * 01: Emit word 1 in table.
6464 * FD: Emit word 253 in table.
6466 * Multi-Byte Code:
6467 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
6468 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
6470 * Returns 0 or an error if the checksum doesn't match
6472 static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
6473 int memsize, int chksum)
6475 int i, j, end, len = 0;
6476 ADV_DCNT sum;
6478 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6480 for (i = 253 * 2; i < size; i++) {
6481 if (buf[i] == 0xff) {
6482 unsigned short word = (buf[i + 3] << 8) | buf[i + 2];
6483 for (j = 0; j < buf[i + 1]; j++) {
6484 AdvWriteWordAutoIncLram(iop_base, word);
6485 len += 2;
6487 i += 3;
6488 } else if (buf[i] == 0xfe) {
6489 unsigned short word = (buf[i + 2] << 8) | buf[i + 1];
6490 AdvWriteWordAutoIncLram(iop_base, word);
6491 i += 2;
6492 len += 2;
6493 } else {
6494 unsigned char off = buf[i] * 2;
6495 unsigned short word = (buf[off + 1] << 8) | buf[off];
6496 AdvWriteWordAutoIncLram(iop_base, word);
6497 len += 2;
6501 end = len;
6503 while (len < memsize) {
6504 AdvWriteWordAutoIncLram(iop_base, 0);
6505 len += 2;
6508 /* Verify the microcode checksum. */
6509 sum = 0;
6510 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6512 for (len = 0; len < end; len += 2) {
6513 sum += AdvReadWordAutoIncLram(iop_base);
6516 if (sum != chksum)
6517 return ASC_IERR_MCODE_CHKSUM;
6519 return 0;
6523 * DvcGetPhyAddr()
6525 * Return the physical address of 'vaddr' and set '*lenp' to the
6526 * number of physically contiguous bytes that follow 'vaddr'.
6527 * 'flag' indicates the type of structure whose physical address
6528 * is being translated.
6530 * Note: Because Linux currently doesn't page the kernel and all
6531 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
6533 ADV_PADDR
6534 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
6535 uchar *vaddr, ADV_SDCNT *lenp, int flag)
6537 ADV_PADDR paddr = virt_to_bus(vaddr);
6539 ASC_DBG(4, "vaddr 0x%p, lenp 0x%p *lenp %lu, paddr 0x%lx\n",
6540 vaddr, lenp, (ulong)*((ulong *)lenp), (ulong)paddr);
6542 return paddr;
6545 static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
6547 ADV_CARR_T *carrp;
6548 ADV_SDCNT buf_size;
6549 ADV_PADDR carr_paddr;
6551 BUG_ON(!asc_dvc->carrier_buf);
6553 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
6554 asc_dvc->carr_freelist = NULL;
6555 if (carrp == asc_dvc->carrier_buf) {
6556 buf_size = ADV_CARRIER_BUFSIZE;
6557 } else {
6558 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
6561 do {
6562 /* Get physical address of the carrier 'carrp'. */
6563 ADV_DCNT contig_len = sizeof(ADV_CARR_T);
6564 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL,
6565 (uchar *)carrp,
6566 (ADV_SDCNT *)&contig_len,
6567 ADV_IS_CARRIER_FLAG));
6569 buf_size -= sizeof(ADV_CARR_T);
6572 * If the current carrier is not physically contiguous, then
6573 * maybe there was a page crossing. Try the next carrier
6574 * aligned start address.
6576 if (contig_len < sizeof(ADV_CARR_T)) {
6577 carrp++;
6578 continue;
6581 carrp->carr_pa = carr_paddr;
6582 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
6585 * Insert the carrier at the beginning of the freelist.
6587 carrp->next_vpa =
6588 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
6589 asc_dvc->carr_freelist = carrp;
6591 carrp++;
6592 } while (buf_size > 0);
6596 * Send an idle command to the chip and wait for completion.
6598 * Command completion is polled for once per microsecond.
6600 * The function can be called from anywhere including an interrupt handler.
6601 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
6602 * functions to prevent reentrancy.
6604 * Return Values:
6605 * ADV_TRUE - command completed successfully
6606 * ADV_FALSE - command failed
6607 * ADV_ERROR - command timed out
6609 static int
6610 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
6611 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
6613 int result;
6614 ADV_DCNT i, j;
6615 AdvPortAddr iop_base;
6617 iop_base = asc_dvc->iop_base;
6620 * Clear the idle command status which is set by the microcode
6621 * to a non-zero value to indicate when the command is completed.
6622 * The non-zero result is one of the IDLE_CMD_STATUS_* values
6624 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
6627 * Write the idle command value after the idle command parameter
6628 * has been written to avoid a race condition. If the order is not
6629 * followed, the microcode may process the idle command before the
6630 * parameters have been written to LRAM.
6632 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
6633 cpu_to_le32(idle_cmd_parameter));
6634 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
6637 * Tickle the RISC to tell it to process the idle command.
6639 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
6640 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
6642 * Clear the tickle value. In the ASC-3550 the RISC flag
6643 * command 'clr_tickle_b' does not work unless the host
6644 * value is cleared.
6646 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
6649 /* Wait for up to 100 millisecond for the idle command to timeout. */
6650 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
6651 /* Poll once each microsecond for command completion. */
6652 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
6653 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
6654 result);
6655 if (result != 0)
6656 return result;
6657 udelay(1);
6661 BUG(); /* The idle command should never timeout. */
6662 return ADV_ERROR;
6666 * Reset SCSI Bus and purge all outstanding requests.
6668 * Return Value:
6669 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
6670 * ADV_FALSE(0) - Microcode command failed.
6671 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
6672 * may be hung which requires driver recovery.
6674 static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
6676 int status;
6679 * Send the SCSI Bus Reset idle start idle command which asserts
6680 * the SCSI Bus Reset signal.
6682 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
6683 if (status != ADV_TRUE) {
6684 return status;
6688 * Delay for the specified SCSI Bus Reset hold time.
6690 * The hold time delay is done on the host because the RISC has no
6691 * microsecond accurate timer.
6693 udelay(ASC_SCSI_RESET_HOLD_TIME_US);
6696 * Send the SCSI Bus Reset end idle command which de-asserts
6697 * the SCSI Bus Reset signal and purges any pending requests.
6699 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
6700 if (status != ADV_TRUE) {
6701 return status;
6704 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
6706 return status;
6710 * Initialize the ASC-3550.
6712 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
6714 * For a non-fatal error return a warning code. If there are no warnings
6715 * then 0 is returned.
6717 * Needed after initialization for error recovery.
6719 static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
6721 AdvPortAddr iop_base;
6722 ushort warn_code;
6723 int begin_addr;
6724 int end_addr;
6725 ushort code_sum;
6726 int word;
6727 int i;
6728 ushort scsi_cfg1;
6729 uchar tid;
6730 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
6731 ushort wdtr_able = 0, sdtr_able, tagqng_able;
6732 uchar max_cmd[ADV_MAX_TID + 1];
6734 /* If there is already an error, don't continue. */
6735 if (asc_dvc->err_code != 0)
6736 return ADV_ERROR;
6739 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
6741 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
6742 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
6743 return ADV_ERROR;
6746 warn_code = 0;
6747 iop_base = asc_dvc->iop_base;
6750 * Save the RISC memory BIOS region before writing the microcode.
6751 * The BIOS may already be loaded and using its RISC LRAM region
6752 * so its region must be saved and restored.
6754 * Note: This code makes the assumption, which is currently true,
6755 * that a chip reset does not clear RISC LRAM.
6757 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6758 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6759 bios_mem[i]);
6763 * Save current per TID negotiated values.
6765 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
6766 ushort bios_version, major, minor;
6768 bios_version =
6769 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
6770 major = (bios_version >> 12) & 0xF;
6771 minor = (bios_version >> 8) & 0xF;
6772 if (major < 3 || (major == 3 && minor == 1)) {
6773 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
6774 AdvReadWordLram(iop_base, 0x120, wdtr_able);
6775 } else {
6776 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
6779 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
6780 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6781 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
6782 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
6783 max_cmd[tid]);
6786 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf,
6787 _adv_asc3550_size, ADV_3550_MEMSIZE,
6788 _adv_asc3550_chksum);
6789 if (asc_dvc->err_code)
6790 return ADV_ERROR;
6793 * Restore the RISC memory BIOS region.
6795 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6796 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6797 bios_mem[i]);
6801 * Calculate and write the microcode code checksum to the microcode
6802 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
6804 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
6805 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
6806 code_sum = 0;
6807 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
6808 for (word = begin_addr; word < end_addr; word += 2) {
6809 code_sum += AdvReadWordAutoIncLram(iop_base);
6811 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
6814 * Read and save microcode version and date.
6816 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
6817 asc_dvc->cfg->mcode_date);
6818 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
6819 asc_dvc->cfg->mcode_version);
6822 * Set the chip type to indicate the ASC3550.
6824 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
6827 * If the PCI Configuration Command Register "Parity Error Response
6828 * Control" Bit was clear (0), then set the microcode variable
6829 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
6830 * to ignore DMA parity errors.
6832 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
6833 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
6834 word |= CONTROL_FLAG_IGNORE_PERR;
6835 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
6839 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
6840 * threshold of 128 bytes. This register is only accessible to the host.
6842 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
6843 START_CTL_EMFU | READ_CMD_MRM);
6846 * Microcode operating variables for WDTR, SDTR, and command tag
6847 * queuing will be set in slave_configure() based on what a
6848 * device reports it is capable of in Inquiry byte 7.
6850 * If SCSI Bus Resets have been disabled, then directly set
6851 * SDTR and WDTR from the EEPROM configuration. This will allow
6852 * the BIOS and warm boot to work without a SCSI bus hang on
6853 * the Inquiry caused by host and target mismatched DTR values.
6854 * Without the SCSI Bus Reset, before an Inquiry a device can't
6855 * be assumed to be in Asynchronous, Narrow mode.
6857 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
6858 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
6859 asc_dvc->wdtr_able);
6860 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
6861 asc_dvc->sdtr_able);
6865 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
6866 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
6867 * bitmask. These values determine the maximum SDTR speed negotiated
6868 * with a device.
6870 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
6871 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
6872 * without determining here whether the device supports SDTR.
6874 * 4-bit speed SDTR speed name
6875 * =========== ===============
6876 * 0000b (0x0) SDTR disabled
6877 * 0001b (0x1) 5 Mhz
6878 * 0010b (0x2) 10 Mhz
6879 * 0011b (0x3) 20 Mhz (Ultra)
6880 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
6881 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
6882 * 0110b (0x6) Undefined
6884 * 1111b (0xF) Undefined
6886 word = 0;
6887 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
6888 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
6889 /* Set Ultra speed for TID 'tid'. */
6890 word |= (0x3 << (4 * (tid % 4)));
6891 } else {
6892 /* Set Fast speed for TID 'tid'. */
6893 word |= (0x2 << (4 * (tid % 4)));
6895 if (tid == 3) { /* Check if done with sdtr_speed1. */
6896 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
6897 word = 0;
6898 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
6899 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
6900 word = 0;
6901 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
6902 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
6903 word = 0;
6904 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
6905 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
6906 /* End of loop. */
6911 * Set microcode operating variable for the disconnect per TID bitmask.
6913 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
6914 asc_dvc->cfg->disc_enable);
6917 * Set SCSI_CFG0 Microcode Default Value.
6919 * The microcode will set the SCSI_CFG0 register using this value
6920 * after it is started below.
6922 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
6923 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
6924 asc_dvc->chip_scsi_id);
6927 * Determine SCSI_CFG1 Microcode Default Value.
6929 * The microcode will set the SCSI_CFG1 register using this value
6930 * after it is started below.
6933 /* Read current SCSI_CFG1 Register value. */
6934 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
6937 * If all three connectors are in use, return an error.
6939 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
6940 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
6941 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
6942 return ADV_ERROR;
6946 * If the internal narrow cable is reversed all of the SCSI_CTRL
6947 * register signals will be set. Check for and return an error if
6948 * this condition is found.
6950 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
6951 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
6952 return ADV_ERROR;
6956 * If this is a differential board and a single-ended device
6957 * is attached to one of the connectors, return an error.
6959 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
6960 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
6961 return ADV_ERROR;
6965 * If automatic termination control is enabled, then set the
6966 * termination value based on a table listed in a_condor.h.
6968 * If manual termination was specified with an EEPROM setting
6969 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
6970 * is ready to be 'ored' into SCSI_CFG1.
6972 if (asc_dvc->cfg->termination == 0) {
6974 * The software always controls termination by setting TERM_CTL_SEL.
6975 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
6977 asc_dvc->cfg->termination |= TERM_CTL_SEL;
6979 switch (scsi_cfg1 & CABLE_DETECT) {
6980 /* TERM_CTL_H: on, TERM_CTL_L: on */
6981 case 0x3:
6982 case 0x7:
6983 case 0xB:
6984 case 0xD:
6985 case 0xE:
6986 case 0xF:
6987 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
6988 break;
6990 /* TERM_CTL_H: on, TERM_CTL_L: off */
6991 case 0x1:
6992 case 0x5:
6993 case 0x9:
6994 case 0xA:
6995 case 0xC:
6996 asc_dvc->cfg->termination |= TERM_CTL_H;
6997 break;
6999 /* TERM_CTL_H: off, TERM_CTL_L: off */
7000 case 0x2:
7001 case 0x6:
7002 break;
7007 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
7009 scsi_cfg1 &= ~TERM_CTL;
7012 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
7013 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
7014 * referenced, because the hardware internally inverts
7015 * the Termination High and Low bits if TERM_POL is set.
7017 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
7020 * Set SCSI_CFG1 Microcode Default Value
7022 * Set filter value and possibly modified termination control
7023 * bits in the Microcode SCSI_CFG1 Register Value.
7025 * The microcode will set the SCSI_CFG1 register using this value
7026 * after it is started below.
7028 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
7029 FLTR_DISABLE | scsi_cfg1);
7032 * Set MEM_CFG Microcode Default Value
7034 * The microcode will set the MEM_CFG register using this value
7035 * after it is started below.
7037 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7038 * are defined.
7040 * ASC-3550 has 8KB internal memory.
7042 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7043 BIOS_EN | RAM_SZ_8KB);
7046 * Set SEL_MASK Microcode Default Value
7048 * The microcode will set the SEL_MASK register using this value
7049 * after it is started below.
7051 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7052 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7054 AdvBuildCarrierFreelist(asc_dvc);
7057 * Set-up the Host->RISC Initiator Command Queue (ICQ).
7060 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7061 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7062 return ADV_ERROR;
7064 asc_dvc->carr_freelist = (ADV_CARR_T *)
7065 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7068 * The first command issued will be placed in the stopper carrier.
7070 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7073 * Set RISC ICQ physical address start value.
7075 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7078 * Set-up the RISC->Host Initiator Response Queue (IRQ).
7080 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7081 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7082 return ADV_ERROR;
7084 asc_dvc->carr_freelist = (ADV_CARR_T *)
7085 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7088 * The first command completed by the RISC will be placed in
7089 * the stopper.
7091 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7092 * completed the RISC will set the ASC_RQ_STOPPER bit.
7094 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7097 * Set RISC IRQ physical address start value.
7099 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7100 asc_dvc->carr_pending_cnt = 0;
7102 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7103 (ADV_INTR_ENABLE_HOST_INTR |
7104 ADV_INTR_ENABLE_GLOBAL_INTR));
7106 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7107 AdvWriteWordRegister(iop_base, IOPW_PC, word);
7109 /* finally, finally, gentlemen, start your engine */
7110 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7113 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7114 * Resets should be performed. The RISC has to be running
7115 * to issue a SCSI Bus Reset.
7117 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7119 * If the BIOS Signature is present in memory, restore the
7120 * BIOS Handshake Configuration Table and do not perform
7121 * a SCSI Bus Reset.
7123 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7124 0x55AA) {
7126 * Restore per TID negotiated values.
7128 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7129 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7130 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7131 tagqng_able);
7132 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7133 AdvWriteByteLram(iop_base,
7134 ASC_MC_NUMBER_OF_MAX_CMD + tid,
7135 max_cmd[tid]);
7137 } else {
7138 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7139 warn_code = ASC_WARN_BUSRESET_ERROR;
7144 return warn_code;
7148 * Initialize the ASC-38C0800.
7150 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
7152 * For a non-fatal error return a warning code. If there are no warnings
7153 * then 0 is returned.
7155 * Needed after initialization for error recovery.
7157 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
7159 AdvPortAddr iop_base;
7160 ushort warn_code;
7161 int begin_addr;
7162 int end_addr;
7163 ushort code_sum;
7164 int word;
7165 int i;
7166 ushort scsi_cfg1;
7167 uchar byte;
7168 uchar tid;
7169 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
7170 ushort wdtr_able, sdtr_able, tagqng_able;
7171 uchar max_cmd[ADV_MAX_TID + 1];
7173 /* If there is already an error, don't continue. */
7174 if (asc_dvc->err_code != 0)
7175 return ADV_ERROR;
7178 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
7180 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
7181 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7182 return ADV_ERROR;
7185 warn_code = 0;
7186 iop_base = asc_dvc->iop_base;
7189 * Save the RISC memory BIOS region before writing the microcode.
7190 * The BIOS may already be loaded and using its RISC LRAM region
7191 * so its region must be saved and restored.
7193 * Note: This code makes the assumption, which is currently true,
7194 * that a chip reset does not clear RISC LRAM.
7196 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7197 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7198 bios_mem[i]);
7202 * Save current per TID negotiated values.
7204 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7205 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7206 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7207 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7208 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
7209 max_cmd[tid]);
7213 * RAM BIST (RAM Built-In Self Test)
7215 * Address : I/O base + offset 0x38h register (byte).
7216 * Function: Bit 7-6(RW) : RAM mode
7217 * Normal Mode : 0x00
7218 * Pre-test Mode : 0x40
7219 * RAM Test Mode : 0x80
7220 * Bit 5 : unused
7221 * Bit 4(RO) : Done bit
7222 * Bit 3-0(RO) : Status
7223 * Host Error : 0x08
7224 * Int_RAM Error : 0x04
7225 * RISC Error : 0x02
7226 * SCSI Error : 0x01
7227 * No Error : 0x00
7229 * Note: RAM BIST code should be put right here, before loading the
7230 * microcode and after saving the RISC memory BIOS region.
7234 * LRAM Pre-test
7236 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
7237 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
7238 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
7239 * to NORMAL_MODE, return an error too.
7241 for (i = 0; i < 2; i++) {
7242 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
7243 mdelay(10); /* Wait for 10ms before reading back. */
7244 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7245 if ((byte & RAM_TEST_DONE) == 0
7246 || (byte & 0x0F) != PRE_TEST_VALUE) {
7247 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7248 return ADV_ERROR;
7251 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7252 mdelay(10); /* Wait for 10ms before reading back. */
7253 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
7254 != NORMAL_VALUE) {
7255 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7256 return ADV_ERROR;
7261 * LRAM Test - It takes about 1.5 ms to run through the test.
7263 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
7264 * If Done bit not set or Status not 0, save register byte, set the
7265 * err_code, and return an error.
7267 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7268 mdelay(10); /* Wait for 10ms before checking status. */
7270 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7271 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
7272 /* Get here if Done bit not set or Status not 0. */
7273 asc_dvc->bist_err_code = byte; /* for BIOS display message */
7274 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
7275 return ADV_ERROR;
7278 /* We need to reset back to normal mode after LRAM test passes. */
7279 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7281 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf,
7282 _adv_asc38C0800_size, ADV_38C0800_MEMSIZE,
7283 _adv_asc38C0800_chksum);
7284 if (asc_dvc->err_code)
7285 return ADV_ERROR;
7288 * Restore the RISC memory BIOS region.
7290 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7291 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7292 bios_mem[i]);
7296 * Calculate and write the microcode code checksum to the microcode
7297 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7299 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
7300 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
7301 code_sum = 0;
7302 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
7303 for (word = begin_addr; word < end_addr; word += 2) {
7304 code_sum += AdvReadWordAutoIncLram(iop_base);
7306 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7309 * Read microcode version and date.
7311 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
7312 asc_dvc->cfg->mcode_date);
7313 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
7314 asc_dvc->cfg->mcode_version);
7317 * Set the chip type to indicate the ASC38C0800.
7319 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
7322 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
7323 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
7324 * cable detection and then we are able to read C_DET[3:0].
7326 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7327 * Microcode Default Value' section below.
7329 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7330 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7331 scsi_cfg1 | DIS_TERM_DRV);
7334 * If the PCI Configuration Command Register "Parity Error Response
7335 * Control" Bit was clear (0), then set the microcode variable
7336 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
7337 * to ignore DMA parity errors.
7339 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
7340 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7341 word |= CONTROL_FLAG_IGNORE_PERR;
7342 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7346 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
7347 * bits for the default FIFO threshold.
7349 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
7351 * For DMA Errata #4 set the BC_THRESH_ENB bit.
7353 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7354 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
7355 READ_CMD_MRM);
7358 * Microcode operating variables for WDTR, SDTR, and command tag
7359 * queuing will be set in slave_configure() based on what a
7360 * device reports it is capable of in Inquiry byte 7.
7362 * If SCSI Bus Resets have been disabled, then directly set
7363 * SDTR and WDTR from the EEPROM configuration. This will allow
7364 * the BIOS and warm boot to work without a SCSI bus hang on
7365 * the Inquiry caused by host and target mismatched DTR values.
7366 * Without the SCSI Bus Reset, before an Inquiry a device can't
7367 * be assumed to be in Asynchronous, Narrow mode.
7369 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
7370 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
7371 asc_dvc->wdtr_able);
7372 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
7373 asc_dvc->sdtr_able);
7377 * Set microcode operating variables for DISC and SDTR_SPEED1,
7378 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
7379 * configuration values.
7381 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
7382 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7383 * without determining here whether the device supports SDTR.
7385 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
7386 asc_dvc->cfg->disc_enable);
7387 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
7388 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
7389 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
7390 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
7393 * Set SCSI_CFG0 Microcode Default Value.
7395 * The microcode will set the SCSI_CFG0 register using this value
7396 * after it is started below.
7398 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
7399 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
7400 asc_dvc->chip_scsi_id);
7403 * Determine SCSI_CFG1 Microcode Default Value.
7405 * The microcode will set the SCSI_CFG1 register using this value
7406 * after it is started below.
7409 /* Read current SCSI_CFG1 Register value. */
7410 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7413 * If the internal narrow cable is reversed all of the SCSI_CTRL
7414 * register signals will be set. Check for and return an error if
7415 * this condition is found.
7417 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7418 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7419 return ADV_ERROR;
7423 * All kind of combinations of devices attached to one of four
7424 * connectors are acceptable except HVD device attached. For example,
7425 * LVD device can be attached to SE connector while SE device attached
7426 * to LVD connector. If LVD device attached to SE connector, it only
7427 * runs up to Ultra speed.
7429 * If an HVD device is attached to one of LVD connectors, return an
7430 * error. However, there is no way to detect HVD device attached to
7431 * SE connectors.
7433 if (scsi_cfg1 & HVD) {
7434 asc_dvc->err_code = ASC_IERR_HVD_DEVICE;
7435 return ADV_ERROR;
7439 * If either SE or LVD automatic termination control is enabled, then
7440 * set the termination value based on a table listed in a_condor.h.
7442 * If manual termination was specified with an EEPROM setting then
7443 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready
7444 * to be 'ored' into SCSI_CFG1.
7446 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
7447 /* SE automatic termination control is enabled. */
7448 switch (scsi_cfg1 & C_DET_SE) {
7449 /* TERM_SE_HI: on, TERM_SE_LO: on */
7450 case 0x1:
7451 case 0x2:
7452 case 0x3:
7453 asc_dvc->cfg->termination |= TERM_SE;
7454 break;
7456 /* TERM_SE_HI: on, TERM_SE_LO: off */
7457 case 0x0:
7458 asc_dvc->cfg->termination |= TERM_SE_HI;
7459 break;
7463 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
7464 /* LVD automatic termination control is enabled. */
7465 switch (scsi_cfg1 & C_DET_LVD) {
7466 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
7467 case 0x4:
7468 case 0x8:
7469 case 0xC:
7470 asc_dvc->cfg->termination |= TERM_LVD;
7471 break;
7473 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
7474 case 0x0:
7475 break;
7480 * Clear any set TERM_SE and TERM_LVD bits.
7482 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
7485 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
7487 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
7490 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE
7491 * bits and set possibly modified termination control bits in the
7492 * Microcode SCSI_CFG1 Register Value.
7494 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
7497 * Set SCSI_CFG1 Microcode Default Value
7499 * Set possibly modified termination control and reset DIS_TERM_DRV
7500 * bits in the Microcode SCSI_CFG1 Register Value.
7502 * The microcode will set the SCSI_CFG1 register using this value
7503 * after it is started below.
7505 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
7508 * Set MEM_CFG Microcode Default Value
7510 * The microcode will set the MEM_CFG register using this value
7511 * after it is started below.
7513 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7514 * are defined.
7516 * ASC-38C0800 has 16KB internal memory.
7518 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7519 BIOS_EN | RAM_SZ_16KB);
7522 * Set SEL_MASK Microcode Default Value
7524 * The microcode will set the SEL_MASK register using this value
7525 * after it is started below.
7527 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7528 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7530 AdvBuildCarrierFreelist(asc_dvc);
7533 * Set-up the Host->RISC Initiator Command Queue (ICQ).
7536 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7537 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7538 return ADV_ERROR;
7540 asc_dvc->carr_freelist = (ADV_CARR_T *)
7541 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7544 * The first command issued will be placed in the stopper carrier.
7546 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7549 * Set RISC ICQ physical address start value.
7550 * carr_pa is LE, must be native before write
7552 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7555 * Set-up the RISC->Host Initiator Response Queue (IRQ).
7557 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7558 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7559 return ADV_ERROR;
7561 asc_dvc->carr_freelist = (ADV_CARR_T *)
7562 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7565 * The first command completed by the RISC will be placed in
7566 * the stopper.
7568 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7569 * completed the RISC will set the ASC_RQ_STOPPER bit.
7571 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7574 * Set RISC IRQ physical address start value.
7576 * carr_pa is LE, must be native before write *
7578 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7579 asc_dvc->carr_pending_cnt = 0;
7581 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7582 (ADV_INTR_ENABLE_HOST_INTR |
7583 ADV_INTR_ENABLE_GLOBAL_INTR));
7585 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7586 AdvWriteWordRegister(iop_base, IOPW_PC, word);
7588 /* finally, finally, gentlemen, start your engine */
7589 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7592 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7593 * Resets should be performed. The RISC has to be running
7594 * to issue a SCSI Bus Reset.
7596 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7598 * If the BIOS Signature is present in memory, restore the
7599 * BIOS Handshake Configuration Table and do not perform
7600 * a SCSI Bus Reset.
7602 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7603 0x55AA) {
7605 * Restore per TID negotiated values.
7607 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7608 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7609 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7610 tagqng_able);
7611 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7612 AdvWriteByteLram(iop_base,
7613 ASC_MC_NUMBER_OF_MAX_CMD + tid,
7614 max_cmd[tid]);
7616 } else {
7617 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7618 warn_code = ASC_WARN_BUSRESET_ERROR;
7623 return warn_code;
7627 * Initialize the ASC-38C1600.
7629 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
7631 * For a non-fatal error return a warning code. If there are no warnings
7632 * then 0 is returned.
7634 * Needed after initialization for error recovery.
7636 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
7638 AdvPortAddr iop_base;
7639 ushort warn_code;
7640 int begin_addr;
7641 int end_addr;
7642 ushort code_sum;
7643 long word;
7644 int i;
7645 ushort scsi_cfg1;
7646 uchar byte;
7647 uchar tid;
7648 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
7649 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
7650 uchar max_cmd[ASC_MAX_TID + 1];
7652 /* If there is already an error, don't continue. */
7653 if (asc_dvc->err_code != 0) {
7654 return ADV_ERROR;
7658 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
7660 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
7661 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7662 return ADV_ERROR;
7665 warn_code = 0;
7666 iop_base = asc_dvc->iop_base;
7669 * Save the RISC memory BIOS region before writing the microcode.
7670 * The BIOS may already be loaded and using its RISC LRAM region
7671 * so its region must be saved and restored.
7673 * Note: This code makes the assumption, which is currently true,
7674 * that a chip reset does not clear RISC LRAM.
7676 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7677 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7678 bios_mem[i]);
7682 * Save current per TID negotiated values.
7684 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7685 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7686 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
7687 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7688 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
7689 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
7690 max_cmd[tid]);
7694 * RAM BIST (Built-In Self Test)
7696 * Address : I/O base + offset 0x38h register (byte).
7697 * Function: Bit 7-6(RW) : RAM mode
7698 * Normal Mode : 0x00
7699 * Pre-test Mode : 0x40
7700 * RAM Test Mode : 0x80
7701 * Bit 5 : unused
7702 * Bit 4(RO) : Done bit
7703 * Bit 3-0(RO) : Status
7704 * Host Error : 0x08
7705 * Int_RAM Error : 0x04
7706 * RISC Error : 0x02
7707 * SCSI Error : 0x01
7708 * No Error : 0x00
7710 * Note: RAM BIST code should be put right here, before loading the
7711 * microcode and after saving the RISC memory BIOS region.
7715 * LRAM Pre-test
7717 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
7718 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
7719 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
7720 * to NORMAL_MODE, return an error too.
7722 for (i = 0; i < 2; i++) {
7723 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
7724 mdelay(10); /* Wait for 10ms before reading back. */
7725 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7726 if ((byte & RAM_TEST_DONE) == 0
7727 || (byte & 0x0F) != PRE_TEST_VALUE) {
7728 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7729 return ADV_ERROR;
7732 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7733 mdelay(10); /* Wait for 10ms before reading back. */
7734 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
7735 != NORMAL_VALUE) {
7736 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7737 return ADV_ERROR;
7742 * LRAM Test - It takes about 1.5 ms to run through the test.
7744 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
7745 * If Done bit not set or Status not 0, save register byte, set the
7746 * err_code, and return an error.
7748 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7749 mdelay(10); /* Wait for 10ms before checking status. */
7751 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7752 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
7753 /* Get here if Done bit not set or Status not 0. */
7754 asc_dvc->bist_err_code = byte; /* for BIOS display message */
7755 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
7756 return ADV_ERROR;
7759 /* We need to reset back to normal mode after LRAM test passes. */
7760 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7762 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf,
7763 _adv_asc38C1600_size, ADV_38C1600_MEMSIZE,
7764 _adv_asc38C1600_chksum);
7765 if (asc_dvc->err_code)
7766 return ADV_ERROR;
7769 * Restore the RISC memory BIOS region.
7771 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7772 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7773 bios_mem[i]);
7777 * Calculate and write the microcode code checksum to the microcode
7778 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7780 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
7781 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
7782 code_sum = 0;
7783 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
7784 for (word = begin_addr; word < end_addr; word += 2) {
7785 code_sum += AdvReadWordAutoIncLram(iop_base);
7787 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7790 * Read microcode version and date.
7792 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
7793 asc_dvc->cfg->mcode_date);
7794 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
7795 asc_dvc->cfg->mcode_version);
7798 * Set the chip type to indicate the ASC38C1600.
7800 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
7803 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
7804 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
7805 * cable detection and then we are able to read C_DET[3:0].
7807 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7808 * Microcode Default Value' section below.
7810 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7811 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7812 scsi_cfg1 | DIS_TERM_DRV);
7815 * If the PCI Configuration Command Register "Parity Error Response
7816 * Control" Bit was clear (0), then set the microcode variable
7817 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
7818 * to ignore DMA parity errors.
7820 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
7821 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7822 word |= CONTROL_FLAG_IGNORE_PERR;
7823 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7827 * If the BIOS control flag AIPP (Asynchronous Information
7828 * Phase Protection) disable bit is not set, then set the firmware
7829 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
7830 * AIPP checking and encoding.
7832 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
7833 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7834 word |= CONTROL_FLAG_ENABLE_AIPP;
7835 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7839 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
7840 * and START_CTL_TH [3:2].
7842 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7843 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
7846 * Microcode operating variables for WDTR, SDTR, and command tag
7847 * queuing will be set in slave_configure() based on what a
7848 * device reports it is capable of in Inquiry byte 7.
7850 * If SCSI Bus Resets have been disabled, then directly set
7851 * SDTR and WDTR from the EEPROM configuration. This will allow
7852 * the BIOS and warm boot to work without a SCSI bus hang on
7853 * the Inquiry caused by host and target mismatched DTR values.
7854 * Without the SCSI Bus Reset, before an Inquiry a device can't
7855 * be assumed to be in Asynchronous, Narrow mode.
7857 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
7858 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
7859 asc_dvc->wdtr_able);
7860 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
7861 asc_dvc->sdtr_able);
7865 * Set microcode operating variables for DISC and SDTR_SPEED1,
7866 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
7867 * configuration values.
7869 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
7870 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7871 * without determining here whether the device supports SDTR.
7873 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
7874 asc_dvc->cfg->disc_enable);
7875 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
7876 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
7877 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
7878 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
7881 * Set SCSI_CFG0 Microcode Default Value.
7883 * The microcode will set the SCSI_CFG0 register using this value
7884 * after it is started below.
7886 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
7887 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
7888 asc_dvc->chip_scsi_id);
7891 * Calculate SCSI_CFG1 Microcode Default Value.
7893 * The microcode will set the SCSI_CFG1 register using this value
7894 * after it is started below.
7896 * Each ASC-38C1600 function has only two cable detect bits.
7897 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
7899 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7902 * If the cable is reversed all of the SCSI_CTRL register signals
7903 * will be set. Check for and return an error if this condition is
7904 * found.
7906 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7907 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7908 return ADV_ERROR;
7912 * Each ASC-38C1600 function has two connectors. Only an HVD device
7913 * can not be connected to either connector. An LVD device or SE device
7914 * may be connected to either connecor. If an SE device is connected,
7915 * then at most Ultra speed (20 Mhz) can be used on both connectors.
7917 * If an HVD device is attached, return an error.
7919 if (scsi_cfg1 & HVD) {
7920 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
7921 return ADV_ERROR;
7925 * Each function in the ASC-38C1600 uses only the SE cable detect and
7926 * termination because there are two connectors for each function. Each
7927 * function may use either LVD or SE mode. Corresponding the SE automatic
7928 * termination control EEPROM bits are used for each function. Each
7929 * function has its own EEPROM. If SE automatic control is enabled for
7930 * the function, then set the termination value based on a table listed
7931 * in a_condor.h.
7933 * If manual termination is specified in the EEPROM for the function,
7934 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
7935 * ready to be 'ored' into SCSI_CFG1.
7937 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
7938 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
7939 /* SE automatic termination control is enabled. */
7940 switch (scsi_cfg1 & C_DET_SE) {
7941 /* TERM_SE_HI: on, TERM_SE_LO: on */
7942 case 0x1:
7943 case 0x2:
7944 case 0x3:
7945 asc_dvc->cfg->termination |= TERM_SE;
7946 break;
7948 case 0x0:
7949 if (PCI_FUNC(pdev->devfn) == 0) {
7950 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
7951 } else {
7952 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
7953 asc_dvc->cfg->termination |= TERM_SE_HI;
7955 break;
7960 * Clear any set TERM_SE bits.
7962 scsi_cfg1 &= ~TERM_SE;
7965 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
7967 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
7970 * Clear Big Endian and Terminator Polarity bits and set possibly
7971 * modified termination control bits in the Microcode SCSI_CFG1
7972 * Register Value.
7974 * Big Endian bit is not used even on big endian machines.
7976 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
7979 * Set SCSI_CFG1 Microcode Default Value
7981 * Set possibly modified termination control bits in the Microcode
7982 * SCSI_CFG1 Register Value.
7984 * The microcode will set the SCSI_CFG1 register using this value
7985 * after it is started below.
7987 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
7990 * Set MEM_CFG Microcode Default Value
7992 * The microcode will set the MEM_CFG register using this value
7993 * after it is started below.
7995 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7996 * are defined.
7998 * ASC-38C1600 has 32KB internal memory.
8000 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
8001 * out a special 16K Adv Library and Microcode version. After the issue
8002 * resolved, we should turn back to the 32K support. Both a_condor.h and
8003 * mcode.sas files also need to be updated.
8005 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
8006 * BIOS_EN | RAM_SZ_32KB);
8008 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
8009 BIOS_EN | RAM_SZ_16KB);
8012 * Set SEL_MASK Microcode Default Value
8014 * The microcode will set the SEL_MASK register using this value
8015 * after it is started below.
8017 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
8018 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
8020 AdvBuildCarrierFreelist(asc_dvc);
8023 * Set-up the Host->RISC Initiator Command Queue (ICQ).
8025 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
8026 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
8027 return ADV_ERROR;
8029 asc_dvc->carr_freelist = (ADV_CARR_T *)
8030 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
8033 * The first command issued will be placed in the stopper carrier.
8035 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
8038 * Set RISC ICQ physical address start value. Initialize the
8039 * COMMA register to the same value otherwise the RISC will
8040 * prematurely detect a command is available.
8042 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
8043 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
8044 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
8047 * Set-up the RISC->Host Initiator Response Queue (IRQ).
8049 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
8050 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
8051 return ADV_ERROR;
8053 asc_dvc->carr_freelist = (ADV_CARR_T *)
8054 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
8057 * The first command completed by the RISC will be placed in
8058 * the stopper.
8060 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
8061 * completed the RISC will set the ASC_RQ_STOPPER bit.
8063 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
8066 * Set RISC IRQ physical address start value.
8068 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
8069 asc_dvc->carr_pending_cnt = 0;
8071 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
8072 (ADV_INTR_ENABLE_HOST_INTR |
8073 ADV_INTR_ENABLE_GLOBAL_INTR));
8074 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
8075 AdvWriteWordRegister(iop_base, IOPW_PC, word);
8077 /* finally, finally, gentlemen, start your engine */
8078 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
8081 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
8082 * Resets should be performed. The RISC has to be running
8083 * to issue a SCSI Bus Reset.
8085 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
8087 * If the BIOS Signature is present in memory, restore the
8088 * per TID microcode operating variables.
8090 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
8091 0x55AA) {
8093 * Restore per TID negotiated values.
8095 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8096 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8097 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8098 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
8099 tagqng_able);
8100 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
8101 AdvWriteByteLram(iop_base,
8102 ASC_MC_NUMBER_OF_MAX_CMD + tid,
8103 max_cmd[tid]);
8105 } else {
8106 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
8107 warn_code = ASC_WARN_BUSRESET_ERROR;
8112 return warn_code;
8116 * Reset chip and SCSI Bus.
8118 * Return Value:
8119 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
8120 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
8122 static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
8124 int status;
8125 ushort wdtr_able, sdtr_able, tagqng_able;
8126 ushort ppr_able = 0;
8127 uchar tid, max_cmd[ADV_MAX_TID + 1];
8128 AdvPortAddr iop_base;
8129 ushort bios_sig;
8131 iop_base = asc_dvc->iop_base;
8134 * Save current per TID negotiated values.
8136 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8137 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8138 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8139 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8141 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8142 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
8143 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
8144 max_cmd[tid]);
8148 * Force the AdvInitAsc3550/38C0800Driver() function to
8149 * perform a SCSI Bus Reset by clearing the BIOS signature word.
8150 * The initialization functions assumes a SCSI Bus Reset is not
8151 * needed if the BIOS signature word is present.
8153 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8154 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
8157 * Stop chip and reset it.
8159 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
8160 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
8161 mdelay(100);
8162 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
8163 ADV_CTRL_REG_CMD_WR_IO_REG);
8166 * Reset Adv Library error code, if any, and try
8167 * re-initializing the chip.
8169 asc_dvc->err_code = 0;
8170 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8171 status = AdvInitAsc38C1600Driver(asc_dvc);
8172 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8173 status = AdvInitAsc38C0800Driver(asc_dvc);
8174 } else {
8175 status = AdvInitAsc3550Driver(asc_dvc);
8178 /* Translate initialization return value to status value. */
8179 if (status == 0) {
8180 status = ADV_TRUE;
8181 } else {
8182 status = ADV_FALSE;
8186 * Restore the BIOS signature word.
8188 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8191 * Restore per TID negotiated values.
8193 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8194 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8195 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8196 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8198 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8199 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
8200 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
8201 max_cmd[tid]);
8204 return status;
8208 * adv_async_callback() - Adv Library asynchronous event callback function.
8210 static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
8212 switch (code) {
8213 case ADV_ASYNC_SCSI_BUS_RESET_DET:
8215 * The firmware detected a SCSI Bus reset.
8217 ASC_DBG(0, "ADV_ASYNC_SCSI_BUS_RESET_DET\n");
8218 break;
8220 case ADV_ASYNC_RDMA_FAILURE:
8222 * Handle RDMA failure by resetting the SCSI Bus and
8223 * possibly the chip if it is unresponsive. Log the error
8224 * with a unique code.
8226 ASC_DBG(0, "ADV_ASYNC_RDMA_FAILURE\n");
8227 AdvResetChipAndSB(adv_dvc_varp);
8228 break;
8230 case ADV_HOST_SCSI_BUS_RESET:
8232 * Host generated SCSI bus reset occurred.
8234 ASC_DBG(0, "ADV_HOST_SCSI_BUS_RESET\n");
8235 break;
8237 default:
8238 ASC_DBG(0, "unknown code 0x%x\n", code);
8239 break;
8244 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
8246 * Callback function for the Wide SCSI Adv Library.
8248 static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
8250 struct asc_board *boardp;
8251 adv_req_t *reqp;
8252 adv_sgblk_t *sgblkp;
8253 struct scsi_cmnd *scp;
8254 struct Scsi_Host *shost;
8255 ADV_DCNT resid_cnt;
8257 ASC_DBG(1, "adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
8258 (ulong)adv_dvc_varp, (ulong)scsiqp);
8259 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
8262 * Get the adv_req_t structure for the command that has been
8263 * completed. The adv_req_t structure actually contains the
8264 * completed ADV_SCSI_REQ_Q structure.
8266 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
8267 ASC_DBG(1, "reqp 0x%lx\n", (ulong)reqp);
8268 if (reqp == NULL) {
8269 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
8270 return;
8274 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
8275 * command that has been completed.
8277 * Note: The adv_req_t request structure and adv_sgblk_t structure,
8278 * if any, are dropped, because a board structure pointer can not be
8279 * determined.
8281 scp = reqp->cmndp;
8282 ASC_DBG(1, "scp 0x%p\n", scp);
8283 if (scp == NULL) {
8284 ASC_PRINT
8285 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
8286 return;
8288 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
8290 shost = scp->device->host;
8291 ASC_STATS(shost, callback);
8292 ASC_DBG(1, "shost 0x%p\n", shost);
8294 boardp = shost_priv(shost);
8295 BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var);
8298 * 'done_status' contains the command's ending status.
8300 switch (scsiqp->done_status) {
8301 case QD_NO_ERROR:
8302 ASC_DBG(2, "QD_NO_ERROR\n");
8303 scp->result = 0;
8306 * Check for an underrun condition.
8308 * If there was no error and an underrun condition, then
8309 * then return the number of underrun bytes.
8311 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
8312 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
8313 resid_cnt <= scp->request_bufflen) {
8314 ASC_DBG(1, "underrun condition %lu bytes\n",
8315 (ulong)resid_cnt);
8316 scp->resid = resid_cnt;
8318 break;
8320 case QD_WITH_ERROR:
8321 ASC_DBG(2, "QD_WITH_ERROR\n");
8322 switch (scsiqp->host_status) {
8323 case QHSTA_NO_ERROR:
8324 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
8325 ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
8326 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
8327 sizeof(scp->sense_buffer));
8329 * Note: The 'status_byte()' macro used by
8330 * target drivers defined in scsi.h shifts the
8331 * status byte returned by host drivers right
8332 * by 1 bit. This is why target drivers also
8333 * use right shifted status byte definitions.
8334 * For instance target drivers use
8335 * CHECK_CONDITION, defined to 0x1, instead of
8336 * the SCSI defined check condition value of
8337 * 0x2. Host drivers are supposed to return
8338 * the status byte as it is defined by SCSI.
8340 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
8341 STATUS_BYTE(scsiqp->scsi_status);
8342 } else {
8343 scp->result = STATUS_BYTE(scsiqp->scsi_status);
8345 break;
8347 default:
8348 /* Some other QHSTA error occurred. */
8349 ASC_DBG(1, "host_status 0x%x\n", scsiqp->host_status);
8350 scp->result = HOST_BYTE(DID_BAD_TARGET);
8351 break;
8353 break;
8355 case QD_ABORTED_BY_HOST:
8356 ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
8357 scp->result =
8358 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
8359 break;
8361 default:
8362 ASC_DBG(1, "done_status 0x%x\n", scsiqp->done_status);
8363 scp->result =
8364 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
8365 break;
8369 * If the 'init_tidmask' bit isn't already set for the target and the
8370 * current request finished normally, then set the bit for the target
8371 * to indicate that a device is present.
8373 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
8374 scsiqp->done_status == QD_NO_ERROR &&
8375 scsiqp->host_status == QHSTA_NO_ERROR) {
8376 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
8379 asc_scsi_done(scp);
8382 * Free all 'adv_sgblk_t' structures allocated for the request.
8384 while ((sgblkp = reqp->sgblkp) != NULL) {
8385 /* Remove 'sgblkp' from the request list. */
8386 reqp->sgblkp = sgblkp->next_sgblkp;
8388 /* Add 'sgblkp' to the board free list. */
8389 sgblkp->next_sgblkp = boardp->adv_sgblkp;
8390 boardp->adv_sgblkp = sgblkp;
8394 * Free the adv_req_t structure used with the command by adding
8395 * it back to the board free list.
8397 reqp->next_reqp = boardp->adv_reqp;
8398 boardp->adv_reqp = reqp;
8400 ASC_DBG(1, "done\n");
8402 return;
8406 * Adv Library Interrupt Service Routine
8408 * This function is called by a driver's interrupt service routine.
8409 * The function disables and re-enables interrupts.
8411 * When a microcode idle command is completed, the ADV_DVC_VAR
8412 * 'idle_cmd_done' field is set to ADV_TRUE.
8414 * Note: AdvISR() can be called when interrupts are disabled or even
8415 * when there is no hardware interrupt condition present. It will
8416 * always check for completed idle commands and microcode requests.
8417 * This is an important feature that shouldn't be changed because it
8418 * allows commands to be completed from polling mode loops.
8420 * Return:
8421 * ADV_TRUE(1) - interrupt was pending
8422 * ADV_FALSE(0) - no interrupt was pending
8424 static int AdvISR(ADV_DVC_VAR *asc_dvc)
8426 AdvPortAddr iop_base;
8427 uchar int_stat;
8428 ushort target_bit;
8429 ADV_CARR_T *free_carrp;
8430 ADV_VADDR irq_next_vpa;
8431 ADV_SCSI_REQ_Q *scsiq;
8433 iop_base = asc_dvc->iop_base;
8435 /* Reading the register clears the interrupt. */
8436 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
8438 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
8439 ADV_INTR_STATUS_INTRC)) == 0) {
8440 return ADV_FALSE;
8444 * Notify the driver of an asynchronous microcode condition by
8445 * calling the adv_async_callback function. The function
8446 * is passed the microcode ASC_MC_INTRB_CODE byte value.
8448 if (int_stat & ADV_INTR_STATUS_INTRB) {
8449 uchar intrb_code;
8451 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
8453 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
8454 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8455 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
8456 asc_dvc->carr_pending_cnt != 0) {
8457 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
8458 ADV_TICKLE_A);
8459 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
8460 AdvWriteByteRegister(iop_base,
8461 IOPB_TICKLE,
8462 ADV_TICKLE_NOP);
8467 adv_async_callback(asc_dvc, intrb_code);
8471 * Check if the IRQ stopper carrier contains a completed request.
8473 while (((irq_next_vpa =
8474 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
8476 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
8477 * The RISC will have set 'areq_vpa' to a virtual address.
8479 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
8480 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
8481 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
8482 * in AdvExeScsiQueue().
8484 scsiq = (ADV_SCSI_REQ_Q *)
8485 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
8488 * Request finished with good status and the queue was not
8489 * DMAed to host memory by the firmware. Set all status fields
8490 * to indicate good status.
8492 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
8493 scsiq->done_status = QD_NO_ERROR;
8494 scsiq->host_status = scsiq->scsi_status = 0;
8495 scsiq->data_cnt = 0L;
8499 * Advance the stopper pointer to the next carrier
8500 * ignoring the lower four bits. Free the previous
8501 * stopper carrier.
8503 free_carrp = asc_dvc->irq_sp;
8504 asc_dvc->irq_sp = (ADV_CARR_T *)
8505 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
8507 free_carrp->next_vpa =
8508 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
8509 asc_dvc->carr_freelist = free_carrp;
8510 asc_dvc->carr_pending_cnt--;
8512 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
8515 * Clear request microcode control flag.
8517 scsiq->cntl = 0;
8520 * Notify the driver of the completed request by passing
8521 * the ADV_SCSI_REQ_Q pointer to its callback function.
8523 scsiq->a_flag |= ADV_SCSIQ_DONE;
8524 adv_isr_callback(asc_dvc, scsiq);
8526 * Note: After the driver callback function is called, 'scsiq'
8527 * can no longer be referenced.
8529 * Fall through and continue processing other completed
8530 * requests...
8533 return ADV_TRUE;
8536 static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
8538 if (asc_dvc->err_code == 0) {
8539 asc_dvc->err_code = err_code;
8540 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
8541 err_code);
8543 return err_code;
8546 static void AscAckInterrupt(PortAddr iop_base)
8548 uchar host_flag;
8549 uchar risc_flag;
8550 ushort loop;
8552 loop = 0;
8553 do {
8554 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
8555 if (loop++ > 0x7FFF) {
8556 break;
8558 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
8559 host_flag =
8560 AscReadLramByte(iop_base,
8561 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
8562 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8563 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
8564 AscSetChipStatus(iop_base, CIW_INT_ACK);
8565 loop = 0;
8566 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
8567 AscSetChipStatus(iop_base, CIW_INT_ACK);
8568 if (loop++ > 3) {
8569 break;
8572 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8573 return;
8576 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
8578 uchar *period_table;
8579 int max_index;
8580 int min_index;
8581 int i;
8583 period_table = asc_dvc->sdtr_period_tbl;
8584 max_index = (int)asc_dvc->max_sdtr_index;
8585 min_index = (int)asc_dvc->host_init_sdtr_index;
8586 if ((syn_time <= period_table[max_index])) {
8587 for (i = min_index; i < (max_index - 1); i++) {
8588 if (syn_time <= period_table[i]) {
8589 return (uchar)i;
8592 return (uchar)max_index;
8593 } else {
8594 return (uchar)(max_index + 1);
8598 static uchar
8599 AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
8601 EXT_MSG sdtr_buf;
8602 uchar sdtr_period_index;
8603 PortAddr iop_base;
8605 iop_base = asc_dvc->iop_base;
8606 sdtr_buf.msg_type = EXTENDED_MESSAGE;
8607 sdtr_buf.msg_len = MS_SDTR_LEN;
8608 sdtr_buf.msg_req = EXTENDED_SDTR;
8609 sdtr_buf.xfer_period = sdtr_period;
8610 sdtr_offset &= ASC_SYN_MAX_OFFSET;
8611 sdtr_buf.req_ack_offset = sdtr_offset;
8612 sdtr_period_index = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8613 if (sdtr_period_index <= asc_dvc->max_sdtr_index) {
8614 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
8615 (uchar *)&sdtr_buf,
8616 sizeof(EXT_MSG) >> 1);
8617 return ((sdtr_period_index << 4) | sdtr_offset);
8618 } else {
8619 sdtr_buf.req_ack_offset = 0;
8620 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
8621 (uchar *)&sdtr_buf,
8622 sizeof(EXT_MSG) >> 1);
8623 return 0;
8627 static uchar
8628 AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
8630 uchar byte;
8631 uchar sdtr_period_ix;
8633 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8634 if (sdtr_period_ix > asc_dvc->max_sdtr_index) {
8635 return 0xFF;
8637 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
8638 return byte;
8641 static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
8643 ASC_SCSI_BIT_ID_TYPE org_id;
8644 int i;
8645 int sta = TRUE;
8647 AscSetBank(iop_base, 1);
8648 org_id = AscReadChipDvcID(iop_base);
8649 for (i = 0; i <= ASC_MAX_TID; i++) {
8650 if (org_id == (0x01 << i))
8651 break;
8653 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
8654 AscWriteChipDvcID(iop_base, id);
8655 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
8656 AscSetBank(iop_base, 0);
8657 AscSetChipSyn(iop_base, sdtr_data);
8658 if (AscGetChipSyn(iop_base) != sdtr_data) {
8659 sta = FALSE;
8661 } else {
8662 sta = FALSE;
8664 AscSetBank(iop_base, 1);
8665 AscWriteChipDvcID(iop_base, org_id);
8666 AscSetBank(iop_base, 0);
8667 return (sta);
8670 static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
8672 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
8673 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
8676 static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8678 EXT_MSG ext_msg;
8679 EXT_MSG out_msg;
8680 ushort halt_q_addr;
8681 int sdtr_accept;
8682 ushort int_halt_code;
8683 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8684 ASC_SCSI_BIT_ID_TYPE target_id;
8685 PortAddr iop_base;
8686 uchar tag_code;
8687 uchar q_status;
8688 uchar halt_qp;
8689 uchar sdtr_data;
8690 uchar target_ix;
8691 uchar q_cntl, tid_no;
8692 uchar cur_dvc_qng;
8693 uchar asyn_sdtr;
8694 uchar scsi_status;
8695 struct asc_board *boardp;
8697 BUG_ON(!asc_dvc->drv_ptr);
8698 boardp = asc_dvc->drv_ptr;
8700 iop_base = asc_dvc->iop_base;
8701 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8703 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8704 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8705 target_ix = AscReadLramByte(iop_base,
8706 (ushort)(halt_q_addr +
8707 (ushort)ASC_SCSIQ_B_TARGET_IX));
8708 q_cntl = AscReadLramByte(iop_base,
8709 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8710 tid_no = ASC_TIX_TO_TID(target_ix);
8711 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8712 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8713 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8714 } else {
8715 asyn_sdtr = 0;
8717 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8718 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8719 AscSetChipSDTR(iop_base, 0, tid_no);
8720 boardp->sdtr_data[tid_no] = 0;
8722 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8723 return (0);
8724 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8725 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8726 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8727 boardp->sdtr_data[tid_no] = asyn_sdtr;
8729 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8730 return (0);
8731 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8732 AscMemWordCopyPtrFromLram(iop_base,
8733 ASCV_MSGIN_BEG,
8734 (uchar *)&ext_msg,
8735 sizeof(EXT_MSG) >> 1);
8737 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8738 ext_msg.msg_req == EXTENDED_SDTR &&
8739 ext_msg.msg_len == MS_SDTR_LEN) {
8740 sdtr_accept = TRUE;
8741 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8743 sdtr_accept = FALSE;
8744 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8746 if ((ext_msg.xfer_period <
8747 asc_dvc->sdtr_period_tbl[asc_dvc->
8748 host_init_sdtr_index])
8749 || (ext_msg.xfer_period >
8750 asc_dvc->sdtr_period_tbl[asc_dvc->
8751 max_sdtr_index])) {
8752 sdtr_accept = FALSE;
8753 ext_msg.xfer_period =
8754 asc_dvc->sdtr_period_tbl[asc_dvc->
8755 host_init_sdtr_index];
8757 if (sdtr_accept) {
8758 sdtr_data =
8759 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8760 ext_msg.req_ack_offset);
8761 if ((sdtr_data == 0xFF)) {
8763 q_cntl |= QC_MSG_OUT;
8764 asc_dvc->init_sdtr &= ~target_id;
8765 asc_dvc->sdtr_done &= ~target_id;
8766 AscSetChipSDTR(iop_base, asyn_sdtr,
8767 tid_no);
8768 boardp->sdtr_data[tid_no] = asyn_sdtr;
8771 if (ext_msg.req_ack_offset == 0) {
8773 q_cntl &= ~QC_MSG_OUT;
8774 asc_dvc->init_sdtr &= ~target_id;
8775 asc_dvc->sdtr_done &= ~target_id;
8776 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8777 } else {
8778 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8780 q_cntl &= ~QC_MSG_OUT;
8781 asc_dvc->sdtr_done |= target_id;
8782 asc_dvc->init_sdtr |= target_id;
8783 asc_dvc->pci_fix_asyn_xfer &=
8784 ~target_id;
8785 sdtr_data =
8786 AscCalSDTRData(asc_dvc,
8787 ext_msg.xfer_period,
8788 ext_msg.
8789 req_ack_offset);
8790 AscSetChipSDTR(iop_base, sdtr_data,
8791 tid_no);
8792 boardp->sdtr_data[tid_no] = sdtr_data;
8793 } else {
8795 q_cntl |= QC_MSG_OUT;
8796 AscMsgOutSDTR(asc_dvc,
8797 ext_msg.xfer_period,
8798 ext_msg.req_ack_offset);
8799 asc_dvc->pci_fix_asyn_xfer &=
8800 ~target_id;
8801 sdtr_data =
8802 AscCalSDTRData(asc_dvc,
8803 ext_msg.xfer_period,
8804 ext_msg.
8805 req_ack_offset);
8806 AscSetChipSDTR(iop_base, sdtr_data,
8807 tid_no);
8808 boardp->sdtr_data[tid_no] = sdtr_data;
8809 asc_dvc->sdtr_done |= target_id;
8810 asc_dvc->init_sdtr |= target_id;
8814 AscWriteLramByte(iop_base,
8815 (ushort)(halt_q_addr +
8816 (ushort)ASC_SCSIQ_B_CNTL),
8817 q_cntl);
8818 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8819 return (0);
8820 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8821 ext_msg.msg_req == EXTENDED_WDTR &&
8822 ext_msg.msg_len == MS_WDTR_LEN) {
8824 ext_msg.wdtr_width = 0;
8825 AscMemWordCopyPtrToLram(iop_base,
8826 ASCV_MSGOUT_BEG,
8827 (uchar *)&ext_msg,
8828 sizeof(EXT_MSG) >> 1);
8829 q_cntl |= QC_MSG_OUT;
8830 AscWriteLramByte(iop_base,
8831 (ushort)(halt_q_addr +
8832 (ushort)ASC_SCSIQ_B_CNTL),
8833 q_cntl);
8834 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8835 return (0);
8836 } else {
8838 ext_msg.msg_type = MESSAGE_REJECT;
8839 AscMemWordCopyPtrToLram(iop_base,
8840 ASCV_MSGOUT_BEG,
8841 (uchar *)&ext_msg,
8842 sizeof(EXT_MSG) >> 1);
8843 q_cntl |= QC_MSG_OUT;
8844 AscWriteLramByte(iop_base,
8845 (ushort)(halt_q_addr +
8846 (ushort)ASC_SCSIQ_B_CNTL),
8847 q_cntl);
8848 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8849 return (0);
8851 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8853 q_cntl |= QC_REQ_SENSE;
8855 if ((asc_dvc->init_sdtr & target_id) != 0) {
8857 asc_dvc->sdtr_done &= ~target_id;
8859 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8860 q_cntl |= QC_MSG_OUT;
8861 AscMsgOutSDTR(asc_dvc,
8862 asc_dvc->
8863 sdtr_period_tbl[(sdtr_data >> 4) &
8864 (uchar)(asc_dvc->
8865 max_sdtr_index -
8866 1)],
8867 (uchar)(sdtr_data & (uchar)
8868 ASC_SYN_MAX_OFFSET));
8871 AscWriteLramByte(iop_base,
8872 (ushort)(halt_q_addr +
8873 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8875 tag_code = AscReadLramByte(iop_base,
8876 (ushort)(halt_q_addr + (ushort)
8877 ASC_SCSIQ_B_TAG_CODE));
8878 tag_code &= 0xDC;
8879 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8880 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8883 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8884 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8887 AscWriteLramByte(iop_base,
8888 (ushort)(halt_q_addr +
8889 (ushort)ASC_SCSIQ_B_TAG_CODE),
8890 tag_code);
8892 q_status = AscReadLramByte(iop_base,
8893 (ushort)(halt_q_addr + (ushort)
8894 ASC_SCSIQ_B_STATUS));
8895 q_status |= (QS_READY | QS_BUSY);
8896 AscWriteLramByte(iop_base,
8897 (ushort)(halt_q_addr +
8898 (ushort)ASC_SCSIQ_B_STATUS),
8899 q_status);
8901 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8902 scsi_busy &= ~target_id;
8903 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8905 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8906 return (0);
8907 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8909 AscMemWordCopyPtrFromLram(iop_base,
8910 ASCV_MSGOUT_BEG,
8911 (uchar *)&out_msg,
8912 sizeof(EXT_MSG) >> 1);
8914 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
8915 (out_msg.msg_len == MS_SDTR_LEN) &&
8916 (out_msg.msg_req == EXTENDED_SDTR)) {
8918 asc_dvc->init_sdtr &= ~target_id;
8919 asc_dvc->sdtr_done &= ~target_id;
8920 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8921 boardp->sdtr_data[tid_no] = asyn_sdtr;
8923 q_cntl &= ~QC_MSG_OUT;
8924 AscWriteLramByte(iop_base,
8925 (ushort)(halt_q_addr +
8926 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8927 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8928 return (0);
8929 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8931 scsi_status = AscReadLramByte(iop_base,
8932 (ushort)((ushort)halt_q_addr +
8933 (ushort)
8934 ASC_SCSIQ_SCSI_STATUS));
8935 cur_dvc_qng =
8936 AscReadLramByte(iop_base,
8937 (ushort)((ushort)ASC_QADR_BEG +
8938 (ushort)target_ix));
8939 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8941 scsi_busy = AscReadLramByte(iop_base,
8942 (ushort)ASCV_SCSIBUSY_B);
8943 scsi_busy |= target_id;
8944 AscWriteLramByte(iop_base,
8945 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8946 asc_dvc->queue_full_or_busy |= target_id;
8948 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8949 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8950 cur_dvc_qng -= 1;
8951 asc_dvc->max_dvc_qng[tid_no] =
8952 cur_dvc_qng;
8954 AscWriteLramByte(iop_base,
8955 (ushort)((ushort)
8956 ASCV_MAX_DVC_QNG_BEG
8957 + (ushort)
8958 tid_no),
8959 cur_dvc_qng);
8962 * Set the device queue depth to the
8963 * number of active requests when the
8964 * QUEUE FULL condition was encountered.
8966 boardp->queue_full |= target_id;
8967 boardp->queue_full_cnt[tid_no] =
8968 cur_dvc_qng;
8972 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8973 return (0);
8975 #if CC_VERY_LONG_SG_LIST
8976 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8977 uchar q_no;
8978 ushort q_addr;
8979 uchar sg_wk_q_no;
8980 uchar first_sg_wk_q_no;
8981 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
8982 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
8983 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
8984 ushort sg_list_dwords;
8985 ushort sg_entry_cnt;
8986 uchar next_qp;
8987 int i;
8989 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8990 if (q_no == ASC_QLINK_END)
8991 return 0;
8993 q_addr = ASC_QNO_TO_QADDR(q_no);
8996 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8997 * structure pointer using a macro provided by the driver.
8998 * The ASC_SCSI_REQ pointer provides a pointer to the
8999 * host ASC_SG_HEAD structure.
9001 /* Read request's SRB pointer. */
9002 scsiq = (ASC_SCSI_Q *)
9003 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
9004 (ushort)
9005 (q_addr +
9006 ASC_SCSIQ_D_SRBPTR))));
9009 * Get request's first and working SG queue.
9011 sg_wk_q_no = AscReadLramByte(iop_base,
9012 (ushort)(q_addr +
9013 ASC_SCSIQ_B_SG_WK_QP));
9015 first_sg_wk_q_no = AscReadLramByte(iop_base,
9016 (ushort)(q_addr +
9017 ASC_SCSIQ_B_FIRST_SG_WK_QP));
9020 * Reset request's working SG queue back to the
9021 * first SG queue.
9023 AscWriteLramByte(iop_base,
9024 (ushort)(q_addr +
9025 (ushort)ASC_SCSIQ_B_SG_WK_QP),
9026 first_sg_wk_q_no);
9028 sg_head = scsiq->sg_head;
9031 * Set sg_entry_cnt to the number of SG elements
9032 * that will be completed on this interrupt.
9034 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
9035 * SG elements. The data_cnt and data_addr fields which
9036 * add 1 to the SG element capacity are not used when
9037 * restarting SG handling after a halt.
9039 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
9040 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9043 * Keep track of remaining number of SG elements that
9044 * will need to be handled on the next interrupt.
9046 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
9047 } else {
9048 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
9049 scsiq->remain_sg_entry_cnt = 0;
9053 * Copy SG elements into the list of allocated SG queues.
9055 * Last index completed is saved in scsiq->next_sg_index.
9057 next_qp = first_sg_wk_q_no;
9058 q_addr = ASC_QNO_TO_QADDR(next_qp);
9059 scsi_sg_q.sg_head_qp = q_no;
9060 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9061 for (i = 0; i < sg_head->queue_cnt; i++) {
9062 scsi_sg_q.seq_no = i + 1;
9063 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9064 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9065 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9067 * After very first SG queue RISC FW uses next
9068 * SG queue first element then checks sg_list_cnt
9069 * against zero and then decrements, so set
9070 * sg_list_cnt 1 less than number of SG elements
9071 * in each SG queue.
9073 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
9074 scsi_sg_q.sg_cur_list_cnt =
9075 ASC_SG_LIST_PER_Q - 1;
9076 } else {
9078 * This is the last SG queue in the list of
9079 * allocated SG queues. If there are more
9080 * SG elements than will fit in the allocated
9081 * queues, then set the QCSG_SG_XFER_MORE flag.
9083 if (scsiq->remain_sg_entry_cnt != 0) {
9084 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9085 } else {
9086 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
9088 /* equals sg_entry_cnt * 2 */
9089 sg_list_dwords = sg_entry_cnt << 1;
9090 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
9091 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
9092 sg_entry_cnt = 0;
9095 scsi_sg_q.q_no = next_qp;
9096 AscMemWordCopyPtrToLram(iop_base,
9097 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9098 (uchar *)&scsi_sg_q,
9099 sizeof(ASC_SG_LIST_Q) >> 1);
9101 AscMemDWordCopyPtrToLram(iop_base,
9102 q_addr + ASC_SGQ_LIST_BEG,
9103 (uchar *)&sg_head->
9104 sg_list[scsiq->next_sg_index],
9105 sg_list_dwords);
9107 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
9110 * If the just completed SG queue contained the
9111 * last SG element, then no more SG queues need
9112 * to be written.
9114 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
9115 break;
9118 next_qp = AscReadLramByte(iop_base,
9119 (ushort)(q_addr +
9120 ASC_SCSIQ_B_FWD));
9121 q_addr = ASC_QNO_TO_QADDR(next_qp);
9125 * Clear the halt condition so the RISC will be restarted
9126 * after the return.
9128 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9129 return (0);
9131 #endif /* CC_VERY_LONG_SG_LIST */
9132 return (0);
9136 * void
9137 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9139 * Calling/Exit State:
9140 * none
9142 * Description:
9143 * Input an ASC_QDONE_INFO structure from the chip
9145 static void
9146 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9148 int i;
9149 ushort word;
9151 AscSetChipLramAddr(iop_base, s_addr);
9152 for (i = 0; i < 2 * words; i += 2) {
9153 if (i == 10) {
9154 continue;
9156 word = inpw(iop_base + IOP_RAM_DATA);
9157 inbuf[i] = word & 0xff;
9158 inbuf[i + 1] = (word >> 8) & 0xff;
9160 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
9163 static uchar
9164 _AscCopyLramScsiDoneQ(PortAddr iop_base,
9165 ushort q_addr,
9166 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
9168 ushort _val;
9169 uchar sg_queue_cnt;
9171 DvcGetQinfo(iop_base,
9172 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
9173 (uchar *)scsiq,
9174 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
9176 _val = AscReadLramWord(iop_base,
9177 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
9178 scsiq->q_status = (uchar)_val;
9179 scsiq->q_no = (uchar)(_val >> 8);
9180 _val = AscReadLramWord(iop_base,
9181 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
9182 scsiq->cntl = (uchar)_val;
9183 sg_queue_cnt = (uchar)(_val >> 8);
9184 _val = AscReadLramWord(iop_base,
9185 (ushort)(q_addr +
9186 (ushort)ASC_SCSIQ_B_SENSE_LEN));
9187 scsiq->sense_len = (uchar)_val;
9188 scsiq->extra_bytes = (uchar)(_val >> 8);
9191 * Read high word of remain bytes from alternate location.
9193 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
9194 (ushort)(q_addr +
9195 (ushort)
9196 ASC_SCSIQ_W_ALT_DC1)))
9197 << 16);
9199 * Read low word of remain bytes from original location.
9201 scsiq->remain_bytes += AscReadLramWord(iop_base,
9202 (ushort)(q_addr + (ushort)
9203 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
9205 scsiq->remain_bytes &= max_dma_count;
9206 return sg_queue_cnt;
9210 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
9212 * Interrupt callback function for the Narrow SCSI Asc Library.
9214 static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
9216 struct asc_board *boardp;
9217 struct scsi_cmnd *scp;
9218 struct Scsi_Host *shost;
9220 ASC_DBG(1, "asc_dvc_varp 0x%p, qdonep 0x%p\n", asc_dvc_varp, qdonep);
9221 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
9224 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
9225 * command that has been completed.
9227 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
9228 ASC_DBG(1, "scp 0x%p\n", scp);
9230 if (scp == NULL) {
9231 ASC_PRINT("asc_isr_callback: scp is NULL\n");
9232 return;
9234 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
9236 shost = scp->device->host;
9237 ASC_STATS(shost, callback);
9238 ASC_DBG(1, "shost 0x%p\n", shost);
9240 boardp = shost_priv(shost);
9241 BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var);
9244 * 'qdonep' contains the command's ending status.
9246 switch (qdonep->d3.done_stat) {
9247 case QD_NO_ERROR:
9248 ASC_DBG(2, "QD_NO_ERROR\n");
9249 scp->result = 0;
9252 * Check for an underrun condition.
9254 * If there was no error and an underrun condition, then
9255 * return the number of underrun bytes.
9257 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
9258 qdonep->remain_bytes <= scp->request_bufflen) {
9259 ASC_DBG(1, "underrun condition %u bytes\n",
9260 (unsigned)qdonep->remain_bytes);
9261 scp->resid = qdonep->remain_bytes;
9263 break;
9265 case QD_WITH_ERROR:
9266 ASC_DBG(2, "QD_WITH_ERROR\n");
9267 switch (qdonep->d3.host_stat) {
9268 case QHSTA_NO_ERROR:
9269 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
9270 ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
9271 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
9272 sizeof(scp->sense_buffer));
9274 * Note: The 'status_byte()' macro used by
9275 * target drivers defined in scsi.h shifts the
9276 * status byte returned by host drivers right
9277 * by 1 bit. This is why target drivers also
9278 * use right shifted status byte definitions.
9279 * For instance target drivers use
9280 * CHECK_CONDITION, defined to 0x1, instead of
9281 * the SCSI defined check condition value of
9282 * 0x2. Host drivers are supposed to return
9283 * the status byte as it is defined by SCSI.
9285 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
9286 STATUS_BYTE(qdonep->d3.scsi_stat);
9287 } else {
9288 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
9290 break;
9292 default:
9293 /* QHSTA error occurred */
9294 ASC_DBG(1, "host_stat 0x%x\n", qdonep->d3.host_stat);
9295 scp->result = HOST_BYTE(DID_BAD_TARGET);
9296 break;
9298 break;
9300 case QD_ABORTED_BY_HOST:
9301 ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
9302 scp->result =
9303 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
9304 scsi_msg) |
9305 STATUS_BYTE(qdonep->d3.scsi_stat);
9306 break;
9308 default:
9309 ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat);
9310 scp->result =
9311 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
9312 scsi_msg) |
9313 STATUS_BYTE(qdonep->d3.scsi_stat);
9314 break;
9318 * If the 'init_tidmask' bit isn't already set for the target and the
9319 * current request finished normally, then set the bit for the target
9320 * to indicate that a device is present.
9322 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
9323 qdonep->d3.done_stat == QD_NO_ERROR &&
9324 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
9325 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
9328 asc_scsi_done(scp);
9330 return;
9333 static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
9335 uchar next_qp;
9336 uchar n_q_used;
9337 uchar sg_list_qp;
9338 uchar sg_queue_cnt;
9339 uchar q_cnt;
9340 uchar done_q_tail;
9341 uchar tid_no;
9342 ASC_SCSI_BIT_ID_TYPE scsi_busy;
9343 ASC_SCSI_BIT_ID_TYPE target_id;
9344 PortAddr iop_base;
9345 ushort q_addr;
9346 ushort sg_q_addr;
9347 uchar cur_target_qng;
9348 ASC_QDONE_INFO scsiq_buf;
9349 ASC_QDONE_INFO *scsiq;
9350 int false_overrun;
9352 iop_base = asc_dvc->iop_base;
9353 n_q_used = 1;
9354 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
9355 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
9356 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
9357 next_qp = AscReadLramByte(iop_base,
9358 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
9359 if (next_qp != ASC_QLINK_END) {
9360 AscPutVarDoneQTail(iop_base, next_qp);
9361 q_addr = ASC_QNO_TO_QADDR(next_qp);
9362 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
9363 asc_dvc->max_dma_count);
9364 AscWriteLramByte(iop_base,
9365 (ushort)(q_addr +
9366 (ushort)ASC_SCSIQ_B_STATUS),
9367 (uchar)(scsiq->
9368 q_status & (uchar)~(QS_READY |
9369 QS_ABORTED)));
9370 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
9371 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
9372 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
9373 sg_q_addr = q_addr;
9374 sg_list_qp = next_qp;
9375 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
9376 sg_list_qp = AscReadLramByte(iop_base,
9377 (ushort)(sg_q_addr
9378 + (ushort)
9379 ASC_SCSIQ_B_FWD));
9380 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
9381 if (sg_list_qp == ASC_QLINK_END) {
9382 AscSetLibErrorCode(asc_dvc,
9383 ASCQ_ERR_SG_Q_LINKS);
9384 scsiq->d3.done_stat = QD_WITH_ERROR;
9385 scsiq->d3.host_stat =
9386 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
9387 goto FATAL_ERR_QDONE;
9389 AscWriteLramByte(iop_base,
9390 (ushort)(sg_q_addr + (ushort)
9391 ASC_SCSIQ_B_STATUS),
9392 QS_FREE);
9394 n_q_used = sg_queue_cnt + 1;
9395 AscPutVarDoneQTail(iop_base, sg_list_qp);
9397 if (asc_dvc->queue_full_or_busy & target_id) {
9398 cur_target_qng = AscReadLramByte(iop_base,
9399 (ushort)((ushort)
9400 ASC_QADR_BEG
9401 + (ushort)
9402 scsiq->d2.
9403 target_ix));
9404 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
9405 scsi_busy = AscReadLramByte(iop_base, (ushort)
9406 ASCV_SCSIBUSY_B);
9407 scsi_busy &= ~target_id;
9408 AscWriteLramByte(iop_base,
9409 (ushort)ASCV_SCSIBUSY_B,
9410 scsi_busy);
9411 asc_dvc->queue_full_or_busy &= ~target_id;
9414 if (asc_dvc->cur_total_qng >= n_q_used) {
9415 asc_dvc->cur_total_qng -= n_q_used;
9416 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
9417 asc_dvc->cur_dvc_qng[tid_no]--;
9419 } else {
9420 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
9421 scsiq->d3.done_stat = QD_WITH_ERROR;
9422 goto FATAL_ERR_QDONE;
9424 if ((scsiq->d2.srb_ptr == 0UL) ||
9425 ((scsiq->q_status & QS_ABORTED) != 0)) {
9426 return (0x11);
9427 } else if (scsiq->q_status == QS_DONE) {
9428 false_overrun = FALSE;
9429 if (scsiq->extra_bytes != 0) {
9430 scsiq->remain_bytes +=
9431 (ADV_DCNT)scsiq->extra_bytes;
9433 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
9434 if (scsiq->d3.host_stat ==
9435 QHSTA_M_DATA_OVER_RUN) {
9436 if ((scsiq->
9437 cntl & (QC_DATA_IN | QC_DATA_OUT))
9438 == 0) {
9439 scsiq->d3.done_stat =
9440 QD_NO_ERROR;
9441 scsiq->d3.host_stat =
9442 QHSTA_NO_ERROR;
9443 } else if (false_overrun) {
9444 scsiq->d3.done_stat =
9445 QD_NO_ERROR;
9446 scsiq->d3.host_stat =
9447 QHSTA_NO_ERROR;
9449 } else if (scsiq->d3.host_stat ==
9450 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
9451 AscStopChip(iop_base);
9452 AscSetChipControl(iop_base,
9453 (uchar)(CC_SCSI_RESET
9454 | CC_HALT));
9455 udelay(60);
9456 AscSetChipControl(iop_base, CC_HALT);
9457 AscSetChipStatus(iop_base,
9458 CIW_CLR_SCSI_RESET_INT);
9459 AscSetChipStatus(iop_base, 0);
9460 AscSetChipControl(iop_base, 0);
9463 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9464 asc_isr_callback(asc_dvc, scsiq);
9465 } else {
9466 if ((AscReadLramByte(iop_base,
9467 (ushort)(q_addr + (ushort)
9468 ASC_SCSIQ_CDB_BEG))
9469 == START_STOP)) {
9470 asc_dvc->unit_not_ready &= ~target_id;
9471 if (scsiq->d3.done_stat != QD_NO_ERROR) {
9472 asc_dvc->start_motor &=
9473 ~target_id;
9477 return (1);
9478 } else {
9479 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
9480 FATAL_ERR_QDONE:
9481 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9482 asc_isr_callback(asc_dvc, scsiq);
9484 return (0x80);
9487 return (0);
9490 static int AscISR(ASC_DVC_VAR *asc_dvc)
9492 ASC_CS_TYPE chipstat;
9493 PortAddr iop_base;
9494 ushort saved_ram_addr;
9495 uchar ctrl_reg;
9496 uchar saved_ctrl_reg;
9497 int int_pending;
9498 int status;
9499 uchar host_flag;
9501 iop_base = asc_dvc->iop_base;
9502 int_pending = FALSE;
9504 if (AscIsIntPending(iop_base) == 0)
9505 return int_pending;
9507 if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
9508 return ERR;
9510 if (asc_dvc->in_critical_cnt != 0) {
9511 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
9512 return ERR;
9514 if (asc_dvc->is_in_int) {
9515 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
9516 return ERR;
9518 asc_dvc->is_in_int = TRUE;
9519 ctrl_reg = AscGetChipControl(iop_base);
9520 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
9521 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
9522 chipstat = AscGetChipStatus(iop_base);
9523 if (chipstat & CSW_SCSI_RESET_LATCH) {
9524 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
9525 int i = 10;
9526 int_pending = TRUE;
9527 asc_dvc->sdtr_done = 0;
9528 saved_ctrl_reg &= (uchar)(~CC_HALT);
9529 while ((AscGetChipStatus(iop_base) &
9530 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
9531 mdelay(100);
9533 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
9534 AscSetChipControl(iop_base, CC_HALT);
9535 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
9536 AscSetChipStatus(iop_base, 0);
9537 chipstat = AscGetChipStatus(iop_base);
9540 saved_ram_addr = AscGetChipLramAddr(iop_base);
9541 host_flag = AscReadLramByte(iop_base,
9542 ASCV_HOST_FLAG_B) &
9543 (uchar)(~ASC_HOST_FLAG_IN_ISR);
9544 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
9545 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
9546 if ((chipstat & CSW_INT_PENDING) || (int_pending)) {
9547 AscAckInterrupt(iop_base);
9548 int_pending = TRUE;
9549 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
9550 if (AscIsrChipHalted(asc_dvc) == ERR) {
9551 goto ISR_REPORT_QDONE_FATAL_ERROR;
9552 } else {
9553 saved_ctrl_reg &= (uchar)(~CC_HALT);
9555 } else {
9556 ISR_REPORT_QDONE_FATAL_ERROR:
9557 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
9558 while (((status =
9559 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
9561 } else {
9562 do {
9563 if ((status =
9564 AscIsrQDone(asc_dvc)) == 1) {
9565 break;
9567 } while (status == 0x11);
9569 if ((status & 0x80) != 0)
9570 int_pending = ERR;
9573 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9574 AscSetChipLramAddr(iop_base, saved_ram_addr);
9575 AscSetChipControl(iop_base, saved_ctrl_reg);
9576 asc_dvc->is_in_int = FALSE;
9577 return int_pending;
9581 * advansys_reset()
9583 * Reset the bus associated with the command 'scp'.
9585 * This function runs its own thread. Interrupts must be blocked but
9586 * sleeping is allowed and no locking other than for host structures is
9587 * required. Returns SUCCESS or FAILED.
9589 static int advansys_reset(struct scsi_cmnd *scp)
9591 struct Scsi_Host *shost = scp->device->host;
9592 struct asc_board *boardp = shost_priv(shost);
9593 unsigned long flags;
9594 int status;
9595 int ret = SUCCESS;
9597 ASC_DBG(1, "0x%p\n", scp);
9599 ASC_STATS(shost, reset);
9601 scmd_printk(KERN_INFO, scp, "SCSI bus reset started...\n");
9603 if (ASC_NARROW_BOARD(boardp)) {
9604 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
9606 /* Reset the chip and SCSI bus. */
9607 ASC_DBG(1, "before AscInitAsc1000Driver()\n");
9608 status = AscInitAsc1000Driver(asc_dvc);
9610 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
9611 if (asc_dvc->err_code) {
9612 scmd_printk(KERN_INFO, scp, "SCSI bus reset error: "
9613 "0x%x\n", asc_dvc->err_code);
9614 ret = FAILED;
9615 } else if (status) {
9616 scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: "
9617 "0x%x\n", status);
9618 } else {
9619 scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9620 "successful\n");
9623 ASC_DBG(1, "after AscInitAsc1000Driver()\n");
9624 spin_lock_irqsave(&boardp->lock, flags);
9625 } else {
9627 * If the suggest reset bus flags are set, then reset the bus.
9628 * Otherwise only reset the device.
9630 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
9633 * Reset the target's SCSI bus.
9635 ASC_DBG(1, "before AdvResetChipAndSB()\n");
9636 switch (AdvResetChipAndSB(adv_dvc)) {
9637 case ASC_TRUE:
9638 scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9639 "successful\n");
9640 break;
9641 case ASC_FALSE:
9642 default:
9643 scmd_printk(KERN_INFO, scp, "SCSI bus reset error\n");
9644 ret = FAILED;
9645 break;
9647 spin_lock_irqsave(&boardp->lock, flags);
9648 AdvISR(adv_dvc);
9651 /* Save the time of the most recently completed reset. */
9652 boardp->last_reset = jiffies;
9653 spin_unlock_irqrestore(&boardp->lock, flags);
9655 ASC_DBG(1, "ret %d\n", ret);
9657 return ret;
9661 * advansys_biosparam()
9663 * Translate disk drive geometry if the "BIOS greater than 1 GB"
9664 * support is enabled for a drive.
9666 * ip (information pointer) is an int array with the following definition:
9667 * ip[0]: heads
9668 * ip[1]: sectors
9669 * ip[2]: cylinders
9671 static int
9672 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
9673 sector_t capacity, int ip[])
9675 struct asc_board *boardp = shost_priv(sdev->host);
9677 ASC_DBG(1, "begin\n");
9678 ASC_STATS(sdev->host, biosparam);
9679 if (ASC_NARROW_BOARD(boardp)) {
9680 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
9681 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
9682 ip[0] = 255;
9683 ip[1] = 63;
9684 } else {
9685 ip[0] = 64;
9686 ip[1] = 32;
9688 } else {
9689 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
9690 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
9691 ip[0] = 255;
9692 ip[1] = 63;
9693 } else {
9694 ip[0] = 64;
9695 ip[1] = 32;
9698 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
9699 ASC_DBG(1, "end\n");
9700 return 0;
9704 * First-level interrupt handler.
9706 * 'dev_id' is a pointer to the interrupting adapter's Scsi_Host.
9708 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
9710 unsigned long flags;
9711 struct Scsi_Host *shost = dev_id;
9712 struct asc_board *boardp = shost_priv(shost);
9713 irqreturn_t result = IRQ_NONE;
9715 ASC_DBG(2, "boardp 0x%p\n", boardp);
9716 spin_lock_irqsave(&boardp->lock, flags);
9717 if (ASC_NARROW_BOARD(boardp)) {
9718 if (AscIsIntPending(shost->io_port)) {
9719 result = IRQ_HANDLED;
9720 ASC_STATS(shost, interrupt);
9721 ASC_DBG(1, "before AscISR()\n");
9722 AscISR(&boardp->dvc_var.asc_dvc_var);
9724 } else {
9725 ASC_DBG(1, "before AdvISR()\n");
9726 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
9727 result = IRQ_HANDLED;
9728 ASC_STATS(shost, interrupt);
9731 spin_unlock_irqrestore(&boardp->lock, flags);
9733 ASC_DBG(1, "end\n");
9734 return result;
9737 static int AscHostReqRiscHalt(PortAddr iop_base)
9739 int count = 0;
9740 int sta = 0;
9741 uchar saved_stop_code;
9743 if (AscIsChipHalted(iop_base))
9744 return (1);
9745 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
9746 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9747 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
9748 do {
9749 if (AscIsChipHalted(iop_base)) {
9750 sta = 1;
9751 break;
9753 mdelay(100);
9754 } while (count++ < 20);
9755 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
9756 return (sta);
9759 static int
9760 AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9762 int sta = FALSE;
9764 if (AscHostReqRiscHalt(iop_base)) {
9765 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9766 AscStartChip(iop_base);
9768 return sta;
9771 static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
9773 char type = sdev->type;
9774 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
9776 if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN))
9777 return;
9778 if (asc_dvc->init_sdtr & tid_bits)
9779 return;
9781 if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0))
9782 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
9784 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
9785 if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) ||
9786 (type == TYPE_ROM) || (type == TYPE_TAPE))
9787 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
9789 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
9790 AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id,
9791 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
9794 static void
9795 advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
9797 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
9798 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
9800 if (sdev->lun == 0) {
9801 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
9802 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
9803 asc_dvc->init_sdtr |= tid_bit;
9804 } else {
9805 asc_dvc->init_sdtr &= ~tid_bit;
9808 if (orig_init_sdtr != asc_dvc->init_sdtr)
9809 AscAsyncFix(asc_dvc, sdev);
9812 if (sdev->tagged_supported) {
9813 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
9814 if (sdev->lun == 0) {
9815 asc_dvc->cfg->can_tagged_qng |= tid_bit;
9816 asc_dvc->use_tagged_qng |= tid_bit;
9818 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
9819 asc_dvc->max_dvc_qng[sdev->id]);
9821 } else {
9822 if (sdev->lun == 0) {
9823 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
9824 asc_dvc->use_tagged_qng &= ~tid_bit;
9826 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
9829 if ((sdev->lun == 0) &&
9830 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
9831 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
9832 asc_dvc->cfg->disc_enable);
9833 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
9834 asc_dvc->use_tagged_qng);
9835 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
9836 asc_dvc->cfg->can_tagged_qng);
9838 asc_dvc->max_dvc_qng[sdev->id] =
9839 asc_dvc->cfg->max_tag_qng[sdev->id];
9840 AscWriteLramByte(asc_dvc->iop_base,
9841 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
9842 asc_dvc->max_dvc_qng[sdev->id]);
9847 * Wide Transfers
9849 * If the EEPROM enabled WDTR for the device and the device supports wide
9850 * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
9851 * write the new value to the microcode.
9853 static void
9854 advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
9856 unsigned short cfg_word;
9857 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
9858 if ((cfg_word & tidmask) != 0)
9859 return;
9861 cfg_word |= tidmask;
9862 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
9865 * Clear the microcode SDTR and WDTR negotiation done indicators for
9866 * the target to cause it to negotiate with the new setting set above.
9867 * WDTR when accepted causes the target to enter asynchronous mode, so
9868 * SDTR must be negotiated.
9870 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9871 cfg_word &= ~tidmask;
9872 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9873 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
9874 cfg_word &= ~tidmask;
9875 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
9879 * Synchronous Transfers
9881 * If the EEPROM enabled SDTR for the device and the device
9882 * supports synchronous transfers, then turn on the device's
9883 * 'sdtr_able' bit. Write the new value to the microcode.
9885 static void
9886 advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
9888 unsigned short cfg_word;
9889 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
9890 if ((cfg_word & tidmask) != 0)
9891 return;
9893 cfg_word |= tidmask;
9894 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
9897 * Clear the microcode "SDTR negotiation" done indicator for the
9898 * target to cause it to negotiate with the new setting set above.
9900 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9901 cfg_word &= ~tidmask;
9902 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9906 * PPR (Parallel Protocol Request) Capable
9908 * If the device supports DT mode, then it must be PPR capable.
9909 * The PPR message will be used in place of the SDTR and WDTR
9910 * messages to negotiate synchronous speed and offset, transfer
9911 * width, and protocol options.
9913 static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
9914 AdvPortAddr iop_base, unsigned short tidmask)
9916 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
9917 adv_dvc->ppr_able |= tidmask;
9918 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
9921 static void
9922 advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
9924 AdvPortAddr iop_base = adv_dvc->iop_base;
9925 unsigned short tidmask = 1 << sdev->id;
9927 if (sdev->lun == 0) {
9929 * Handle WDTR, SDTR, and Tag Queuing. If the feature
9930 * is enabled in the EEPROM and the device supports the
9931 * feature, then enable it in the microcode.
9934 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
9935 advansys_wide_enable_wdtr(iop_base, tidmask);
9936 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
9937 advansys_wide_enable_sdtr(iop_base, tidmask);
9938 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
9939 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
9942 * Tag Queuing is disabled for the BIOS which runs in polled
9943 * mode and would see no benefit from Tag Queuing. Also by
9944 * disabling Tag Queuing in the BIOS devices with Tag Queuing
9945 * bugs will at least work with the BIOS.
9947 if ((adv_dvc->tagqng_able & tidmask) &&
9948 sdev->tagged_supported) {
9949 unsigned short cfg_word;
9950 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
9951 cfg_word |= tidmask;
9952 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
9953 cfg_word);
9954 AdvWriteByteLram(iop_base,
9955 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
9956 adv_dvc->max_dvc_qng);
9960 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
9961 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
9962 adv_dvc->max_dvc_qng);
9963 } else {
9964 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
9969 * Set the number of commands to queue per device for the
9970 * specified host adapter.
9972 static int advansys_slave_configure(struct scsi_device *sdev)
9974 struct asc_board *boardp = shost_priv(sdev->host);
9976 if (ASC_NARROW_BOARD(boardp))
9977 advansys_narrow_slave_configure(sdev,
9978 &boardp->dvc_var.asc_dvc_var);
9979 else
9980 advansys_wide_slave_configure(sdev,
9981 &boardp->dvc_var.adv_dvc_var);
9983 return 0;
9986 static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
9987 struct asc_scsi_q *asc_scsi_q)
9989 memset(asc_scsi_q, 0, sizeof(*asc_scsi_q));
9992 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
9994 asc_scsi_q->q2.srb_ptr = ASC_VADDR_TO_U32(scp);
9997 * Build the ASC_SCSI_Q request.
9999 asc_scsi_q->cdbptr = &scp->cmnd[0];
10000 asc_scsi_q->q2.cdb_len = scp->cmd_len;
10001 asc_scsi_q->q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
10002 asc_scsi_q->q1.target_lun = scp->device->lun;
10003 asc_scsi_q->q2.target_ix =
10004 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
10005 asc_scsi_q->q1.sense_addr =
10006 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
10007 asc_scsi_q->q1.sense_len = sizeof(scp->sense_buffer);
10010 * If there are any outstanding requests for the current target,
10011 * then every 255th request send an ORDERED request. This heuristic
10012 * tries to retain the benefit of request sorting while preventing
10013 * request starvation. 255 is the max number of tags or pending commands
10014 * a device may have outstanding.
10016 * The request count is incremented below for every successfully
10017 * started request.
10020 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
10021 (boardp->reqcnt[scp->device->id] % 255) == 0) {
10022 asc_scsi_q->q2.tag_code = MSG_ORDERED_TAG;
10023 } else {
10024 asc_scsi_q->q2.tag_code = MSG_SIMPLE_TAG;
10028 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
10029 * buffer command.
10031 if (scp->use_sg == 0) {
10033 * CDB request of single contiguous buffer.
10035 ASC_STATS(scp->device->host, cont_cnt);
10036 scp->SCp.dma_handle = scp->request_bufflen ?
10037 dma_map_single(boardp->dev, scp->request_buffer,
10038 scp->request_bufflen,
10039 scp->sc_data_direction) : 0;
10040 asc_scsi_q->q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
10041 asc_scsi_q->q1.data_cnt = cpu_to_le32(scp->request_bufflen);
10042 ASC_STATS_ADD(scp->device->host, cont_xfer,
10043 ASC_CEILING(scp->request_bufflen, 512));
10044 asc_scsi_q->q1.sg_queue_cnt = 0;
10045 asc_scsi_q->sg_head = NULL;
10046 } else {
10048 * CDB scatter-gather request list.
10050 int sgcnt;
10051 int use_sg;
10052 struct scatterlist *slp;
10053 struct asc_sg_head *asc_sg_head;
10055 slp = (struct scatterlist *)scp->request_buffer;
10056 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
10057 scp->sc_data_direction);
10059 if (use_sg > scp->device->host->sg_tablesize) {
10060 ASC_PRINT3("asc_build_req: board %d: use_sg %d > "
10061 "sg_tablesize %d\n", boardp->id, use_sg,
10062 scp->device->host->sg_tablesize);
10063 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10064 scp->sc_data_direction);
10065 scp->result = HOST_BYTE(DID_ERROR);
10066 return ASC_ERROR;
10069 ASC_STATS(scp->device->host, sg_cnt);
10071 asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) +
10072 use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC);
10073 if (!asc_sg_head) {
10074 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10075 scp->sc_data_direction);
10076 scp->result = HOST_BYTE(DID_SOFT_ERROR);
10077 return ASC_ERROR;
10080 asc_scsi_q->q1.cntl |= QC_SG_HEAD;
10081 asc_scsi_q->sg_head = asc_sg_head;
10082 asc_scsi_q->q1.data_cnt = 0;
10083 asc_scsi_q->q1.data_addr = 0;
10084 /* This is a byte value, otherwise it would need to be swapped. */
10085 asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg;
10086 ASC_STATS_ADD(scp->device->host, sg_elem,
10087 asc_sg_head->entry_cnt);
10090 * Convert scatter-gather list into ASC_SG_HEAD list.
10092 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
10093 asc_sg_head->sg_list[sgcnt].addr =
10094 cpu_to_le32(sg_dma_address(slp));
10095 asc_sg_head->sg_list[sgcnt].bytes =
10096 cpu_to_le32(sg_dma_len(slp));
10097 ASC_STATS_ADD(scp->device->host, sg_xfer,
10098 ASC_CEILING(sg_dma_len(slp), 512));
10102 ASC_DBG_PRT_ASC_SCSI_Q(2, asc_scsi_q);
10103 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
10105 return ASC_NOERROR;
10109 * Build scatter-gather list for Adv Library (Wide Board).
10111 * Additional ADV_SG_BLOCK structures will need to be allocated
10112 * if the total number of scatter-gather elements exceeds
10113 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
10114 * assumed to be physically contiguous.
10116 * Return:
10117 * ADV_SUCCESS(1) - SG List successfully created
10118 * ADV_ERROR(-1) - SG List creation failed
10120 static int
10121 adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
10122 int use_sg)
10124 adv_sgblk_t *sgblkp;
10125 ADV_SCSI_REQ_Q *scsiqp;
10126 struct scatterlist *slp;
10127 int sg_elem_cnt;
10128 ADV_SG_BLOCK *sg_block, *prev_sg_block;
10129 ADV_PADDR sg_block_paddr;
10130 int i;
10132 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
10133 slp = (struct scatterlist *)scp->request_buffer;
10134 sg_elem_cnt = use_sg;
10135 prev_sg_block = NULL;
10136 reqp->sgblkp = NULL;
10138 for (;;) {
10140 * Allocate a 'adv_sgblk_t' structure from the board free
10141 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
10142 * (15) scatter-gather elements.
10144 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
10145 ASC_DBG(1, "no free adv_sgblk_t\n");
10146 ASC_STATS(scp->device->host, adv_build_nosg);
10149 * Allocation failed. Free 'adv_sgblk_t' structures
10150 * already allocated for the request.
10152 while ((sgblkp = reqp->sgblkp) != NULL) {
10153 /* Remove 'sgblkp' from the request list. */
10154 reqp->sgblkp = sgblkp->next_sgblkp;
10156 /* Add 'sgblkp' to the board free list. */
10157 sgblkp->next_sgblkp = boardp->adv_sgblkp;
10158 boardp->adv_sgblkp = sgblkp;
10160 return ASC_BUSY;
10163 /* Complete 'adv_sgblk_t' board allocation. */
10164 boardp->adv_sgblkp = sgblkp->next_sgblkp;
10165 sgblkp->next_sgblkp = NULL;
10168 * Get 8 byte aligned virtual and physical addresses
10169 * for the allocated ADV_SG_BLOCK structure.
10171 sg_block = (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
10172 sg_block_paddr = virt_to_bus(sg_block);
10175 * Check if this is the first 'adv_sgblk_t' for the
10176 * request.
10178 if (reqp->sgblkp == NULL) {
10179 /* Request's first scatter-gather block. */
10180 reqp->sgblkp = sgblkp;
10183 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
10184 * address pointers.
10186 scsiqp->sg_list_ptr = sg_block;
10187 scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
10188 } else {
10189 /* Request's second or later scatter-gather block. */
10190 sgblkp->next_sgblkp = reqp->sgblkp;
10191 reqp->sgblkp = sgblkp;
10194 * Point the previous ADV_SG_BLOCK structure to
10195 * the newly allocated ADV_SG_BLOCK structure.
10197 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
10200 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
10201 sg_block->sg_list[i].sg_addr =
10202 cpu_to_le32(sg_dma_address(slp));
10203 sg_block->sg_list[i].sg_count =
10204 cpu_to_le32(sg_dma_len(slp));
10205 ASC_STATS_ADD(scp->device->host, sg_xfer,
10206 ASC_CEILING(sg_dma_len(slp), 512));
10208 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
10209 sg_block->sg_cnt = i + 1;
10210 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
10211 return ADV_SUCCESS;
10213 slp++;
10215 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
10216 prev_sg_block = sg_block;
10221 * Build a request structure for the Adv Library (Wide Board).
10223 * If an adv_req_t can not be allocated to issue the request,
10224 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
10226 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
10227 * microcode for DMA addresses or math operations are byte swapped
10228 * to little-endian order.
10230 static int
10231 adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
10232 ADV_SCSI_REQ_Q **adv_scsiqpp)
10234 adv_req_t *reqp;
10235 ADV_SCSI_REQ_Q *scsiqp;
10236 int i;
10237 int ret;
10240 * Allocate an adv_req_t structure from the board to execute
10241 * the command.
10243 if (boardp->adv_reqp == NULL) {
10244 ASC_DBG(1, "no free adv_req_t\n");
10245 ASC_STATS(scp->device->host, adv_build_noreq);
10246 return ASC_BUSY;
10247 } else {
10248 reqp = boardp->adv_reqp;
10249 boardp->adv_reqp = reqp->next_reqp;
10250 reqp->next_reqp = NULL;
10254 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
10256 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
10259 * Initialize the structure.
10261 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
10264 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
10266 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
10269 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
10271 reqp->cmndp = scp;
10274 * Build the ADV_SCSI_REQ_Q request.
10277 /* Set CDB length and copy it to the request structure. */
10278 scsiqp->cdb_len = scp->cmd_len;
10279 /* Copy first 12 CDB bytes to cdb[]. */
10280 for (i = 0; i < scp->cmd_len && i < 12; i++) {
10281 scsiqp->cdb[i] = scp->cmnd[i];
10283 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
10284 for (; i < scp->cmd_len; i++) {
10285 scsiqp->cdb16[i - 12] = scp->cmnd[i];
10288 scsiqp->target_id = scp->device->id;
10289 scsiqp->target_lun = scp->device->lun;
10291 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
10292 scsiqp->sense_len = sizeof(scp->sense_buffer);
10295 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
10296 * buffer command.
10299 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
10300 scsiqp->vdata_addr = scp->request_buffer;
10301 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
10303 if (scp->use_sg == 0) {
10305 * CDB request of single contiguous buffer.
10307 reqp->sgblkp = NULL;
10308 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
10309 if (scp->request_bufflen) {
10310 scsiqp->vdata_addr = scp->request_buffer;
10311 scp->SCp.dma_handle =
10312 dma_map_single(boardp->dev, scp->request_buffer,
10313 scp->request_bufflen,
10314 scp->sc_data_direction);
10315 } else {
10316 scsiqp->vdata_addr = NULL;
10317 scp->SCp.dma_handle = 0;
10319 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
10320 scsiqp->sg_list_ptr = NULL;
10321 scsiqp->sg_real_addr = 0;
10322 ASC_STATS(scp->device->host, cont_cnt);
10323 ASC_STATS_ADD(scp->device->host, cont_xfer,
10324 ASC_CEILING(scp->request_bufflen, 512));
10325 } else {
10327 * CDB scatter-gather request list.
10329 struct scatterlist *slp;
10330 int use_sg;
10332 slp = (struct scatterlist *)scp->request_buffer;
10333 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
10334 scp->sc_data_direction);
10336 if (use_sg > ADV_MAX_SG_LIST) {
10337 ASC_PRINT3("adv_build_req: board %d: use_sg %d > "
10338 "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg,
10339 scp->device->host->sg_tablesize);
10340 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10341 scp->sc_data_direction);
10342 scp->result = HOST_BYTE(DID_ERROR);
10345 * Free the 'adv_req_t' structure by adding it back
10346 * to the board free list.
10348 reqp->next_reqp = boardp->adv_reqp;
10349 boardp->adv_reqp = reqp;
10351 return ASC_ERROR;
10354 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
10355 if (ret != ADV_SUCCESS) {
10357 * Free the adv_req_t structure by adding it back to
10358 * the board free list.
10360 reqp->next_reqp = boardp->adv_reqp;
10361 boardp->adv_reqp = reqp;
10363 return ret;
10366 ASC_STATS(scp->device->host, sg_cnt);
10367 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
10370 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
10371 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
10373 *adv_scsiqpp = scsiqp;
10375 return ASC_NOERROR;
10378 static int AscSgListToQueue(int sg_list)
10380 int n_sg_list_qs;
10382 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
10383 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
10384 n_sg_list_qs++;
10385 return n_sg_list_qs + 1;
10388 static uint
10389 AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
10391 uint cur_used_qs;
10392 uint cur_free_qs;
10393 ASC_SCSI_BIT_ID_TYPE target_id;
10394 uchar tid_no;
10396 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
10397 tid_no = ASC_TIX_TO_TID(target_ix);
10398 if ((asc_dvc->unit_not_ready & target_id) ||
10399 (asc_dvc->queue_full_or_busy & target_id)) {
10400 return 0;
10402 if (n_qs == 1) {
10403 cur_used_qs = (uint) asc_dvc->cur_total_qng +
10404 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
10405 } else {
10406 cur_used_qs = (uint) asc_dvc->cur_total_qng +
10407 (uint) ASC_MIN_FREE_Q;
10409 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
10410 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
10411 if (asc_dvc->cur_dvc_qng[tid_no] >=
10412 asc_dvc->max_dvc_qng[tid_no]) {
10413 return 0;
10415 return cur_free_qs;
10417 if (n_qs > 1) {
10418 if ((n_qs > asc_dvc->last_q_shortage)
10419 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
10420 asc_dvc->last_q_shortage = n_qs;
10423 return 0;
10426 static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
10428 ushort q_addr;
10429 uchar next_qp;
10430 uchar q_status;
10432 q_addr = ASC_QNO_TO_QADDR(free_q_head);
10433 q_status = (uchar)AscReadLramByte(iop_base,
10434 (ushort)(q_addr +
10435 ASC_SCSIQ_B_STATUS));
10436 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10437 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END))
10438 return next_qp;
10439 return ASC_QLINK_END;
10442 static uchar
10443 AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
10445 uchar i;
10447 for (i = 0; i < n_free_q; i++) {
10448 free_q_head = AscAllocFreeQueue(iop_base, free_q_head);
10449 if (free_q_head == ASC_QLINK_END)
10450 break;
10452 return free_q_head;
10456 * void
10457 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10459 * Calling/Exit State:
10460 * none
10462 * Description:
10463 * Output an ASC_SCSI_Q structure to the chip
10465 static void
10466 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10468 int i;
10470 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
10471 AscSetChipLramAddr(iop_base, s_addr);
10472 for (i = 0; i < 2 * words; i += 2) {
10473 if (i == 4 || i == 20) {
10474 continue;
10476 outpw(iop_base + IOP_RAM_DATA,
10477 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
10481 static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10483 ushort q_addr;
10484 uchar tid_no;
10485 uchar sdtr_data;
10486 uchar syn_period_ix;
10487 uchar syn_offset;
10488 PortAddr iop_base;
10490 iop_base = asc_dvc->iop_base;
10491 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
10492 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
10493 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
10494 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10495 syn_period_ix =
10496 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
10497 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
10498 AscMsgOutSDTR(asc_dvc,
10499 asc_dvc->sdtr_period_tbl[syn_period_ix],
10500 syn_offset);
10501 scsiq->q1.cntl |= QC_MSG_OUT;
10503 q_addr = ASC_QNO_TO_QADDR(q_no);
10504 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
10505 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10507 scsiq->q1.status = QS_FREE;
10508 AscMemWordCopyPtrToLram(iop_base,
10509 q_addr + ASC_SCSIQ_CDB_BEG,
10510 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
10512 DvcPutScsiQ(iop_base,
10513 q_addr + ASC_SCSIQ_CPY_BEG,
10514 (uchar *)&scsiq->q1.cntl,
10515 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
10516 AscWriteLramWord(iop_base,
10517 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
10518 (ushort)(((ushort)scsiq->q1.
10519 q_no << 8) | (ushort)QS_READY));
10520 return 1;
10523 static int
10524 AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10526 int sta;
10527 int i;
10528 ASC_SG_HEAD *sg_head;
10529 ASC_SG_LIST_Q scsi_sg_q;
10530 ASC_DCNT saved_data_addr;
10531 ASC_DCNT saved_data_cnt;
10532 PortAddr iop_base;
10533 ushort sg_list_dwords;
10534 ushort sg_index;
10535 ushort sg_entry_cnt;
10536 ushort q_addr;
10537 uchar next_qp;
10539 iop_base = asc_dvc->iop_base;
10540 sg_head = scsiq->sg_head;
10541 saved_data_addr = scsiq->q1.data_addr;
10542 saved_data_cnt = scsiq->q1.data_cnt;
10543 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
10544 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
10545 #if CC_VERY_LONG_SG_LIST
10547 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
10548 * then not all SG elements will fit in the allocated queues.
10549 * The rest of the SG elements will be copied when the RISC
10550 * completes the SG elements that fit and halts.
10552 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10554 * Set sg_entry_cnt to be the number of SG elements that
10555 * will fit in the allocated SG queues. It is minus 1, because
10556 * the first SG element is handled above. ASC_MAX_SG_LIST is
10557 * already inflated by 1 to account for this. For example it
10558 * may be 50 which is 1 + 7 queues * 7 SG elements.
10560 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10563 * Keep track of remaining number of SG elements that will
10564 * need to be handled from a_isr.c.
10566 scsiq->remain_sg_entry_cnt =
10567 sg_head->entry_cnt - ASC_MAX_SG_LIST;
10568 } else {
10569 #endif /* CC_VERY_LONG_SG_LIST */
10571 * Set sg_entry_cnt to be the number of SG elements that
10572 * will fit in the allocated SG queues. It is minus 1, because
10573 * the first SG element is handled above.
10575 sg_entry_cnt = sg_head->entry_cnt - 1;
10576 #if CC_VERY_LONG_SG_LIST
10578 #endif /* CC_VERY_LONG_SG_LIST */
10579 if (sg_entry_cnt != 0) {
10580 scsiq->q1.cntl |= QC_SG_HEAD;
10581 q_addr = ASC_QNO_TO_QADDR(q_no);
10582 sg_index = 1;
10583 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
10584 scsi_sg_q.sg_head_qp = q_no;
10585 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10586 for (i = 0; i < sg_head->queue_cnt; i++) {
10587 scsi_sg_q.seq_no = i + 1;
10588 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
10589 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
10590 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10591 if (i == 0) {
10592 scsi_sg_q.sg_list_cnt =
10593 ASC_SG_LIST_PER_Q;
10594 scsi_sg_q.sg_cur_list_cnt =
10595 ASC_SG_LIST_PER_Q;
10596 } else {
10597 scsi_sg_q.sg_list_cnt =
10598 ASC_SG_LIST_PER_Q - 1;
10599 scsi_sg_q.sg_cur_list_cnt =
10600 ASC_SG_LIST_PER_Q - 1;
10602 } else {
10603 #if CC_VERY_LONG_SG_LIST
10605 * This is the last SG queue in the list of
10606 * allocated SG queues. If there are more
10607 * SG elements than will fit in the allocated
10608 * queues, then set the QCSG_SG_XFER_MORE flag.
10610 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10611 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10612 } else {
10613 #endif /* CC_VERY_LONG_SG_LIST */
10614 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10615 #if CC_VERY_LONG_SG_LIST
10617 #endif /* CC_VERY_LONG_SG_LIST */
10618 sg_list_dwords = sg_entry_cnt << 1;
10619 if (i == 0) {
10620 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
10621 scsi_sg_q.sg_cur_list_cnt =
10622 sg_entry_cnt;
10623 } else {
10624 scsi_sg_q.sg_list_cnt =
10625 sg_entry_cnt - 1;
10626 scsi_sg_q.sg_cur_list_cnt =
10627 sg_entry_cnt - 1;
10629 sg_entry_cnt = 0;
10631 next_qp = AscReadLramByte(iop_base,
10632 (ushort)(q_addr +
10633 ASC_SCSIQ_B_FWD));
10634 scsi_sg_q.q_no = next_qp;
10635 q_addr = ASC_QNO_TO_QADDR(next_qp);
10636 AscMemWordCopyPtrToLram(iop_base,
10637 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10638 (uchar *)&scsi_sg_q,
10639 sizeof(ASC_SG_LIST_Q) >> 1);
10640 AscMemDWordCopyPtrToLram(iop_base,
10641 q_addr + ASC_SGQ_LIST_BEG,
10642 (uchar *)&sg_head->
10643 sg_list[sg_index],
10644 sg_list_dwords);
10645 sg_index += ASC_SG_LIST_PER_Q;
10646 scsiq->next_sg_index = sg_index;
10648 } else {
10649 scsiq->q1.cntl &= ~QC_SG_HEAD;
10651 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
10652 scsiq->q1.data_addr = saved_data_addr;
10653 scsiq->q1.data_cnt = saved_data_cnt;
10654 return (sta);
10657 static int
10658 AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
10660 PortAddr iop_base;
10661 uchar free_q_head;
10662 uchar next_qp;
10663 uchar tid_no;
10664 uchar target_ix;
10665 int sta;
10667 iop_base = asc_dvc->iop_base;
10668 target_ix = scsiq->q2.target_ix;
10669 tid_no = ASC_TIX_TO_TID(target_ix);
10670 sta = 0;
10671 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
10672 if (n_q_required > 1) {
10673 next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head,
10674 (uchar)n_q_required);
10675 if (next_qp != ASC_QLINK_END) {
10676 asc_dvc->last_q_shortage = 0;
10677 scsiq->sg_head->queue_cnt = n_q_required - 1;
10678 scsiq->q1.q_no = free_q_head;
10679 sta = AscPutReadySgListQueue(asc_dvc, scsiq,
10680 free_q_head);
10682 } else if (n_q_required == 1) {
10683 next_qp = AscAllocFreeQueue(iop_base, free_q_head);
10684 if (next_qp != ASC_QLINK_END) {
10685 scsiq->q1.q_no = free_q_head;
10686 sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head);
10689 if (sta == 1) {
10690 AscPutVarFreeQHead(iop_base, next_qp);
10691 asc_dvc->cur_total_qng += n_q_required;
10692 asc_dvc->cur_dvc_qng[tid_no]++;
10694 return sta;
10697 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
10698 static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
10699 INQUIRY,
10700 REQUEST_SENSE,
10701 READ_CAPACITY,
10702 READ_TOC,
10703 MODE_SELECT,
10704 MODE_SENSE,
10705 MODE_SELECT_10,
10706 MODE_SENSE_10,
10707 0xFF,
10708 0xFF,
10709 0xFF,
10710 0xFF,
10711 0xFF,
10712 0xFF,
10713 0xFF,
10714 0xFF
10717 static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
10719 PortAddr iop_base;
10720 int sta;
10721 int n_q_required;
10722 int disable_syn_offset_one_fix;
10723 int i;
10724 ASC_PADDR addr;
10725 ushort sg_entry_cnt = 0;
10726 ushort sg_entry_cnt_minus_one = 0;
10727 uchar target_ix;
10728 uchar tid_no;
10729 uchar sdtr_data;
10730 uchar extra_bytes;
10731 uchar scsi_cmd;
10732 uchar disable_cmd;
10733 ASC_SG_HEAD *sg_head;
10734 ASC_DCNT data_cnt;
10736 iop_base = asc_dvc->iop_base;
10737 sg_head = scsiq->sg_head;
10738 if (asc_dvc->err_code != 0)
10739 return (ERR);
10740 scsiq->q1.q_no = 0;
10741 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
10742 scsiq->q1.extra_bytes = 0;
10744 sta = 0;
10745 target_ix = scsiq->q2.target_ix;
10746 tid_no = ASC_TIX_TO_TID(target_ix);
10747 n_q_required = 1;
10748 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
10749 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
10750 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
10751 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10752 AscMsgOutSDTR(asc_dvc,
10753 asc_dvc->
10754 sdtr_period_tbl[(sdtr_data >> 4) &
10755 (uchar)(asc_dvc->
10756 max_sdtr_index -
10757 1)],
10758 (uchar)(sdtr_data & (uchar)
10759 ASC_SYN_MAX_OFFSET));
10760 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
10763 if (asc_dvc->in_critical_cnt != 0) {
10764 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
10765 return (ERR);
10767 asc_dvc->in_critical_cnt++;
10768 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10769 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
10770 asc_dvc->in_critical_cnt--;
10771 return (ERR);
10773 #if !CC_VERY_LONG_SG_LIST
10774 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
10775 asc_dvc->in_critical_cnt--;
10776 return (ERR);
10778 #endif /* !CC_VERY_LONG_SG_LIST */
10779 if (sg_entry_cnt == 1) {
10780 scsiq->q1.data_addr =
10781 (ADV_PADDR)sg_head->sg_list[0].addr;
10782 scsiq->q1.data_cnt =
10783 (ADV_DCNT)sg_head->sg_list[0].bytes;
10784 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
10786 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
10788 scsi_cmd = scsiq->cdbptr[0];
10789 disable_syn_offset_one_fix = FALSE;
10790 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
10791 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
10792 if (scsiq->q1.cntl & QC_SG_HEAD) {
10793 data_cnt = 0;
10794 for (i = 0; i < sg_entry_cnt; i++) {
10795 data_cnt +=
10796 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
10797 bytes);
10799 } else {
10800 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10802 if (data_cnt != 0UL) {
10803 if (data_cnt < 512UL) {
10804 disable_syn_offset_one_fix = TRUE;
10805 } else {
10806 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
10807 i++) {
10808 disable_cmd =
10809 _syn_offset_one_disable_cmd[i];
10810 if (disable_cmd == 0xFF) {
10811 break;
10813 if (scsi_cmd == disable_cmd) {
10814 disable_syn_offset_one_fix =
10815 TRUE;
10816 break;
10822 if (disable_syn_offset_one_fix) {
10823 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10824 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
10825 ASC_TAG_FLAG_DISABLE_DISCONNECT);
10826 } else {
10827 scsiq->q2.tag_code &= 0x27;
10829 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10830 if (asc_dvc->bug_fix_cntl) {
10831 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10832 if ((scsi_cmd == READ_6) ||
10833 (scsi_cmd == READ_10)) {
10834 addr =
10835 (ADV_PADDR)le32_to_cpu(sg_head->
10836 sg_list
10837 [sg_entry_cnt_minus_one].
10838 addr) +
10839 (ADV_DCNT)le32_to_cpu(sg_head->
10840 sg_list
10841 [sg_entry_cnt_minus_one].
10842 bytes);
10843 extra_bytes =
10844 (uchar)((ushort)addr & 0x0003);
10845 if ((extra_bytes != 0)
10847 ((scsiq->q2.
10848 tag_code &
10849 ASC_TAG_FLAG_EXTRA_BYTES)
10850 == 0)) {
10851 scsiq->q2.tag_code |=
10852 ASC_TAG_FLAG_EXTRA_BYTES;
10853 scsiq->q1.extra_bytes =
10854 extra_bytes;
10855 data_cnt =
10856 le32_to_cpu(sg_head->
10857 sg_list
10858 [sg_entry_cnt_minus_one].
10859 bytes);
10860 data_cnt -=
10861 (ASC_DCNT) extra_bytes;
10862 sg_head->
10863 sg_list
10864 [sg_entry_cnt_minus_one].
10865 bytes =
10866 cpu_to_le32(data_cnt);
10871 sg_head->entry_to_copy = sg_head->entry_cnt;
10872 #if CC_VERY_LONG_SG_LIST
10874 * Set the sg_entry_cnt to the maximum possible. The rest of
10875 * the SG elements will be copied when the RISC completes the
10876 * SG elements that fit and halts.
10878 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
10879 sg_entry_cnt = ASC_MAX_SG_LIST;
10881 #endif /* CC_VERY_LONG_SG_LIST */
10882 n_q_required = AscSgListToQueue(sg_entry_cnt);
10883 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
10884 (uint) n_q_required)
10885 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10886 if ((sta =
10887 AscSendScsiQueue(asc_dvc, scsiq,
10888 n_q_required)) == 1) {
10889 asc_dvc->in_critical_cnt--;
10890 return (sta);
10893 } else {
10894 if (asc_dvc->bug_fix_cntl) {
10895 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10896 if ((scsi_cmd == READ_6) ||
10897 (scsi_cmd == READ_10)) {
10898 addr =
10899 le32_to_cpu(scsiq->q1.data_addr) +
10900 le32_to_cpu(scsiq->q1.data_cnt);
10901 extra_bytes =
10902 (uchar)((ushort)addr & 0x0003);
10903 if ((extra_bytes != 0)
10905 ((scsiq->q2.
10906 tag_code &
10907 ASC_TAG_FLAG_EXTRA_BYTES)
10908 == 0)) {
10909 data_cnt =
10910 le32_to_cpu(scsiq->q1.
10911 data_cnt);
10912 if (((ushort)data_cnt & 0x01FF)
10913 == 0) {
10914 scsiq->q2.tag_code |=
10915 ASC_TAG_FLAG_EXTRA_BYTES;
10916 data_cnt -= (ASC_DCNT)
10917 extra_bytes;
10918 scsiq->q1.data_cnt =
10919 cpu_to_le32
10920 (data_cnt);
10921 scsiq->q1.extra_bytes =
10922 extra_bytes;
10928 n_q_required = 1;
10929 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
10930 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10931 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
10932 n_q_required)) == 1) {
10933 asc_dvc->in_critical_cnt--;
10934 return (sta);
10938 asc_dvc->in_critical_cnt--;
10939 return (sta);
10943 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
10945 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
10946 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
10947 * RISC to notify it a new command is ready to be executed.
10949 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
10950 * set to SCSI_MAX_RETRY.
10952 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
10953 * for DMA addresses or math operations are byte swapped to little-endian
10954 * order.
10956 * Return:
10957 * ADV_SUCCESS(1) - The request was successfully queued.
10958 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
10959 * request completes.
10960 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
10961 * host IC error.
10963 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
10965 AdvPortAddr iop_base;
10966 ADV_DCNT req_size;
10967 ADV_PADDR req_paddr;
10968 ADV_CARR_T *new_carrp;
10971 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
10973 if (scsiq->target_id > ADV_MAX_TID) {
10974 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
10975 scsiq->done_status = QD_WITH_ERROR;
10976 return ADV_ERROR;
10979 iop_base = asc_dvc->iop_base;
10982 * Allocate a carrier ensuring at least one carrier always
10983 * remains on the freelist and initialize fields.
10985 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
10986 return ADV_BUSY;
10988 asc_dvc->carr_freelist = (ADV_CARR_T *)
10989 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
10990 asc_dvc->carr_pending_cnt++;
10993 * Set the carrier to be a stopper by setting 'next_vpa'
10994 * to the stopper value. The current stopper will be changed
10995 * below to point to the new stopper.
10997 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
11000 * Clear the ADV_SCSI_REQ_Q done flag.
11002 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
11004 req_size = sizeof(ADV_SCSI_REQ_Q);
11005 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
11006 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
11008 BUG_ON(req_paddr & 31);
11009 BUG_ON(req_size < sizeof(ADV_SCSI_REQ_Q));
11011 /* Wait for assertion before making little-endian */
11012 req_paddr = cpu_to_le32(req_paddr);
11014 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
11015 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
11016 scsiq->scsiq_rptr = req_paddr;
11018 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
11020 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
11021 * order during initialization.
11023 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
11026 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
11027 * the microcode. The newly allocated stopper will become the new
11028 * stopper.
11030 asc_dvc->icq_sp->areq_vpa = req_paddr;
11033 * Set the 'next_vpa' pointer for the old stopper to be the
11034 * physical address of the new stopper. The RISC can only
11035 * follow physical addresses.
11037 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
11040 * Set the host adapter stopper pointer to point to the new carrier.
11042 asc_dvc->icq_sp = new_carrp;
11044 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
11045 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
11047 * Tickle the RISC to tell it to read its Command Queue Head pointer.
11049 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
11050 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
11052 * Clear the tickle value. In the ASC-3550 the RISC flag
11053 * command 'clr_tickle_a' does not work unless the host
11054 * value is cleared.
11056 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
11057 ADV_TICKLE_NOP);
11059 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
11061 * Notify the RISC a carrier is ready by writing the physical
11062 * address of the new carrier stopper to the COMMA register.
11064 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
11065 le32_to_cpu(new_carrp->carr_pa));
11068 return ADV_SUCCESS;
11072 * Execute a single 'Scsi_Cmnd'.
11074 * The function 'done' is called when the request has been completed.
11076 * Scsi_Cmnd:
11078 * host - board controlling device
11079 * device - device to send command
11080 * target - target of device
11081 * lun - lun of device
11082 * cmd_len - length of SCSI CDB
11083 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
11084 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
11086 * if (use_sg == 0) {
11087 * request_buffer - buffer address for request
11088 * request_bufflen - length of request buffer
11089 * } else {
11090 * request_buffer - pointer to scatterlist structure
11093 * sense_buffer - sense command buffer
11095 * result (4 bytes of an int):
11096 * Byte Meaning
11097 * 0 SCSI Status Byte Code
11098 * 1 SCSI One Byte Message Code
11099 * 2 Host Error Code
11100 * 3 Mid-Level Error Code
11102 * host driver fields:
11103 * SCp - Scsi_Pointer used for command processing status
11104 * scsi_done - used to save caller's done function
11105 * host_scribble - used for pointer to another struct scsi_cmnd
11107 * If this function returns ASC_NOERROR the request will be completed
11108 * from the interrupt handler.
11110 * If this function returns ASC_ERROR the host error code has been set,
11111 * and the called must call asc_scsi_done.
11113 * If ASC_BUSY is returned the request will be returned to the midlayer
11114 * and re-tried later.
11116 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
11118 int ret, err_code;
11119 struct asc_board *boardp = shost_priv(scp->device->host);
11121 ASC_DBG(1, "scp 0x%p\n", scp);
11123 if (ASC_NARROW_BOARD(boardp)) {
11124 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
11125 struct asc_scsi_q asc_scsi_q;
11127 /* asc_build_req() can not return ASC_BUSY. */
11128 ret = asc_build_req(boardp, scp, &asc_scsi_q);
11129 if (ret == ASC_ERROR) {
11130 ASC_STATS(scp->device->host, build_error);
11131 return ASC_ERROR;
11134 ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q);
11135 kfree(asc_scsi_q.sg_head);
11136 err_code = asc_dvc->err_code;
11137 } else {
11138 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
11139 ADV_SCSI_REQ_Q *adv_scsiqp;
11141 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
11142 case ASC_NOERROR:
11143 ASC_DBG(3, "adv_build_req ASC_NOERROR\n");
11144 break;
11145 case ASC_BUSY:
11146 ASC_DBG(1, "adv_build_req ASC_BUSY\n");
11148 * The asc_stats fields 'adv_build_noreq' and
11149 * 'adv_build_nosg' count wide board busy conditions.
11150 * They are updated in adv_build_req and
11151 * adv_get_sglist, respectively.
11153 return ASC_BUSY;
11154 case ASC_ERROR:
11155 default:
11156 ASC_DBG(1, "adv_build_req ASC_ERROR\n");
11157 ASC_STATS(scp->device->host, build_error);
11158 return ASC_ERROR;
11161 ret = AdvExeScsiQueue(adv_dvc, adv_scsiqp);
11162 err_code = adv_dvc->err_code;
11165 switch (ret) {
11166 case ASC_NOERROR:
11167 ASC_STATS(scp->device->host, exe_noerror);
11169 * Increment monotonically increasing per device
11170 * successful request counter. Wrapping doesn't matter.
11172 boardp->reqcnt[scp->device->id]++;
11173 ASC_DBG(1, "ExeScsiQueue() ASC_NOERROR\n");
11174 break;
11175 case ASC_BUSY:
11176 ASC_STATS(scp->device->host, exe_busy);
11177 break;
11178 case ASC_ERROR:
11179 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: ExeScsiQueue() "
11180 "ASC_ERROR, err_code 0x%x\n", boardp->id, err_code);
11181 ASC_STATS(scp->device->host, exe_error);
11182 scp->result = HOST_BYTE(DID_ERROR);
11183 break;
11184 default:
11185 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: ExeScsiQueue() "
11186 "unknown, err_code 0x%x\n", boardp->id, err_code);
11187 ASC_STATS(scp->device->host, exe_unknown);
11188 scp->result = HOST_BYTE(DID_ERROR);
11189 break;
11192 ASC_DBG(1, "end\n");
11193 return ret;
11197 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
11199 * This function always returns 0. Command return status is saved
11200 * in the 'scp' result field.
11202 static int
11203 advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
11205 struct Scsi_Host *shost = scp->device->host;
11206 struct asc_board *boardp = shost_priv(shost);
11207 unsigned long flags;
11208 int asc_res, result = 0;
11210 ASC_STATS(shost, queuecommand);
11211 scp->scsi_done = done;
11214 * host_lock taken by mid-level prior to call, but need
11215 * to protect against own ISR
11217 spin_lock_irqsave(&boardp->lock, flags);
11218 asc_res = asc_execute_scsi_cmnd(scp);
11219 spin_unlock_irqrestore(&boardp->lock, flags);
11221 switch (asc_res) {
11222 case ASC_NOERROR:
11223 break;
11224 case ASC_BUSY:
11225 result = SCSI_MLQUEUE_HOST_BUSY;
11226 break;
11227 case ASC_ERROR:
11228 default:
11229 asc_scsi_done(scp);
11230 break;
11233 return result;
11236 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
11238 PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11239 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
11240 return inpw(eisa_cfg_iop);
11244 * Return the BIOS address of the adapter at the specified
11245 * I/O port and with the specified bus type.
11247 static unsigned short __devinit
11248 AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
11250 unsigned short cfg_lsw;
11251 unsigned short bios_addr;
11254 * The PCI BIOS is re-located by the motherboard BIOS. Because
11255 * of this the driver can not determine where a PCI BIOS is
11256 * loaded and executes.
11258 if (bus_type & ASC_IS_PCI)
11259 return 0;
11261 if ((bus_type & ASC_IS_EISA) != 0) {
11262 cfg_lsw = AscGetEisaChipCfg(iop_base);
11263 cfg_lsw &= 0x000F;
11264 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
11265 return bios_addr;
11268 cfg_lsw = AscGetChipCfgLsw(iop_base);
11271 * ISA PnP uses the top bit as the 32K BIOS flag
11273 if (bus_type == ASC_IS_ISAPNP)
11274 cfg_lsw &= 0x7FFF;
11275 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
11276 return bios_addr;
11279 static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
11281 ushort cfg_lsw;
11283 if (AscGetChipScsiID(iop_base) == new_host_id) {
11284 return (new_host_id);
11286 cfg_lsw = AscGetChipCfgLsw(iop_base);
11287 cfg_lsw &= 0xF8FF;
11288 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
11289 AscSetChipCfgLsw(iop_base, cfg_lsw);
11290 return (AscGetChipScsiID(iop_base));
11293 static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
11295 unsigned char sc;
11297 AscSetBank(iop_base, 1);
11298 sc = inp(iop_base + IOP_REG_SC);
11299 AscSetBank(iop_base, 0);
11300 return sc;
11303 static unsigned char __devinit
11304 AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
11306 if (bus_type & ASC_IS_EISA) {
11307 PortAddr eisa_iop;
11308 unsigned char revision;
11309 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11310 (PortAddr) ASC_EISA_REV_IOP_MASK;
11311 revision = inp(eisa_iop);
11312 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
11314 return AscGetChipVerNo(iop_base);
11317 #ifdef CONFIG_ISA
11318 static void __devinit AscEnableIsaDma(uchar dma_channel)
11320 if (dma_channel < 4) {
11321 outp(0x000B, (ushort)(0xC0 | dma_channel));
11322 outp(0x000A, dma_channel);
11323 } else if (dma_channel < 8) {
11324 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
11325 outp(0x00D4, (ushort)(dma_channel - 4));
11327 return;
11329 #endif /* CONFIG_ISA */
11331 static int AscStopQueueExe(PortAddr iop_base)
11333 int count = 0;
11335 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11336 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11337 ASC_STOP_REQ_RISC_STOP);
11338 do {
11339 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11340 ASC_STOP_ACK_RISC_STOP) {
11341 return (1);
11343 mdelay(100);
11344 } while (count++ < 20);
11346 return (0);
11349 static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
11351 if (bus_type & ASC_IS_ISA)
11352 return ASC_MAX_ISA_DMA_COUNT;
11353 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
11354 return ASC_MAX_VL_DMA_COUNT;
11355 return ASC_MAX_PCI_DMA_COUNT;
11358 #ifdef CONFIG_ISA
11359 static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
11361 ushort channel;
11363 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
11364 if (channel == 0x03)
11365 return (0);
11366 else if (channel == 0x00)
11367 return (7);
11368 return (channel + 4);
11371 static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
11373 ushort cfg_lsw;
11374 uchar value;
11376 if ((dma_channel >= 5) && (dma_channel <= 7)) {
11377 if (dma_channel == 7)
11378 value = 0x00;
11379 else
11380 value = dma_channel - 4;
11381 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
11382 cfg_lsw |= value;
11383 AscSetChipCfgLsw(iop_base, cfg_lsw);
11384 return (AscGetIsaDmaChannel(iop_base));
11386 return 0;
11389 static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
11391 uchar speed_value;
11393 AscSetBank(iop_base, 1);
11394 speed_value = AscReadChipDmaSpeed(iop_base);
11395 speed_value &= 0x07;
11396 AscSetBank(iop_base, 0);
11397 return speed_value;
11400 static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
11402 speed_value &= 0x07;
11403 AscSetBank(iop_base, 1);
11404 AscWriteChipDmaSpeed(iop_base, speed_value);
11405 AscSetBank(iop_base, 0);
11406 return AscGetIsaDmaSpeed(iop_base);
11408 #endif /* CONFIG_ISA */
11410 static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
11412 int i;
11413 PortAddr iop_base;
11414 ushort warn_code;
11415 uchar chip_version;
11417 iop_base = asc_dvc->iop_base;
11418 warn_code = 0;
11419 asc_dvc->err_code = 0;
11420 if ((asc_dvc->bus_type &
11421 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
11422 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
11424 AscSetChipControl(iop_base, CC_HALT);
11425 AscSetChipStatus(iop_base, 0);
11426 asc_dvc->bug_fix_cntl = 0;
11427 asc_dvc->pci_fix_asyn_xfer = 0;
11428 asc_dvc->pci_fix_asyn_xfer_always = 0;
11429 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
11430 asc_dvc->sdtr_done = 0;
11431 asc_dvc->cur_total_qng = 0;
11432 asc_dvc->is_in_int = 0;
11433 asc_dvc->in_critical_cnt = 0;
11434 asc_dvc->last_q_shortage = 0;
11435 asc_dvc->use_tagged_qng = 0;
11436 asc_dvc->no_scam = 0;
11437 asc_dvc->unit_not_ready = 0;
11438 asc_dvc->queue_full_or_busy = 0;
11439 asc_dvc->redo_scam = 0;
11440 asc_dvc->res2 = 0;
11441 asc_dvc->host_init_sdtr_index = 0;
11442 asc_dvc->cfg->can_tagged_qng = 0;
11443 asc_dvc->cfg->cmd_qng_enabled = 0;
11444 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
11445 asc_dvc->init_sdtr = 0;
11446 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
11447 asc_dvc->scsi_reset_wait = 3;
11448 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
11449 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
11450 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
11451 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
11452 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
11453 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
11454 asc_dvc->cfg->chip_version = chip_version;
11455 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
11456 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
11457 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
11458 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
11459 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
11460 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
11461 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
11462 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
11463 asc_dvc->max_sdtr_index = 7;
11464 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
11465 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
11466 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
11467 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
11468 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
11469 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
11470 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
11471 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
11472 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
11473 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
11474 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
11475 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
11476 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
11477 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
11478 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
11479 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
11480 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
11481 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
11482 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
11483 asc_dvc->max_sdtr_index = 15;
11484 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
11485 AscSetExtraControl(iop_base,
11486 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11487 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
11488 AscSetExtraControl(iop_base,
11489 (SEC_ACTIVE_NEGATE |
11490 SEC_ENABLE_FILTER));
11493 if (asc_dvc->bus_type == ASC_IS_PCI) {
11494 AscSetExtraControl(iop_base,
11495 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11498 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
11499 #ifdef CONFIG_ISA
11500 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
11501 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
11502 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
11503 asc_dvc->bus_type = ASC_IS_ISAPNP;
11505 asc_dvc->cfg->isa_dma_channel =
11506 (uchar)AscGetIsaDmaChannel(iop_base);
11508 #endif /* CONFIG_ISA */
11509 for (i = 0; i <= ASC_MAX_TID; i++) {
11510 asc_dvc->cur_dvc_qng[i] = 0;
11511 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
11512 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
11513 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
11514 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
11516 return warn_code;
11519 static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
11521 int retry;
11523 for (retry = 0; retry < ASC_EEP_MAX_RETRY; retry++) {
11524 unsigned char read_back;
11525 AscSetChipEEPCmd(iop_base, cmd_reg);
11526 mdelay(1);
11527 read_back = AscGetChipEEPCmd(iop_base);
11528 if (read_back == cmd_reg)
11529 return 1;
11531 return 0;
11534 static void __devinit AscWaitEEPRead(void)
11536 mdelay(1);
11539 static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
11541 ushort read_wval;
11542 uchar cmd_reg;
11544 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11545 AscWaitEEPRead();
11546 cmd_reg = addr | ASC_EEP_CMD_READ;
11547 AscWriteEEPCmdReg(iop_base, cmd_reg);
11548 AscWaitEEPRead();
11549 read_wval = AscGetChipEEPData(iop_base);
11550 AscWaitEEPRead();
11551 return read_wval;
11554 static ushort __devinit
11555 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11557 ushort wval;
11558 ushort sum;
11559 ushort *wbuf;
11560 int cfg_beg;
11561 int cfg_end;
11562 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11563 int s_addr;
11565 wbuf = (ushort *)cfg_buf;
11566 sum = 0;
11567 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
11568 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11569 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11570 sum += *wbuf;
11572 if (bus_type & ASC_IS_VL) {
11573 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11574 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11575 } else {
11576 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11577 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11579 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11580 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
11581 if (s_addr <= uchar_end_in_config) {
11583 * Swap all char fields - must unswap bytes already swapped
11584 * by AscReadEEPWord().
11586 *wbuf = le16_to_cpu(wval);
11587 } else {
11588 /* Don't swap word field at the end - cntl field. */
11589 *wbuf = wval;
11591 sum += wval; /* Checksum treats all EEPROM data as words. */
11594 * Read the checksum word which will be compared against 'sum'
11595 * by the caller. Word field already swapped.
11597 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11598 return sum;
11601 static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
11603 PortAddr iop_base;
11604 ushort q_addr;
11605 ushort saved_word;
11606 int sta;
11608 iop_base = asc_dvc->iop_base;
11609 sta = 0;
11610 q_addr = ASC_QNO_TO_QADDR(241);
11611 saved_word = AscReadLramWord(iop_base, q_addr);
11612 AscSetChipLramAddr(iop_base, q_addr);
11613 AscSetChipLramData(iop_base, 0x55AA);
11614 mdelay(10);
11615 AscSetChipLramAddr(iop_base, q_addr);
11616 if (AscGetChipLramData(iop_base) == 0x55AA) {
11617 sta = 1;
11618 AscWriteLramWord(iop_base, q_addr, saved_word);
11620 return (sta);
11623 static void __devinit AscWaitEEPWrite(void)
11625 mdelay(20);
11626 return;
11629 static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
11631 ushort read_back;
11632 int retry;
11634 retry = 0;
11635 while (TRUE) {
11636 AscSetChipEEPData(iop_base, data_reg);
11637 mdelay(1);
11638 read_back = AscGetChipEEPData(iop_base);
11639 if (read_back == data_reg) {
11640 return (1);
11642 if (retry++ > ASC_EEP_MAX_RETRY) {
11643 return (0);
11648 static ushort __devinit
11649 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
11651 ushort read_wval;
11653 read_wval = AscReadEEPWord(iop_base, addr);
11654 if (read_wval != word_val) {
11655 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
11656 AscWaitEEPRead();
11657 AscWriteEEPDataReg(iop_base, word_val);
11658 AscWaitEEPRead();
11659 AscWriteEEPCmdReg(iop_base,
11660 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
11661 AscWaitEEPWrite();
11662 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11663 AscWaitEEPRead();
11664 return (AscReadEEPWord(iop_base, addr));
11666 return (read_wval);
11669 static int __devinit
11670 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11672 int n_error;
11673 ushort *wbuf;
11674 ushort word;
11675 ushort sum;
11676 int s_addr;
11677 int cfg_beg;
11678 int cfg_end;
11679 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11681 wbuf = (ushort *)cfg_buf;
11682 n_error = 0;
11683 sum = 0;
11684 /* Write two config words; AscWriteEEPWord() will swap bytes. */
11685 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11686 sum += *wbuf;
11687 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11688 n_error++;
11691 if (bus_type & ASC_IS_VL) {
11692 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11693 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11694 } else {
11695 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11696 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11698 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11699 if (s_addr <= uchar_end_in_config) {
11701 * This is a char field. Swap char fields before they are
11702 * swapped again by AscWriteEEPWord().
11704 word = cpu_to_le16(*wbuf);
11705 if (word !=
11706 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11707 n_error++;
11709 } else {
11710 /* Don't swap word field at the end - cntl field. */
11711 if (*wbuf !=
11712 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11713 n_error++;
11716 sum += *wbuf; /* Checksum calculated from word values. */
11718 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
11719 *wbuf = sum;
11720 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
11721 n_error++;
11724 /* Read EEPROM back again. */
11725 wbuf = (ushort *)cfg_buf;
11727 * Read two config words; Byte-swapping done by AscReadEEPWord().
11729 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11730 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11731 n_error++;
11734 if (bus_type & ASC_IS_VL) {
11735 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11736 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11737 } else {
11738 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11739 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11741 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11742 if (s_addr <= uchar_end_in_config) {
11744 * Swap all char fields. Must unswap bytes already swapped
11745 * by AscReadEEPWord().
11747 word =
11748 le16_to_cpu(AscReadEEPWord
11749 (iop_base, (uchar)s_addr));
11750 } else {
11751 /* Don't swap word field at the end - cntl field. */
11752 word = AscReadEEPWord(iop_base, (uchar)s_addr);
11754 if (*wbuf != word) {
11755 n_error++;
11758 /* Read checksum; Byte swapping not needed. */
11759 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11760 n_error++;
11762 return n_error;
11765 static int __devinit
11766 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11768 int retry;
11769 int n_error;
11771 retry = 0;
11772 while (TRUE) {
11773 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11774 bus_type)) == 0) {
11775 break;
11777 if (++retry > ASC_EEP_MAX_RETRY) {
11778 break;
11781 return n_error;
11784 static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
11786 ASCEEP_CONFIG eep_config_buf;
11787 ASCEEP_CONFIG *eep_config;
11788 PortAddr iop_base;
11789 ushort chksum;
11790 ushort warn_code;
11791 ushort cfg_msw, cfg_lsw;
11792 int i;
11793 int write_eep = 0;
11795 iop_base = asc_dvc->iop_base;
11796 warn_code = 0;
11797 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
11798 AscStopQueueExe(iop_base);
11799 if ((AscStopChip(iop_base) == FALSE) ||
11800 (AscGetChipScsiCtrl(iop_base) != 0)) {
11801 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
11802 AscResetChipAndScsiBus(asc_dvc);
11803 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
11805 if (AscIsChipHalted(iop_base) == FALSE) {
11806 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
11807 return (warn_code);
11809 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
11810 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
11811 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
11812 return (warn_code);
11814 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
11815 cfg_msw = AscGetChipCfgMsw(iop_base);
11816 cfg_lsw = AscGetChipCfgLsw(iop_base);
11817 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
11818 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11819 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
11820 AscSetChipCfgMsw(iop_base, cfg_msw);
11822 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
11823 ASC_DBG(1, "chksum 0x%x\n", chksum);
11824 if (chksum == 0) {
11825 chksum = 0xaa55;
11827 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
11828 warn_code |= ASC_WARN_AUTO_CONFIG;
11829 if (asc_dvc->cfg->chip_version == 3) {
11830 if (eep_config->cfg_lsw != cfg_lsw) {
11831 warn_code |= ASC_WARN_EEPROM_RECOVER;
11832 eep_config->cfg_lsw =
11833 AscGetChipCfgLsw(iop_base);
11835 if (eep_config->cfg_msw != cfg_msw) {
11836 warn_code |= ASC_WARN_EEPROM_RECOVER;
11837 eep_config->cfg_msw =
11838 AscGetChipCfgMsw(iop_base);
11842 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11843 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
11844 ASC_DBG(1, "eep_config->chksum 0x%x\n", eep_config->chksum);
11845 if (chksum != eep_config->chksum) {
11846 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
11847 ASC_CHIP_VER_PCI_ULTRA_3050) {
11848 ASC_DBG(1, "chksum error ignored; EEPROM-less board\n");
11849 eep_config->init_sdtr = 0xFF;
11850 eep_config->disc_enable = 0xFF;
11851 eep_config->start_motor = 0xFF;
11852 eep_config->use_cmd_qng = 0;
11853 eep_config->max_total_qng = 0xF0;
11854 eep_config->max_tag_qng = 0x20;
11855 eep_config->cntl = 0xBFFF;
11856 ASC_EEP_SET_CHIP_ID(eep_config, 7);
11857 eep_config->no_scam = 0;
11858 eep_config->adapter_info[0] = 0;
11859 eep_config->adapter_info[1] = 0;
11860 eep_config->adapter_info[2] = 0;
11861 eep_config->adapter_info[3] = 0;
11862 eep_config->adapter_info[4] = 0;
11863 /* Indicate EEPROM-less board. */
11864 eep_config->adapter_info[5] = 0xBB;
11865 } else {
11866 ASC_PRINT
11867 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
11868 write_eep = 1;
11869 warn_code |= ASC_WARN_EEPROM_CHKSUM;
11872 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
11873 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
11874 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
11875 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
11876 asc_dvc->start_motor = eep_config->start_motor;
11877 asc_dvc->dvc_cntl = eep_config->cntl;
11878 asc_dvc->no_scam = eep_config->no_scam;
11879 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
11880 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
11881 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
11882 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
11883 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
11884 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
11885 if (!AscTestExternalLram(asc_dvc)) {
11886 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
11887 ASC_IS_PCI_ULTRA)) {
11888 eep_config->max_total_qng =
11889 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
11890 eep_config->max_tag_qng =
11891 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
11892 } else {
11893 eep_config->cfg_msw |= 0x0800;
11894 cfg_msw |= 0x0800;
11895 AscSetChipCfgMsw(iop_base, cfg_msw);
11896 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
11897 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
11899 } else {
11901 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
11902 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
11904 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
11905 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
11907 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
11908 eep_config->max_tag_qng = eep_config->max_total_qng;
11910 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
11911 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
11913 asc_dvc->max_total_qng = eep_config->max_total_qng;
11914 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
11915 eep_config->use_cmd_qng) {
11916 eep_config->disc_enable = eep_config->use_cmd_qng;
11917 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
11919 ASC_EEP_SET_CHIP_ID(eep_config,
11920 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
11921 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
11922 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
11923 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
11924 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
11927 for (i = 0; i <= ASC_MAX_TID; i++) {
11928 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
11929 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
11930 asc_dvc->cfg->sdtr_period_offset[i] =
11931 (uchar)(ASC_DEF_SDTR_OFFSET |
11932 (asc_dvc->host_init_sdtr_index << 4));
11934 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
11935 if (write_eep) {
11936 if ((i = AscSetEEPConfig(iop_base, eep_config,
11937 asc_dvc->bus_type)) != 0) {
11938 ASC_PRINT1
11939 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
11941 } else {
11942 ASC_PRINT
11943 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
11946 return (warn_code);
11949 static int __devinit AscInitGetConfig(struct asc_board *boardp)
11951 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
11952 unsigned short warn_code = 0;
11954 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
11955 if (asc_dvc->err_code != 0)
11956 return asc_dvc->err_code;
11958 if (AscFindSignature(asc_dvc->iop_base)) {
11959 warn_code |= AscInitAscDvcVar(asc_dvc);
11960 warn_code |= AscInitFromEEP(asc_dvc);
11961 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
11962 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
11963 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
11964 } else {
11965 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11968 switch (warn_code) {
11969 case 0: /* No error */
11970 break;
11971 case ASC_WARN_IO_PORT_ROTATE:
11972 ASC_PRINT1("AscInitGetConfig: board %d: I/O port address "
11973 "modified\n", boardp->id);
11974 break;
11975 case ASC_WARN_AUTO_CONFIG:
11976 ASC_PRINT1("AscInitGetConfig: board %d: I/O port increment "
11977 "switch enabled\n", boardp->id);
11978 break;
11979 case ASC_WARN_EEPROM_CHKSUM:
11980 ASC_PRINT1("AscInitGetConfig: board %d: EEPROM checksum "
11981 "error\n", boardp->id);
11982 break;
11983 case ASC_WARN_IRQ_MODIFIED:
11984 ASC_PRINT1("AscInitGetConfig: board %d: IRQ modified\n",
11985 boardp->id);
11986 break;
11987 case ASC_WARN_CMD_QNG_CONFLICT:
11988 ASC_PRINT1("AscInitGetConfig: board %d: tag queuing enabled "
11989 "w/o disconnects\n", boardp->id);
11990 break;
11991 default:
11992 ASC_PRINT2("AscInitGetConfig: board %d: unknown warning: "
11993 "0x%x\n", boardp->id, warn_code);
11994 break;
11997 if (asc_dvc->err_code != 0) {
11998 ASC_PRINT3("AscInitGetConfig: board %d error: init_state 0x%x, "
11999 "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
12000 asc_dvc->err_code);
12003 return asc_dvc->err_code;
12006 static int __devinit AscInitSetConfig(struct pci_dev *pdev, struct asc_board *boardp)
12008 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
12009 PortAddr iop_base = asc_dvc->iop_base;
12010 unsigned short cfg_msw;
12011 unsigned short warn_code = 0;
12013 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
12014 if (asc_dvc->err_code != 0)
12015 return asc_dvc->err_code;
12016 if (!AscFindSignature(asc_dvc->iop_base)) {
12017 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12018 return asc_dvc->err_code;
12021 cfg_msw = AscGetChipCfgMsw(iop_base);
12022 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12023 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
12024 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12025 AscSetChipCfgMsw(iop_base, cfg_msw);
12027 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
12028 asc_dvc->cfg->cmd_qng_enabled) {
12029 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
12030 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12032 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12033 warn_code |= ASC_WARN_AUTO_CONFIG;
12035 #ifdef CONFIG_PCI
12036 if (asc_dvc->bus_type & ASC_IS_PCI) {
12037 cfg_msw &= 0xFFC0;
12038 AscSetChipCfgMsw(iop_base, cfg_msw);
12039 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
12040 } else {
12041 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
12042 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
12043 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
12044 asc_dvc->bug_fix_cntl |=
12045 ASC_BUG_FIX_ASYN_USE_SYN;
12048 } else
12049 #endif /* CONFIG_PCI */
12050 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
12051 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
12052 == ASC_CHIP_VER_ASYN_BUG) {
12053 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12056 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
12057 asc_dvc->cfg->chip_scsi_id) {
12058 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
12060 #ifdef CONFIG_ISA
12061 if (asc_dvc->bus_type & ASC_IS_ISA) {
12062 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
12063 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
12065 #endif /* CONFIG_ISA */
12067 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
12069 switch (warn_code) {
12070 case 0: /* No error. */
12071 break;
12072 case ASC_WARN_IO_PORT_ROTATE:
12073 ASC_PRINT1("AscInitSetConfig: board %d: I/O port address "
12074 "modified\n", boardp->id);
12075 break;
12076 case ASC_WARN_AUTO_CONFIG:
12077 ASC_PRINT1("AscInitSetConfig: board %d: I/O port increment "
12078 "switch enabled\n", boardp->id);
12079 break;
12080 case ASC_WARN_EEPROM_CHKSUM:
12081 ASC_PRINT1("AscInitSetConfig: board %d: EEPROM checksum "
12082 "error\n", boardp->id);
12083 break;
12084 case ASC_WARN_IRQ_MODIFIED:
12085 ASC_PRINT1("AscInitSetConfig: board %d: IRQ modified\n",
12086 boardp->id);
12087 break;
12088 case ASC_WARN_CMD_QNG_CONFLICT:
12089 ASC_PRINT1("AscInitSetConfig: board %d: tag queuing w/o "
12090 "disconnects\n",
12091 boardp->id);
12092 break;
12093 default:
12094 ASC_PRINT2("AscInitSetConfig: board %d: unknown warning: "
12095 "0x%x\n", boardp->id, warn_code);
12096 break;
12099 if (asc_dvc->err_code != 0) {
12100 ASC_PRINT3("AscInitSetConfig: board %d error: init_state 0x%x, "
12101 "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
12102 asc_dvc->err_code);
12105 return asc_dvc->err_code;
12109 * EEPROM Configuration.
12111 * All drivers should use this structure to set the default EEPROM
12112 * configuration. The BIOS now uses this structure when it is built.
12113 * Additional structure information can be found in a_condor.h where
12114 * the structure is defined.
12116 * The *_Field_IsChar structs are needed to correct for endianness.
12117 * These values are read from the board 16 bits at a time directly
12118 * into the structs. Because some fields are char, the values will be
12119 * in the wrong order. The *_Field_IsChar tells when to flip the
12120 * bytes. Data read and written to PCI memory is automatically swapped
12121 * on big-endian platforms so char fields read as words are actually being
12122 * unswapped on big-endian platforms.
12124 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
12125 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
12126 0x0000, /* cfg_msw */
12127 0xFFFF, /* disc_enable */
12128 0xFFFF, /* wdtr_able */
12129 0xFFFF, /* sdtr_able */
12130 0xFFFF, /* start_motor */
12131 0xFFFF, /* tagqng_able */
12132 0xFFFF, /* bios_scan */
12133 0, /* scam_tolerant */
12134 7, /* adapter_scsi_id */
12135 0, /* bios_boot_delay */
12136 3, /* scsi_reset_delay */
12137 0, /* bios_id_lun */
12138 0, /* termination */
12139 0, /* reserved1 */
12140 0xFFE7, /* bios_ctrl */
12141 0xFFFF, /* ultra_able */
12142 0, /* reserved2 */
12143 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
12144 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
12145 0, /* dvc_cntl */
12146 0, /* bug_fix */
12147 0, /* serial_number_word1 */
12148 0, /* serial_number_word2 */
12149 0, /* serial_number_word3 */
12150 0, /* check_sum */
12151 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12152 , /* oem_name[16] */
12153 0, /* dvc_err_code */
12154 0, /* adv_err_code */
12155 0, /* adv_err_addr */
12156 0, /* saved_dvc_err_code */
12157 0, /* saved_adv_err_code */
12158 0, /* saved_adv_err_addr */
12159 0 /* num_of_err */
12162 static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
12163 0, /* cfg_lsw */
12164 0, /* cfg_msw */
12165 0, /* -disc_enable */
12166 0, /* wdtr_able */
12167 0, /* sdtr_able */
12168 0, /* start_motor */
12169 0, /* tagqng_able */
12170 0, /* bios_scan */
12171 0, /* scam_tolerant */
12172 1, /* adapter_scsi_id */
12173 1, /* bios_boot_delay */
12174 1, /* scsi_reset_delay */
12175 1, /* bios_id_lun */
12176 1, /* termination */
12177 1, /* reserved1 */
12178 0, /* bios_ctrl */
12179 0, /* ultra_able */
12180 0, /* reserved2 */
12181 1, /* max_host_qng */
12182 1, /* max_dvc_qng */
12183 0, /* dvc_cntl */
12184 0, /* bug_fix */
12185 0, /* serial_number_word1 */
12186 0, /* serial_number_word2 */
12187 0, /* serial_number_word3 */
12188 0, /* check_sum */
12189 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12190 , /* oem_name[16] */
12191 0, /* dvc_err_code */
12192 0, /* adv_err_code */
12193 0, /* adv_err_addr */
12194 0, /* saved_dvc_err_code */
12195 0, /* saved_adv_err_code */
12196 0, /* saved_adv_err_addr */
12197 0 /* num_of_err */
12200 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
12201 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
12202 0x0000, /* 01 cfg_msw */
12203 0xFFFF, /* 02 disc_enable */
12204 0xFFFF, /* 03 wdtr_able */
12205 0x4444, /* 04 sdtr_speed1 */
12206 0xFFFF, /* 05 start_motor */
12207 0xFFFF, /* 06 tagqng_able */
12208 0xFFFF, /* 07 bios_scan */
12209 0, /* 08 scam_tolerant */
12210 7, /* 09 adapter_scsi_id */
12211 0, /* bios_boot_delay */
12212 3, /* 10 scsi_reset_delay */
12213 0, /* bios_id_lun */
12214 0, /* 11 termination_se */
12215 0, /* termination_lvd */
12216 0xFFE7, /* 12 bios_ctrl */
12217 0x4444, /* 13 sdtr_speed2 */
12218 0x4444, /* 14 sdtr_speed3 */
12219 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
12220 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
12221 0, /* 16 dvc_cntl */
12222 0x4444, /* 17 sdtr_speed4 */
12223 0, /* 18 serial_number_word1 */
12224 0, /* 19 serial_number_word2 */
12225 0, /* 20 serial_number_word3 */
12226 0, /* 21 check_sum */
12227 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12228 , /* 22-29 oem_name[16] */
12229 0, /* 30 dvc_err_code */
12230 0, /* 31 adv_err_code */
12231 0, /* 32 adv_err_addr */
12232 0, /* 33 saved_dvc_err_code */
12233 0, /* 34 saved_adv_err_code */
12234 0, /* 35 saved_adv_err_addr */
12235 0, /* 36 reserved */
12236 0, /* 37 reserved */
12237 0, /* 38 reserved */
12238 0, /* 39 reserved */
12239 0, /* 40 reserved */
12240 0, /* 41 reserved */
12241 0, /* 42 reserved */
12242 0, /* 43 reserved */
12243 0, /* 44 reserved */
12244 0, /* 45 reserved */
12245 0, /* 46 reserved */
12246 0, /* 47 reserved */
12247 0, /* 48 reserved */
12248 0, /* 49 reserved */
12249 0, /* 50 reserved */
12250 0, /* 51 reserved */
12251 0, /* 52 reserved */
12252 0, /* 53 reserved */
12253 0, /* 54 reserved */
12254 0, /* 55 reserved */
12255 0, /* 56 cisptr_lsw */
12256 0, /* 57 cisprt_msw */
12257 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
12258 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
12259 0, /* 60 reserved */
12260 0, /* 61 reserved */
12261 0, /* 62 reserved */
12262 0 /* 63 reserved */
12265 static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
12266 0, /* 00 cfg_lsw */
12267 0, /* 01 cfg_msw */
12268 0, /* 02 disc_enable */
12269 0, /* 03 wdtr_able */
12270 0, /* 04 sdtr_speed1 */
12271 0, /* 05 start_motor */
12272 0, /* 06 tagqng_able */
12273 0, /* 07 bios_scan */
12274 0, /* 08 scam_tolerant */
12275 1, /* 09 adapter_scsi_id */
12276 1, /* bios_boot_delay */
12277 1, /* 10 scsi_reset_delay */
12278 1, /* bios_id_lun */
12279 1, /* 11 termination_se */
12280 1, /* termination_lvd */
12281 0, /* 12 bios_ctrl */
12282 0, /* 13 sdtr_speed2 */
12283 0, /* 14 sdtr_speed3 */
12284 1, /* 15 max_host_qng */
12285 1, /* max_dvc_qng */
12286 0, /* 16 dvc_cntl */
12287 0, /* 17 sdtr_speed4 */
12288 0, /* 18 serial_number_word1 */
12289 0, /* 19 serial_number_word2 */
12290 0, /* 20 serial_number_word3 */
12291 0, /* 21 check_sum */
12292 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12293 , /* 22-29 oem_name[16] */
12294 0, /* 30 dvc_err_code */
12295 0, /* 31 adv_err_code */
12296 0, /* 32 adv_err_addr */
12297 0, /* 33 saved_dvc_err_code */
12298 0, /* 34 saved_adv_err_code */
12299 0, /* 35 saved_adv_err_addr */
12300 0, /* 36 reserved */
12301 0, /* 37 reserved */
12302 0, /* 38 reserved */
12303 0, /* 39 reserved */
12304 0, /* 40 reserved */
12305 0, /* 41 reserved */
12306 0, /* 42 reserved */
12307 0, /* 43 reserved */
12308 0, /* 44 reserved */
12309 0, /* 45 reserved */
12310 0, /* 46 reserved */
12311 0, /* 47 reserved */
12312 0, /* 48 reserved */
12313 0, /* 49 reserved */
12314 0, /* 50 reserved */
12315 0, /* 51 reserved */
12316 0, /* 52 reserved */
12317 0, /* 53 reserved */
12318 0, /* 54 reserved */
12319 0, /* 55 reserved */
12320 0, /* 56 cisptr_lsw */
12321 0, /* 57 cisprt_msw */
12322 0, /* 58 subsysvid */
12323 0, /* 59 subsysid */
12324 0, /* 60 reserved */
12325 0, /* 61 reserved */
12326 0, /* 62 reserved */
12327 0 /* 63 reserved */
12330 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
12331 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
12332 0x0000, /* 01 cfg_msw */
12333 0xFFFF, /* 02 disc_enable */
12334 0xFFFF, /* 03 wdtr_able */
12335 0x5555, /* 04 sdtr_speed1 */
12336 0xFFFF, /* 05 start_motor */
12337 0xFFFF, /* 06 tagqng_able */
12338 0xFFFF, /* 07 bios_scan */
12339 0, /* 08 scam_tolerant */
12340 7, /* 09 adapter_scsi_id */
12341 0, /* bios_boot_delay */
12342 3, /* 10 scsi_reset_delay */
12343 0, /* bios_id_lun */
12344 0, /* 11 termination_se */
12345 0, /* termination_lvd */
12346 0xFFE7, /* 12 bios_ctrl */
12347 0x5555, /* 13 sdtr_speed2 */
12348 0x5555, /* 14 sdtr_speed3 */
12349 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
12350 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
12351 0, /* 16 dvc_cntl */
12352 0x5555, /* 17 sdtr_speed4 */
12353 0, /* 18 serial_number_word1 */
12354 0, /* 19 serial_number_word2 */
12355 0, /* 20 serial_number_word3 */
12356 0, /* 21 check_sum */
12357 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12358 , /* 22-29 oem_name[16] */
12359 0, /* 30 dvc_err_code */
12360 0, /* 31 adv_err_code */
12361 0, /* 32 adv_err_addr */
12362 0, /* 33 saved_dvc_err_code */
12363 0, /* 34 saved_adv_err_code */
12364 0, /* 35 saved_adv_err_addr */
12365 0, /* 36 reserved */
12366 0, /* 37 reserved */
12367 0, /* 38 reserved */
12368 0, /* 39 reserved */
12369 0, /* 40 reserved */
12370 0, /* 41 reserved */
12371 0, /* 42 reserved */
12372 0, /* 43 reserved */
12373 0, /* 44 reserved */
12374 0, /* 45 reserved */
12375 0, /* 46 reserved */
12376 0, /* 47 reserved */
12377 0, /* 48 reserved */
12378 0, /* 49 reserved */
12379 0, /* 50 reserved */
12380 0, /* 51 reserved */
12381 0, /* 52 reserved */
12382 0, /* 53 reserved */
12383 0, /* 54 reserved */
12384 0, /* 55 reserved */
12385 0, /* 56 cisptr_lsw */
12386 0, /* 57 cisprt_msw */
12387 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
12388 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
12389 0, /* 60 reserved */
12390 0, /* 61 reserved */
12391 0, /* 62 reserved */
12392 0 /* 63 reserved */
12395 static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
12396 0, /* 00 cfg_lsw */
12397 0, /* 01 cfg_msw */
12398 0, /* 02 disc_enable */
12399 0, /* 03 wdtr_able */
12400 0, /* 04 sdtr_speed1 */
12401 0, /* 05 start_motor */
12402 0, /* 06 tagqng_able */
12403 0, /* 07 bios_scan */
12404 0, /* 08 scam_tolerant */
12405 1, /* 09 adapter_scsi_id */
12406 1, /* bios_boot_delay */
12407 1, /* 10 scsi_reset_delay */
12408 1, /* bios_id_lun */
12409 1, /* 11 termination_se */
12410 1, /* termination_lvd */
12411 0, /* 12 bios_ctrl */
12412 0, /* 13 sdtr_speed2 */
12413 0, /* 14 sdtr_speed3 */
12414 1, /* 15 max_host_qng */
12415 1, /* max_dvc_qng */
12416 0, /* 16 dvc_cntl */
12417 0, /* 17 sdtr_speed4 */
12418 0, /* 18 serial_number_word1 */
12419 0, /* 19 serial_number_word2 */
12420 0, /* 20 serial_number_word3 */
12421 0, /* 21 check_sum */
12422 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12423 , /* 22-29 oem_name[16] */
12424 0, /* 30 dvc_err_code */
12425 0, /* 31 adv_err_code */
12426 0, /* 32 adv_err_addr */
12427 0, /* 33 saved_dvc_err_code */
12428 0, /* 34 saved_adv_err_code */
12429 0, /* 35 saved_adv_err_addr */
12430 0, /* 36 reserved */
12431 0, /* 37 reserved */
12432 0, /* 38 reserved */
12433 0, /* 39 reserved */
12434 0, /* 40 reserved */
12435 0, /* 41 reserved */
12436 0, /* 42 reserved */
12437 0, /* 43 reserved */
12438 0, /* 44 reserved */
12439 0, /* 45 reserved */
12440 0, /* 46 reserved */
12441 0, /* 47 reserved */
12442 0, /* 48 reserved */
12443 0, /* 49 reserved */
12444 0, /* 50 reserved */
12445 0, /* 51 reserved */
12446 0, /* 52 reserved */
12447 0, /* 53 reserved */
12448 0, /* 54 reserved */
12449 0, /* 55 reserved */
12450 0, /* 56 cisptr_lsw */
12451 0, /* 57 cisprt_msw */
12452 0, /* 58 subsysvid */
12453 0, /* 59 subsysid */
12454 0, /* 60 reserved */
12455 0, /* 61 reserved */
12456 0, /* 62 reserved */
12457 0 /* 63 reserved */
12460 #ifdef CONFIG_PCI
12462 * Wait for EEPROM command to complete
12464 static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
12466 int eep_delay_ms;
12468 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
12469 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
12470 ASC_EEP_CMD_DONE) {
12471 break;
12473 mdelay(1);
12475 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
12477 BUG();
12481 * Read the EEPROM from specified location
12483 static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
12485 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12486 ASC_EEP_CMD_READ | eep_word_addr);
12487 AdvWaitEEPCmd(iop_base);
12488 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
12492 * Write the EEPROM from 'cfg_buf'.
12494 void __devinit
12495 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
12497 ushort *wbuf;
12498 ushort addr, chksum;
12499 ushort *charfields;
12501 wbuf = (ushort *)cfg_buf;
12502 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
12503 chksum = 0;
12505 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12506 AdvWaitEEPCmd(iop_base);
12509 * Write EEPROM from word 0 to word 20.
12511 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12512 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12513 ushort word;
12515 if (*charfields++) {
12516 word = cpu_to_le16(*wbuf);
12517 } else {
12518 word = *wbuf;
12520 chksum += *wbuf; /* Checksum is calculated from word values. */
12521 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12522 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12523 ASC_EEP_CMD_WRITE | addr);
12524 AdvWaitEEPCmd(iop_base);
12525 mdelay(ADV_EEP_DELAY_MS);
12529 * Write EEPROM checksum at word 21.
12531 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12532 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12533 AdvWaitEEPCmd(iop_base);
12534 wbuf++;
12535 charfields++;
12538 * Write EEPROM OEM name at words 22 to 29.
12540 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12541 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12542 ushort word;
12544 if (*charfields++) {
12545 word = cpu_to_le16(*wbuf);
12546 } else {
12547 word = *wbuf;
12549 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12550 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12551 ASC_EEP_CMD_WRITE | addr);
12552 AdvWaitEEPCmd(iop_base);
12554 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12555 AdvWaitEEPCmd(iop_base);
12559 * Write the EEPROM from 'cfg_buf'.
12561 void __devinit
12562 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
12564 ushort *wbuf;
12565 ushort *charfields;
12566 ushort addr, chksum;
12568 wbuf = (ushort *)cfg_buf;
12569 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
12570 chksum = 0;
12572 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12573 AdvWaitEEPCmd(iop_base);
12576 * Write EEPROM from word 0 to word 20.
12578 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12579 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12580 ushort word;
12582 if (*charfields++) {
12583 word = cpu_to_le16(*wbuf);
12584 } else {
12585 word = *wbuf;
12587 chksum += *wbuf; /* Checksum is calculated from word values. */
12588 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12589 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12590 ASC_EEP_CMD_WRITE | addr);
12591 AdvWaitEEPCmd(iop_base);
12592 mdelay(ADV_EEP_DELAY_MS);
12596 * Write EEPROM checksum at word 21.
12598 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12599 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12600 AdvWaitEEPCmd(iop_base);
12601 wbuf++;
12602 charfields++;
12605 * Write EEPROM OEM name at words 22 to 29.
12607 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12608 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12609 ushort word;
12611 if (*charfields++) {
12612 word = cpu_to_le16(*wbuf);
12613 } else {
12614 word = *wbuf;
12616 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12617 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12618 ASC_EEP_CMD_WRITE | addr);
12619 AdvWaitEEPCmd(iop_base);
12621 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12622 AdvWaitEEPCmd(iop_base);
12626 * Write the EEPROM from 'cfg_buf'.
12628 void __devinit
12629 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
12631 ushort *wbuf;
12632 ushort *charfields;
12633 ushort addr, chksum;
12635 wbuf = (ushort *)cfg_buf;
12636 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
12637 chksum = 0;
12639 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12640 AdvWaitEEPCmd(iop_base);
12643 * Write EEPROM from word 0 to word 20.
12645 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12646 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12647 ushort word;
12649 if (*charfields++) {
12650 word = cpu_to_le16(*wbuf);
12651 } else {
12652 word = *wbuf;
12654 chksum += *wbuf; /* Checksum is calculated from word values. */
12655 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12656 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12657 ASC_EEP_CMD_WRITE | addr);
12658 AdvWaitEEPCmd(iop_base);
12659 mdelay(ADV_EEP_DELAY_MS);
12663 * Write EEPROM checksum at word 21.
12665 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12666 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12667 AdvWaitEEPCmd(iop_base);
12668 wbuf++;
12669 charfields++;
12672 * Write EEPROM OEM name at words 22 to 29.
12674 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12675 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12676 ushort word;
12678 if (*charfields++) {
12679 word = cpu_to_le16(*wbuf);
12680 } else {
12681 word = *wbuf;
12683 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12684 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12685 ASC_EEP_CMD_WRITE | addr);
12686 AdvWaitEEPCmd(iop_base);
12688 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12689 AdvWaitEEPCmd(iop_base);
12693 * Read EEPROM configuration into the specified buffer.
12695 * Return a checksum based on the EEPROM configuration read.
12697 static ushort __devinit
12698 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
12700 ushort wval, chksum;
12701 ushort *wbuf;
12702 int eep_addr;
12703 ushort *charfields;
12705 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
12706 wbuf = (ushort *)cfg_buf;
12707 chksum = 0;
12709 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12710 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12711 wval = AdvReadEEPWord(iop_base, eep_addr);
12712 chksum += wval; /* Checksum is calculated from word values. */
12713 if (*charfields++) {
12714 *wbuf = le16_to_cpu(wval);
12715 } else {
12716 *wbuf = wval;
12719 /* Read checksum word. */
12720 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12721 wbuf++;
12722 charfields++;
12724 /* Read rest of EEPROM not covered by the checksum. */
12725 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12726 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12727 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12728 if (*charfields++) {
12729 *wbuf = le16_to_cpu(*wbuf);
12732 return chksum;
12736 * Read EEPROM configuration into the specified buffer.
12738 * Return a checksum based on the EEPROM configuration read.
12740 static ushort __devinit
12741 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
12743 ushort wval, chksum;
12744 ushort *wbuf;
12745 int eep_addr;
12746 ushort *charfields;
12748 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
12749 wbuf = (ushort *)cfg_buf;
12750 chksum = 0;
12752 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12753 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12754 wval = AdvReadEEPWord(iop_base, eep_addr);
12755 chksum += wval; /* Checksum is calculated from word values. */
12756 if (*charfields++) {
12757 *wbuf = le16_to_cpu(wval);
12758 } else {
12759 *wbuf = wval;
12762 /* Read checksum word. */
12763 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12764 wbuf++;
12765 charfields++;
12767 /* Read rest of EEPROM not covered by the checksum. */
12768 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12769 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12770 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12771 if (*charfields++) {
12772 *wbuf = le16_to_cpu(*wbuf);
12775 return chksum;
12779 * Read EEPROM configuration into the specified buffer.
12781 * Return a checksum based on the EEPROM configuration read.
12783 static ushort __devinit
12784 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
12786 ushort wval, chksum;
12787 ushort *wbuf;
12788 int eep_addr;
12789 ushort *charfields;
12791 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
12792 wbuf = (ushort *)cfg_buf;
12793 chksum = 0;
12795 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12796 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12797 wval = AdvReadEEPWord(iop_base, eep_addr);
12798 chksum += wval; /* Checksum is calculated from word values. */
12799 if (*charfields++) {
12800 *wbuf = le16_to_cpu(wval);
12801 } else {
12802 *wbuf = wval;
12805 /* Read checksum word. */
12806 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12807 wbuf++;
12808 charfields++;
12810 /* Read rest of EEPROM not covered by the checksum. */
12811 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12812 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12813 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12814 if (*charfields++) {
12815 *wbuf = le16_to_cpu(*wbuf);
12818 return chksum;
12822 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12823 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12824 * all of this is done.
12826 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12828 * For a non-fatal error return a warning code. If there are no warnings
12829 * then 0 is returned.
12831 * Note: Chip is stopped on entry.
12833 static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
12835 AdvPortAddr iop_base;
12836 ushort warn_code;
12837 ADVEEP_3550_CONFIG eep_config;
12839 iop_base = asc_dvc->iop_base;
12841 warn_code = 0;
12844 * Read the board's EEPROM configuration.
12846 * Set default values if a bad checksum is found.
12848 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
12849 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12852 * Set EEPROM default values.
12854 memcpy(&eep_config, &Default_3550_EEPROM_Config,
12855 sizeof(ADVEEP_3550_CONFIG));
12858 * Assume the 6 byte board serial number that was read from
12859 * EEPROM is correct even if the EEPROM checksum failed.
12861 eep_config.serial_number_word3 =
12862 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
12864 eep_config.serial_number_word2 =
12865 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
12867 eep_config.serial_number_word1 =
12868 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
12870 AdvSet3550EEPConfig(iop_base, &eep_config);
12873 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
12874 * EEPROM configuration that was read.
12876 * This is the mapping of EEPROM fields to Adv Library fields.
12878 asc_dvc->wdtr_able = eep_config.wdtr_able;
12879 asc_dvc->sdtr_able = eep_config.sdtr_able;
12880 asc_dvc->ultra_able = eep_config.ultra_able;
12881 asc_dvc->tagqng_able = eep_config.tagqng_able;
12882 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
12883 asc_dvc->max_host_qng = eep_config.max_host_qng;
12884 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12885 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
12886 asc_dvc->start_motor = eep_config.start_motor;
12887 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
12888 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
12889 asc_dvc->no_scam = eep_config.scam_tolerant;
12890 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
12891 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
12892 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
12895 * Set the host maximum queuing (max. 253, min. 16) and the per device
12896 * maximum queuing (max. 63, min. 4).
12898 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
12899 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12900 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
12901 /* If the value is zero, assume it is uninitialized. */
12902 if (eep_config.max_host_qng == 0) {
12903 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12904 } else {
12905 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
12909 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
12910 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12911 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
12912 /* If the value is zero, assume it is uninitialized. */
12913 if (eep_config.max_dvc_qng == 0) {
12914 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12915 } else {
12916 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
12921 * If 'max_dvc_qng' is greater than 'max_host_qng', then
12922 * set 'max_dvc_qng' to 'max_host_qng'.
12924 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
12925 eep_config.max_dvc_qng = eep_config.max_host_qng;
12929 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
12930 * values based on possibly adjusted EEPROM values.
12932 asc_dvc->max_host_qng = eep_config.max_host_qng;
12933 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12936 * If the EEPROM 'termination' field is set to automatic (0), then set
12937 * the ADV_DVC_CFG 'termination' field to automatic also.
12939 * If the termination is specified with a non-zero 'termination'
12940 * value check that a legal value is set and set the ADV_DVC_CFG
12941 * 'termination' field appropriately.
12943 if (eep_config.termination == 0) {
12944 asc_dvc->cfg->termination = 0; /* auto termination */
12945 } else {
12946 /* Enable manual control with low off / high off. */
12947 if (eep_config.termination == 1) {
12948 asc_dvc->cfg->termination = TERM_CTL_SEL;
12950 /* Enable manual control with low off / high on. */
12951 } else if (eep_config.termination == 2) {
12952 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
12954 /* Enable manual control with low on / high on. */
12955 } else if (eep_config.termination == 3) {
12956 asc_dvc->cfg->termination =
12957 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
12958 } else {
12960 * The EEPROM 'termination' field contains a bad value. Use
12961 * automatic termination instead.
12963 asc_dvc->cfg->termination = 0;
12964 warn_code |= ASC_WARN_EEPROM_TERMINATION;
12968 return warn_code;
12972 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12973 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12974 * all of this is done.
12976 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12978 * For a non-fatal error return a warning code. If there are no warnings
12979 * then 0 is returned.
12981 * Note: Chip is stopped on entry.
12983 static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
12985 AdvPortAddr iop_base;
12986 ushort warn_code;
12987 ADVEEP_38C0800_CONFIG eep_config;
12988 uchar tid, termination;
12989 ushort sdtr_speed = 0;
12991 iop_base = asc_dvc->iop_base;
12993 warn_code = 0;
12996 * Read the board's EEPROM configuration.
12998 * Set default values if a bad checksum is found.
13000 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
13001 eep_config.check_sum) {
13002 warn_code |= ASC_WARN_EEPROM_CHKSUM;
13005 * Set EEPROM default values.
13007 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
13008 sizeof(ADVEEP_38C0800_CONFIG));
13011 * Assume the 6 byte board serial number that was read from
13012 * EEPROM is correct even if the EEPROM checksum failed.
13014 eep_config.serial_number_word3 =
13015 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
13017 eep_config.serial_number_word2 =
13018 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
13020 eep_config.serial_number_word1 =
13021 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
13023 AdvSet38C0800EEPConfig(iop_base, &eep_config);
13026 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
13027 * EEPROM configuration that was read.
13029 * This is the mapping of EEPROM fields to Adv Library fields.
13031 asc_dvc->wdtr_able = eep_config.wdtr_able;
13032 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13033 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13034 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13035 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13036 asc_dvc->tagqng_able = eep_config.tagqng_able;
13037 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13038 asc_dvc->max_host_qng = eep_config.max_host_qng;
13039 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13040 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
13041 asc_dvc->start_motor = eep_config.start_motor;
13042 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13043 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13044 asc_dvc->no_scam = eep_config.scam_tolerant;
13045 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
13046 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
13047 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
13050 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13051 * are set, then set an 'sdtr_able' bit for it.
13053 asc_dvc->sdtr_able = 0;
13054 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13055 if (tid == 0) {
13056 sdtr_speed = asc_dvc->sdtr_speed1;
13057 } else if (tid == 4) {
13058 sdtr_speed = asc_dvc->sdtr_speed2;
13059 } else if (tid == 8) {
13060 sdtr_speed = asc_dvc->sdtr_speed3;
13061 } else if (tid == 12) {
13062 sdtr_speed = asc_dvc->sdtr_speed4;
13064 if (sdtr_speed & ADV_MAX_TID) {
13065 asc_dvc->sdtr_able |= (1 << tid);
13067 sdtr_speed >>= 4;
13071 * Set the host maximum queuing (max. 253, min. 16) and the per device
13072 * maximum queuing (max. 63, min. 4).
13074 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13075 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13076 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13077 /* If the value is zero, assume it is uninitialized. */
13078 if (eep_config.max_host_qng == 0) {
13079 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13080 } else {
13081 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13085 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13086 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13087 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13088 /* If the value is zero, assume it is uninitialized. */
13089 if (eep_config.max_dvc_qng == 0) {
13090 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13091 } else {
13092 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13097 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13098 * set 'max_dvc_qng' to 'max_host_qng'.
13100 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13101 eep_config.max_dvc_qng = eep_config.max_host_qng;
13105 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
13106 * values based on possibly adjusted EEPROM values.
13108 asc_dvc->max_host_qng = eep_config.max_host_qng;
13109 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13112 * If the EEPROM 'termination' field is set to automatic (0), then set
13113 * the ADV_DVC_CFG 'termination' field to automatic also.
13115 * If the termination is specified with a non-zero 'termination'
13116 * value check that a legal value is set and set the ADV_DVC_CFG
13117 * 'termination' field appropriately.
13119 if (eep_config.termination_se == 0) {
13120 termination = 0; /* auto termination for SE */
13121 } else {
13122 /* Enable manual control with low off / high off. */
13123 if (eep_config.termination_se == 1) {
13124 termination = 0;
13126 /* Enable manual control with low off / high on. */
13127 } else if (eep_config.termination_se == 2) {
13128 termination = TERM_SE_HI;
13130 /* Enable manual control with low on / high on. */
13131 } else if (eep_config.termination_se == 3) {
13132 termination = TERM_SE;
13133 } else {
13135 * The EEPROM 'termination_se' field contains a bad value.
13136 * Use automatic termination instead.
13138 termination = 0;
13139 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13143 if (eep_config.termination_lvd == 0) {
13144 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13145 } else {
13146 /* Enable manual control with low off / high off. */
13147 if (eep_config.termination_lvd == 1) {
13148 asc_dvc->cfg->termination = termination;
13150 /* Enable manual control with low off / high on. */
13151 } else if (eep_config.termination_lvd == 2) {
13152 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13154 /* Enable manual control with low on / high on. */
13155 } else if (eep_config.termination_lvd == 3) {
13156 asc_dvc->cfg->termination = termination | TERM_LVD;
13157 } else {
13159 * The EEPROM 'termination_lvd' field contains a bad value.
13160 * Use automatic termination instead.
13162 asc_dvc->cfg->termination = termination;
13163 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13167 return warn_code;
13171 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
13172 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
13173 * all of this is done.
13175 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
13177 * For a non-fatal error return a warning code. If there are no warnings
13178 * then 0 is returned.
13180 * Note: Chip is stopped on entry.
13182 static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
13184 AdvPortAddr iop_base;
13185 ushort warn_code;
13186 ADVEEP_38C1600_CONFIG eep_config;
13187 uchar tid, termination;
13188 ushort sdtr_speed = 0;
13190 iop_base = asc_dvc->iop_base;
13192 warn_code = 0;
13195 * Read the board's EEPROM configuration.
13197 * Set default values if a bad checksum is found.
13199 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
13200 eep_config.check_sum) {
13201 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
13202 warn_code |= ASC_WARN_EEPROM_CHKSUM;
13205 * Set EEPROM default values.
13207 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
13208 sizeof(ADVEEP_38C1600_CONFIG));
13210 if (PCI_FUNC(pdev->devfn) != 0) {
13211 u8 ints;
13213 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60
13214 * and old Mac system booting problem. The Expansion
13215 * ROM must be disabled in Function 1 for these systems
13217 eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
13219 * Clear the INTAB (bit 11) if the GPIO 0 input
13220 * indicates the Function 1 interrupt line is wired
13221 * to INTB.
13223 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
13224 * 1 - Function 1 interrupt line wired to INT A.
13225 * 0 - Function 1 interrupt line wired to INT B.
13227 * Note: Function 0 is always wired to INTA.
13228 * Put all 5 GPIO bits in input mode and then read
13229 * their input values.
13231 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
13232 ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
13233 if ((ints & 0x01) == 0)
13234 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
13238 * Assume the 6 byte board serial number that was read from
13239 * EEPROM is correct even if the EEPROM checksum failed.
13241 eep_config.serial_number_word3 =
13242 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
13243 eep_config.serial_number_word2 =
13244 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
13245 eep_config.serial_number_word1 =
13246 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
13248 AdvSet38C1600EEPConfig(iop_base, &eep_config);
13252 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13253 * EEPROM configuration that was read.
13255 * This is the mapping of EEPROM fields to Adv Library fields.
13257 asc_dvc->wdtr_able = eep_config.wdtr_able;
13258 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13259 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13260 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13261 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13262 asc_dvc->ppr_able = 0;
13263 asc_dvc->tagqng_able = eep_config.tagqng_able;
13264 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13265 asc_dvc->max_host_qng = eep_config.max_host_qng;
13266 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13267 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
13268 asc_dvc->start_motor = eep_config.start_motor;
13269 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13270 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13271 asc_dvc->no_scam = eep_config.scam_tolerant;
13274 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13275 * are set, then set an 'sdtr_able' bit for it.
13277 asc_dvc->sdtr_able = 0;
13278 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
13279 if (tid == 0) {
13280 sdtr_speed = asc_dvc->sdtr_speed1;
13281 } else if (tid == 4) {
13282 sdtr_speed = asc_dvc->sdtr_speed2;
13283 } else if (tid == 8) {
13284 sdtr_speed = asc_dvc->sdtr_speed3;
13285 } else if (tid == 12) {
13286 sdtr_speed = asc_dvc->sdtr_speed4;
13288 if (sdtr_speed & ASC_MAX_TID) {
13289 asc_dvc->sdtr_able |= (1 << tid);
13291 sdtr_speed >>= 4;
13295 * Set the host maximum queuing (max. 253, min. 16) and the per device
13296 * maximum queuing (max. 63, min. 4).
13298 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13299 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13300 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13301 /* If the value is zero, assume it is uninitialized. */
13302 if (eep_config.max_host_qng == 0) {
13303 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13304 } else {
13305 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13309 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13310 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13311 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13312 /* If the value is zero, assume it is uninitialized. */
13313 if (eep_config.max_dvc_qng == 0) {
13314 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13315 } else {
13316 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13321 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13322 * set 'max_dvc_qng' to 'max_host_qng'.
13324 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13325 eep_config.max_dvc_qng = eep_config.max_host_qng;
13329 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
13330 * values based on possibly adjusted EEPROM values.
13332 asc_dvc->max_host_qng = eep_config.max_host_qng;
13333 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13336 * If the EEPROM 'termination' field is set to automatic (0), then set
13337 * the ASC_DVC_CFG 'termination' field to automatic also.
13339 * If the termination is specified with a non-zero 'termination'
13340 * value check that a legal value is set and set the ASC_DVC_CFG
13341 * 'termination' field appropriately.
13343 if (eep_config.termination_se == 0) {
13344 termination = 0; /* auto termination for SE */
13345 } else {
13346 /* Enable manual control with low off / high off. */
13347 if (eep_config.termination_se == 1) {
13348 termination = 0;
13350 /* Enable manual control with low off / high on. */
13351 } else if (eep_config.termination_se == 2) {
13352 termination = TERM_SE_HI;
13354 /* Enable manual control with low on / high on. */
13355 } else if (eep_config.termination_se == 3) {
13356 termination = TERM_SE;
13357 } else {
13359 * The EEPROM 'termination_se' field contains a bad value.
13360 * Use automatic termination instead.
13362 termination = 0;
13363 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13367 if (eep_config.termination_lvd == 0) {
13368 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13369 } else {
13370 /* Enable manual control with low off / high off. */
13371 if (eep_config.termination_lvd == 1) {
13372 asc_dvc->cfg->termination = termination;
13374 /* Enable manual control with low off / high on. */
13375 } else if (eep_config.termination_lvd == 2) {
13376 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13378 /* Enable manual control with low on / high on. */
13379 } else if (eep_config.termination_lvd == 3) {
13380 asc_dvc->cfg->termination = termination | TERM_LVD;
13381 } else {
13383 * The EEPROM 'termination_lvd' field contains a bad value.
13384 * Use automatic termination instead.
13386 asc_dvc->cfg->termination = termination;
13387 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13391 return warn_code;
13395 * Initialize the ADV_DVC_VAR structure.
13397 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13399 * For a non-fatal error return a warning code. If there are no warnings
13400 * then 0 is returned.
13402 static int __devinit
13403 AdvInitGetConfig(struct pci_dev *pdev, struct asc_board *boardp)
13405 ADV_DVC_VAR *asc_dvc = &boardp->dvc_var.adv_dvc_var;
13406 unsigned short warn_code = 0;
13407 AdvPortAddr iop_base = asc_dvc->iop_base;
13408 u16 cmd;
13409 int status;
13411 asc_dvc->err_code = 0;
13414 * Save the state of the PCI Configuration Command Register
13415 * "Parity Error Response Control" Bit. If the bit is clear (0),
13416 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13417 * DMA parity errors.
13419 asc_dvc->cfg->control_flag = 0;
13420 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
13421 if ((cmd & PCI_COMMAND_PARITY) == 0)
13422 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
13424 asc_dvc->cfg->chip_version =
13425 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13427 ASC_DBG(1, "iopb_chip_id_1: 0x%x 0x%x\n",
13428 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13429 (ushort)ADV_CHIP_ID_BYTE);
13431 ASC_DBG(1, "iopw_chip_id_0: 0x%x 0x%x\n",
13432 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13433 (ushort)ADV_CHIP_ID_WORD);
13436 * Reset the chip to start and allow register writes.
13438 if (AdvFindSignature(iop_base) == 0) {
13439 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13440 return ADV_ERROR;
13441 } else {
13443 * The caller must set 'chip_type' to a valid setting.
13445 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13446 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13447 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13448 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13449 return ADV_ERROR;
13453 * Reset Chip.
13455 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13456 ADV_CTRL_REG_CMD_RESET);
13457 mdelay(100);
13458 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13459 ADV_CTRL_REG_CMD_WR_IO_REG);
13461 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13462 status = AdvInitFrom38C1600EEP(asc_dvc);
13463 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13464 status = AdvInitFrom38C0800EEP(asc_dvc);
13465 } else {
13466 status = AdvInitFrom3550EEP(asc_dvc);
13468 warn_code |= status;
13471 if (warn_code != 0) {
13472 ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
13473 boardp->id, warn_code);
13476 if (asc_dvc->err_code) {
13477 ASC_PRINT2("AdvInitGetConfig: board %d error: err_code 0x%x\n",
13478 boardp->id, asc_dvc->err_code);
13481 return asc_dvc->err_code;
13483 #endif
13485 static struct scsi_host_template advansys_template = {
13486 .proc_name = DRV_NAME,
13487 #ifdef CONFIG_PROC_FS
13488 .proc_info = advansys_proc_info,
13489 #endif
13490 .name = DRV_NAME,
13491 .info = advansys_info,
13492 .queuecommand = advansys_queuecommand,
13493 .eh_bus_reset_handler = advansys_reset,
13494 .bios_param = advansys_biosparam,
13495 .slave_configure = advansys_slave_configure,
13497 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
13498 * must be set. The flag will be cleared in advansys_board_found
13499 * for non-ISA adapters.
13501 .unchecked_isa_dma = 1,
13503 * All adapters controlled by this driver are capable of large
13504 * scatter-gather lists. According to the mid-level SCSI documentation
13505 * this obviates any performance gain provided by setting
13506 * 'use_clustering'. But empirically while CPU utilization is increased
13507 * by enabling clustering, I/O throughput increases as well.
13509 .use_clustering = ENABLE_CLUSTERING,
13512 static int __devinit
13513 advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp)
13515 int req_cnt = 0;
13516 adv_req_t *reqp = NULL;
13517 int sg_cnt = 0;
13518 adv_sgblk_t *sgp;
13519 int warn_code, err_code;
13522 * Allocate buffer carrier structures. The total size
13523 * is about 4 KB, so allocate all at once.
13525 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
13526 ASC_DBG(1, "carrp 0x%p\n", boardp->carrp);
13528 if (!boardp->carrp)
13529 goto kmalloc_failed;
13532 * Allocate up to 'max_host_qng' request structures for the Wide
13533 * board. The total size is about 16 KB, so allocate all at once.
13534 * If the allocation fails decrement and try again.
13536 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
13537 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
13539 ASC_DBG(1, "reqp 0x%p, req_cnt %d, bytes %lu\n", reqp, req_cnt,
13540 (ulong)sizeof(adv_req_t) * req_cnt);
13542 if (reqp)
13543 break;
13546 if (!reqp)
13547 goto kmalloc_failed;
13549 boardp->orig_reqp = reqp;
13552 * Allocate up to ADV_TOT_SG_BLOCK request structures for
13553 * the Wide board. Each structure is about 136 bytes.
13555 boardp->adv_sgblkp = NULL;
13556 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
13557 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
13559 if (!sgp)
13560 break;
13562 sgp->next_sgblkp = boardp->adv_sgblkp;
13563 boardp->adv_sgblkp = sgp;
13567 ASC_DBG(1, "sg_cnt %d * %u = %u bytes\n", sg_cnt, sizeof(adv_sgblk_t),
13568 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
13570 if (!boardp->adv_sgblkp)
13571 goto kmalloc_failed;
13573 adv_dvc_varp->carrier_buf = boardp->carrp;
13576 * Point 'adv_reqp' to the request structures and
13577 * link them together.
13579 req_cnt--;
13580 reqp[req_cnt].next_reqp = NULL;
13581 for (; req_cnt > 0; req_cnt--) {
13582 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
13584 boardp->adv_reqp = &reqp[0];
13586 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
13587 ASC_DBG(2, "AdvInitAsc3550Driver()\n");
13588 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
13589 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
13590 ASC_DBG(2, "AdvInitAsc38C0800Driver()\n");
13591 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
13592 } else {
13593 ASC_DBG(2, "AdvInitAsc38C1600Driver()\n");
13594 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
13596 err_code = adv_dvc_varp->err_code;
13598 if (warn_code || err_code) {
13599 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
13600 " error 0x%x\n", boardp->id, warn_code, err_code);
13603 goto exit;
13605 kmalloc_failed:
13606 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
13607 "failed\n", boardp->id);
13608 err_code = ADV_ERROR;
13609 exit:
13610 return err_code;
13613 static void advansys_wide_free_mem(struct asc_board *boardp)
13615 kfree(boardp->carrp);
13616 boardp->carrp = NULL;
13617 kfree(boardp->orig_reqp);
13618 boardp->orig_reqp = boardp->adv_reqp = NULL;
13619 while (boardp->adv_sgblkp) {
13620 adv_sgblk_t *sgp = boardp->adv_sgblkp;
13621 boardp->adv_sgblkp = sgp->next_sgblkp;
13622 kfree(sgp);
13626 static int __devinit advansys_board_found(struct Scsi_Host *shost,
13627 unsigned int iop, int bus_type)
13629 struct pci_dev *pdev;
13630 struct asc_board *boardp = shost_priv(shost);
13631 ASC_DVC_VAR *asc_dvc_varp = NULL;
13632 ADV_DVC_VAR *adv_dvc_varp = NULL;
13633 int share_irq, warn_code, ret;
13635 boardp->id = asc_board_count++;
13636 spin_lock_init(&boardp->lock);
13637 pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL;
13639 if (ASC_NARROW_BOARD(boardp)) {
13640 ASC_DBG(1, "narrow board\n");
13641 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
13642 asc_dvc_varp->bus_type = bus_type;
13643 asc_dvc_varp->drv_ptr = boardp;
13644 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
13645 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
13646 asc_dvc_varp->iop_base = iop;
13647 } else {
13648 #ifdef CONFIG_PCI
13649 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
13650 adv_dvc_varp->drv_ptr = boardp;
13651 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
13652 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
13653 ASC_DBG(1, "wide board ASC-3550\n");
13654 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
13655 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
13656 ASC_DBG(1, "wide board ASC-38C0800\n");
13657 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
13658 } else {
13659 ASC_DBG(1, "wide board ASC-38C1600\n");
13660 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
13663 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
13664 boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
13665 boardp->asc_n_io_port);
13666 if (!boardp->ioremap_addr) {
13667 ASC_PRINT3
13668 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
13669 boardp->id, pci_resource_start(pdev, 1),
13670 boardp->asc_n_io_port);
13671 ret = -ENODEV;
13672 goto err_shost;
13674 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr;
13675 ASC_DBG(1, "iop_base: 0x%p\n", adv_dvc_varp->iop_base);
13678 * Even though it isn't used to access wide boards, other
13679 * than for the debug line below, save I/O Port address so
13680 * that it can be reported.
13682 boardp->ioport = iop;
13684 ASC_DBG(1, "iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
13685 (ushort)inp(iop + 1), (ushort)inpw(iop));
13686 #endif /* CONFIG_PCI */
13689 #ifdef CONFIG_PROC_FS
13691 * Allocate buffer for printing information from
13692 * /proc/scsi/advansys/[0...].
13694 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
13695 if (!boardp->prtbuf) {
13696 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
13697 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
13698 ret = -ENOMEM;
13699 goto err_unmap;
13701 #endif /* CONFIG_PROC_FS */
13703 if (ASC_NARROW_BOARD(boardp)) {
13705 * Set the board bus type and PCI IRQ before
13706 * calling AscInitGetConfig().
13708 switch (asc_dvc_varp->bus_type) {
13709 #ifdef CONFIG_ISA
13710 case ASC_IS_ISA:
13711 shost->unchecked_isa_dma = TRUE;
13712 share_irq = 0;
13713 break;
13714 case ASC_IS_VL:
13715 shost->unchecked_isa_dma = FALSE;
13716 share_irq = 0;
13717 break;
13718 case ASC_IS_EISA:
13719 shost->unchecked_isa_dma = FALSE;
13720 share_irq = IRQF_SHARED;
13721 break;
13722 #endif /* CONFIG_ISA */
13723 #ifdef CONFIG_PCI
13724 case ASC_IS_PCI:
13725 shost->unchecked_isa_dma = FALSE;
13726 share_irq = IRQF_SHARED;
13727 break;
13728 #endif /* CONFIG_PCI */
13729 default:
13730 ASC_PRINT2
13731 ("advansys_board_found: board %d: unknown adapter type: %d\n",
13732 boardp->id, asc_dvc_varp->bus_type);
13733 shost->unchecked_isa_dma = TRUE;
13734 share_irq = 0;
13735 break;
13739 * NOTE: AscInitGetConfig() may change the board's
13740 * bus_type value. The bus_type value should no
13741 * longer be used. If the bus_type field must be
13742 * referenced only use the bit-wise AND operator "&".
13744 ASC_DBG(2, "AscInitGetConfig()\n");
13745 ret = AscInitGetConfig(boardp) ? -ENODEV : 0;
13746 } else {
13747 #ifdef CONFIG_PCI
13749 * For Wide boards set PCI information before calling
13750 * AdvInitGetConfig().
13752 shost->unchecked_isa_dma = FALSE;
13753 share_irq = IRQF_SHARED;
13754 ASC_DBG(2, "AdvInitGetConfig()\n");
13756 ret = AdvInitGetConfig(pdev, boardp) ? -ENODEV : 0;
13757 #endif /* CONFIG_PCI */
13760 if (ret)
13761 goto err_free_proc;
13764 * Save the EEPROM configuration so that it can be displayed
13765 * from /proc/scsi/advansys/[0...].
13767 if (ASC_NARROW_BOARD(boardp)) {
13769 ASCEEP_CONFIG *ep;
13772 * Set the adapter's target id bit in the 'init_tidmask' field.
13774 boardp->init_tidmask |=
13775 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
13778 * Save EEPROM settings for the board.
13780 ep = &boardp->eep_config.asc_eep;
13782 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
13783 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
13784 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
13785 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
13786 ep->start_motor = asc_dvc_varp->start_motor;
13787 ep->cntl = asc_dvc_varp->dvc_cntl;
13788 ep->no_scam = asc_dvc_varp->no_scam;
13789 ep->max_total_qng = asc_dvc_varp->max_total_qng;
13790 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
13791 /* 'max_tag_qng' is set to the same value for every device. */
13792 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
13793 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
13794 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
13795 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
13796 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
13797 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
13798 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
13801 * Modify board configuration.
13803 ASC_DBG(2, "AscInitSetConfig()\n");
13804 ret = AscInitSetConfig(pdev, boardp) ? -ENODEV : 0;
13805 if (ret)
13806 goto err_free_proc;
13807 } else {
13808 ADVEEP_3550_CONFIG *ep_3550;
13809 ADVEEP_38C0800_CONFIG *ep_38C0800;
13810 ADVEEP_38C1600_CONFIG *ep_38C1600;
13813 * Save Wide EEP Configuration Information.
13815 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
13816 ep_3550 = &boardp->eep_config.adv_3550_eep;
13818 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
13819 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
13820 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
13821 ep_3550->termination = adv_dvc_varp->cfg->termination;
13822 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
13823 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
13824 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
13825 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
13826 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
13827 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
13828 ep_3550->start_motor = adv_dvc_varp->start_motor;
13829 ep_3550->scsi_reset_delay =
13830 adv_dvc_varp->scsi_reset_wait;
13831 ep_3550->serial_number_word1 =
13832 adv_dvc_varp->cfg->serial1;
13833 ep_3550->serial_number_word2 =
13834 adv_dvc_varp->cfg->serial2;
13835 ep_3550->serial_number_word3 =
13836 adv_dvc_varp->cfg->serial3;
13837 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
13838 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
13840 ep_38C0800->adapter_scsi_id =
13841 adv_dvc_varp->chip_scsi_id;
13842 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
13843 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
13844 ep_38C0800->termination_lvd =
13845 adv_dvc_varp->cfg->termination;
13846 ep_38C0800->disc_enable =
13847 adv_dvc_varp->cfg->disc_enable;
13848 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
13849 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
13850 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
13851 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
13852 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
13853 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
13854 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
13855 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
13856 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
13857 ep_38C0800->scsi_reset_delay =
13858 adv_dvc_varp->scsi_reset_wait;
13859 ep_38C0800->serial_number_word1 =
13860 adv_dvc_varp->cfg->serial1;
13861 ep_38C0800->serial_number_word2 =
13862 adv_dvc_varp->cfg->serial2;
13863 ep_38C0800->serial_number_word3 =
13864 adv_dvc_varp->cfg->serial3;
13865 } else {
13866 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
13868 ep_38C1600->adapter_scsi_id =
13869 adv_dvc_varp->chip_scsi_id;
13870 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
13871 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
13872 ep_38C1600->termination_lvd =
13873 adv_dvc_varp->cfg->termination;
13874 ep_38C1600->disc_enable =
13875 adv_dvc_varp->cfg->disc_enable;
13876 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
13877 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
13878 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
13879 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
13880 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
13881 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
13882 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
13883 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
13884 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
13885 ep_38C1600->scsi_reset_delay =
13886 adv_dvc_varp->scsi_reset_wait;
13887 ep_38C1600->serial_number_word1 =
13888 adv_dvc_varp->cfg->serial1;
13889 ep_38C1600->serial_number_word2 =
13890 adv_dvc_varp->cfg->serial2;
13891 ep_38C1600->serial_number_word3 =
13892 adv_dvc_varp->cfg->serial3;
13896 * Set the adapter's target id bit in the 'init_tidmask' field.
13898 boardp->init_tidmask |=
13899 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
13903 * Channels are numbered beginning with 0. For AdvanSys one host
13904 * structure supports one channel. Multi-channel boards have a
13905 * separate host structure for each channel.
13907 shost->max_channel = 0;
13908 if (ASC_NARROW_BOARD(boardp)) {
13909 shost->max_id = ASC_MAX_TID + 1;
13910 shost->max_lun = ASC_MAX_LUN + 1;
13911 shost->max_cmd_len = ASC_MAX_CDB_LEN;
13913 shost->io_port = asc_dvc_varp->iop_base;
13914 boardp->asc_n_io_port = ASC_IOADR_GAP;
13915 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
13917 /* Set maximum number of queues the adapter can handle. */
13918 shost->can_queue = asc_dvc_varp->max_total_qng;
13919 } else {
13920 shost->max_id = ADV_MAX_TID + 1;
13921 shost->max_lun = ADV_MAX_LUN + 1;
13922 shost->max_cmd_len = ADV_MAX_CDB_LEN;
13925 * Save the I/O Port address and length even though
13926 * I/O ports are not used to access Wide boards.
13927 * Instead the Wide boards are accessed with
13928 * PCI Memory Mapped I/O.
13930 shost->io_port = iop;
13932 shost->this_id = adv_dvc_varp->chip_scsi_id;
13934 /* Set maximum number of queues the adapter can handle. */
13935 shost->can_queue = adv_dvc_varp->max_host_qng;
13939 * Following v1.3.89, 'cmd_per_lun' is no longer needed
13940 * and should be set to zero.
13942 * But because of a bug introduced in v1.3.89 if the driver is
13943 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
13944 * SCSI function 'allocate_device' will panic. To allow the driver
13945 * to work as a module in these kernels set 'cmd_per_lun' to 1.
13947 * Note: This is wrong. cmd_per_lun should be set to the depth
13948 * you want on untagged devices always.
13949 #ifdef MODULE
13951 shost->cmd_per_lun = 1;
13952 /* #else
13953 shost->cmd_per_lun = 0;
13954 #endif */
13957 * Set the maximum number of scatter-gather elements the
13958 * adapter can handle.
13960 if (ASC_NARROW_BOARD(boardp)) {
13962 * Allow two commands with 'sg_tablesize' scatter-gather
13963 * elements to be executed simultaneously. This value is
13964 * the theoretical hardware limit. It may be decreased
13965 * below.
13967 shost->sg_tablesize =
13968 (((asc_dvc_varp->max_total_qng - 2) / 2) *
13969 ASC_SG_LIST_PER_Q) + 1;
13970 } else {
13971 shost->sg_tablesize = ADV_MAX_SG_LIST;
13975 * The value of 'sg_tablesize' can not exceed the SCSI
13976 * mid-level driver definition of SG_ALL. SG_ALL also
13977 * must not be exceeded, because it is used to define the
13978 * size of the scatter-gather table in 'struct asc_sg_head'.
13980 if (shost->sg_tablesize > SG_ALL) {
13981 shost->sg_tablesize = SG_ALL;
13984 ASC_DBG(1, "sg_tablesize: %d\n", shost->sg_tablesize);
13986 /* BIOS start address. */
13987 if (ASC_NARROW_BOARD(boardp)) {
13988 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
13989 asc_dvc_varp->bus_type);
13990 } else {
13992 * Fill-in BIOS board variables. The Wide BIOS saves
13993 * information in LRAM that is used by the driver.
13995 AdvReadWordLram(adv_dvc_varp->iop_base,
13996 BIOS_SIGNATURE, boardp->bios_signature);
13997 AdvReadWordLram(adv_dvc_varp->iop_base,
13998 BIOS_VERSION, boardp->bios_version);
13999 AdvReadWordLram(adv_dvc_varp->iop_base,
14000 BIOS_CODESEG, boardp->bios_codeseg);
14001 AdvReadWordLram(adv_dvc_varp->iop_base,
14002 BIOS_CODELEN, boardp->bios_codelen);
14004 ASC_DBG(1, "bios_signature 0x%x, bios_version 0x%x\n",
14005 boardp->bios_signature, boardp->bios_version);
14007 ASC_DBG(1, "bios_codeseg 0x%x, bios_codelen 0x%x\n",
14008 boardp->bios_codeseg, boardp->bios_codelen);
14011 * If the BIOS saved a valid signature, then fill in
14012 * the BIOS code segment base address.
14014 if (boardp->bios_signature == 0x55AA) {
14016 * Convert x86 realmode code segment to a linear
14017 * address by shifting left 4.
14019 shost->base = ((ulong)boardp->bios_codeseg << 4);
14020 } else {
14021 shost->base = 0;
14026 * Register Board Resources - I/O Port, DMA, IRQ
14029 /* Register DMA Channel for Narrow boards. */
14030 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
14031 #ifdef CONFIG_ISA
14032 if (ASC_NARROW_BOARD(boardp)) {
14033 /* Register DMA channel for ISA bus. */
14034 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
14035 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
14036 ret = request_dma(shost->dma_channel, DRV_NAME);
14037 if (ret) {
14038 ASC_PRINT3
14039 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
14040 boardp->id, shost->dma_channel, ret);
14041 goto err_free_proc;
14043 AscEnableIsaDma(shost->dma_channel);
14046 #endif /* CONFIG_ISA */
14048 /* Register IRQ Number. */
14049 ASC_DBG(2, "request_irq(%d, %p)\n", boardp->irq, shost);
14051 ret = request_irq(boardp->irq, advansys_interrupt, share_irq,
14052 DRV_NAME, shost);
14054 if (ret) {
14055 if (ret == -EBUSY) {
14056 ASC_PRINT2
14057 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
14058 boardp->id, boardp->irq);
14059 } else if (ret == -EINVAL) {
14060 ASC_PRINT2
14061 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
14062 boardp->id, boardp->irq);
14063 } else {
14064 ASC_PRINT3
14065 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
14066 boardp->id, boardp->irq, ret);
14068 goto err_free_dma;
14072 * Initialize board RISC chip and enable interrupts.
14074 if (ASC_NARROW_BOARD(boardp)) {
14075 ASC_DBG(2, "AscInitAsc1000Driver()\n");
14076 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
14078 if (warn_code || asc_dvc_varp->err_code) {
14079 ASC_PRINT4("advansys_board_found: board %d error: "
14080 "init_state 0x%x, warn 0x%x, error 0x%x\n",
14081 boardp->id, asc_dvc_varp->init_state,
14082 warn_code, asc_dvc_varp->err_code);
14083 if (asc_dvc_varp->err_code)
14084 ret = -ENODEV;
14086 } else {
14087 if (advansys_wide_init_chip(boardp, adv_dvc_varp))
14088 ret = -ENODEV;
14091 if (ret)
14092 goto err_free_wide_mem;
14094 ASC_DBG_PRT_SCSI_HOST(2, shost);
14096 ret = scsi_add_host(shost, boardp->dev);
14097 if (ret)
14098 goto err_free_wide_mem;
14100 scsi_scan_host(shost);
14101 return 0;
14103 err_free_wide_mem:
14104 advansys_wide_free_mem(boardp);
14105 free_irq(boardp->irq, shost);
14106 err_free_dma:
14107 if (shost->dma_channel != NO_ISA_DMA)
14108 free_dma(shost->dma_channel);
14109 err_free_proc:
14110 kfree(boardp->prtbuf);
14111 err_unmap:
14112 if (boardp->ioremap_addr)
14113 iounmap(boardp->ioremap_addr);
14114 err_shost:
14115 return ret;
14119 * advansys_release()
14121 * Release resources allocated for a single AdvanSys adapter.
14123 static int advansys_release(struct Scsi_Host *shost)
14125 struct asc_board *boardp = shost_priv(shost);
14126 ASC_DBG(1, "begin\n");
14127 scsi_remove_host(shost);
14128 free_irq(boardp->irq, shost);
14129 if (shost->dma_channel != NO_ISA_DMA) {
14130 ASC_DBG(1, "free_dma()\n");
14131 free_dma(shost->dma_channel);
14133 if (!ASC_NARROW_BOARD(boardp)) {
14134 iounmap(boardp->ioremap_addr);
14135 advansys_wide_free_mem(boardp);
14137 kfree(boardp->prtbuf);
14138 scsi_host_put(shost);
14139 ASC_DBG(1, "end\n");
14140 return 0;
14143 #define ASC_IOADR_TABLE_MAX_IX 11
14145 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
14146 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
14147 0x0210, 0x0230, 0x0250, 0x0330
14151 * The ISA IRQ number is found in bits 2 and 3 of the CfgLsw. It decodes as:
14152 * 00: 10
14153 * 01: 11
14154 * 10: 12
14155 * 11: 15
14157 static unsigned int __devinit advansys_isa_irq_no(PortAddr iop_base)
14159 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
14160 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x03) + 10;
14161 if (chip_irq == 13)
14162 chip_irq = 15;
14163 return chip_irq;
14166 static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
14168 int err = -ENODEV;
14169 PortAddr iop_base = _asc_def_iop_base[id];
14170 struct Scsi_Host *shost;
14171 struct asc_board *board;
14173 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
14174 ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
14175 return -ENODEV;
14177 ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
14178 if (!AscFindSignature(iop_base))
14179 goto release_region;
14180 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
14181 goto release_region;
14183 err = -ENOMEM;
14184 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14185 if (!shost)
14186 goto release_region;
14188 board = shost_priv(shost);
14189 board->irq = advansys_isa_irq_no(iop_base);
14190 board->dev = dev;
14192 err = advansys_board_found(shost, iop_base, ASC_IS_ISA);
14193 if (err)
14194 goto free_host;
14196 dev_set_drvdata(dev, shost);
14197 return 0;
14199 free_host:
14200 scsi_host_put(shost);
14201 release_region:
14202 release_region(iop_base, ASC_IOADR_GAP);
14203 return err;
14206 static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
14208 int ioport = _asc_def_iop_base[id];
14209 advansys_release(dev_get_drvdata(dev));
14210 release_region(ioport, ASC_IOADR_GAP);
14211 return 0;
14214 static struct isa_driver advansys_isa_driver = {
14215 .probe = advansys_isa_probe,
14216 .remove = __devexit_p(advansys_isa_remove),
14217 .driver = {
14218 .owner = THIS_MODULE,
14219 .name = DRV_NAME,
14224 * The VLB IRQ number is found in bits 2 to 4 of the CfgLsw. It decodes as:
14225 * 000: invalid
14226 * 001: 10
14227 * 010: 11
14228 * 011: 12
14229 * 100: invalid
14230 * 101: 14
14231 * 110: 15
14232 * 111: invalid
14234 static unsigned int __devinit advansys_vlb_irq_no(PortAddr iop_base)
14236 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
14237 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x07) + 9;
14238 if ((chip_irq < 10) || (chip_irq == 13) || (chip_irq > 15))
14239 return 0;
14240 return chip_irq;
14243 static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
14245 int err = -ENODEV;
14246 PortAddr iop_base = _asc_def_iop_base[id];
14247 struct Scsi_Host *shost;
14248 struct asc_board *board;
14250 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
14251 ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
14252 return -ENODEV;
14254 ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
14255 if (!AscFindSignature(iop_base))
14256 goto release_region;
14258 * I don't think this condition can actually happen, but the old
14259 * driver did it, and the chances of finding a VLB setup in 2007
14260 * to do testing with is slight to none.
14262 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
14263 goto release_region;
14265 err = -ENOMEM;
14266 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14267 if (!shost)
14268 goto release_region;
14270 board = shost_priv(shost);
14271 board->irq = advansys_vlb_irq_no(iop_base);
14272 board->dev = dev;
14274 err = advansys_board_found(shost, iop_base, ASC_IS_VL);
14275 if (err)
14276 goto free_host;
14278 dev_set_drvdata(dev, shost);
14279 return 0;
14281 free_host:
14282 scsi_host_put(shost);
14283 release_region:
14284 release_region(iop_base, ASC_IOADR_GAP);
14285 return -ENODEV;
14288 static struct isa_driver advansys_vlb_driver = {
14289 .probe = advansys_vlb_probe,
14290 .remove = __devexit_p(advansys_isa_remove),
14291 .driver = {
14292 .owner = THIS_MODULE,
14293 .name = "advansys_vlb",
14297 static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
14298 { "ABP7401" },
14299 { "ABP7501" },
14300 { "" }
14303 MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
14306 * EISA is a little more tricky than PCI; each EISA device may have two
14307 * channels, and this driver is written to make each channel its own Scsi_Host
14309 struct eisa_scsi_data {
14310 struct Scsi_Host *host[2];
14314 * The EISA IRQ number is found in bits 8 to 10 of the CfgLsw. It decodes as:
14315 * 000: 10
14316 * 001: 11
14317 * 010: 12
14318 * 011: invalid
14319 * 100: 14
14320 * 101: 15
14321 * 110: invalid
14322 * 111: invalid
14324 static unsigned int __devinit advansys_eisa_irq_no(struct eisa_device *edev)
14326 unsigned short cfg_lsw = inw(edev->base_addr + 0xc86);
14327 unsigned int chip_irq = ((cfg_lsw >> 8) & 0x07) + 10;
14328 if ((chip_irq == 13) || (chip_irq > 15))
14329 return 0;
14330 return chip_irq;
14333 static int __devinit advansys_eisa_probe(struct device *dev)
14335 int i, ioport, irq = 0;
14336 int err;
14337 struct eisa_device *edev = to_eisa_device(dev);
14338 struct eisa_scsi_data *data;
14340 err = -ENOMEM;
14341 data = kzalloc(sizeof(*data), GFP_KERNEL);
14342 if (!data)
14343 goto fail;
14344 ioport = edev->base_addr + 0xc30;
14346 err = -ENODEV;
14347 for (i = 0; i < 2; i++, ioport += 0x20) {
14348 struct asc_board *board;
14349 struct Scsi_Host *shost;
14350 if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) {
14351 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
14352 ioport + ASC_IOADR_GAP - 1);
14353 continue;
14355 if (!AscFindSignature(ioport)) {
14356 release_region(ioport, ASC_IOADR_GAP);
14357 continue;
14361 * I don't know why we need to do this for EISA chips, but
14362 * not for any others. It looks to be equivalent to
14363 * AscGetChipCfgMsw, but I may have overlooked something,
14364 * so I'm not converting it until I get an EISA board to
14365 * test with.
14367 inw(ioport + 4);
14369 if (!irq)
14370 irq = advansys_eisa_irq_no(edev);
14372 err = -ENOMEM;
14373 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14374 if (!shost)
14375 goto release_region;
14377 board = shost_priv(shost);
14378 board->irq = irq;
14379 board->dev = dev;
14381 err = advansys_board_found(shost, ioport, ASC_IS_EISA);
14382 if (!err) {
14383 data->host[i] = shost;
14384 continue;
14387 scsi_host_put(shost);
14388 release_region:
14389 release_region(ioport, ASC_IOADR_GAP);
14390 break;
14393 if (err)
14394 goto free_data;
14395 dev_set_drvdata(dev, data);
14396 return 0;
14398 free_data:
14399 kfree(data->host[0]);
14400 kfree(data->host[1]);
14401 kfree(data);
14402 fail:
14403 return err;
14406 static __devexit int advansys_eisa_remove(struct device *dev)
14408 int i;
14409 struct eisa_scsi_data *data = dev_get_drvdata(dev);
14411 for (i = 0; i < 2; i++) {
14412 int ioport;
14413 struct Scsi_Host *shost = data->host[i];
14414 if (!shost)
14415 continue;
14416 ioport = shost->io_port;
14417 advansys_release(shost);
14418 release_region(ioport, ASC_IOADR_GAP);
14421 kfree(data);
14422 return 0;
14425 static struct eisa_driver advansys_eisa_driver = {
14426 .id_table = advansys_eisa_table,
14427 .driver = {
14428 .name = DRV_NAME,
14429 .probe = advansys_eisa_probe,
14430 .remove = __devexit_p(advansys_eisa_remove),
14434 /* PCI Devices supported by this driver */
14435 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
14436 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
14437 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14438 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
14439 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14440 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
14441 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14442 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
14443 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14444 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
14445 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14446 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
14447 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14451 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
14453 static void __devinit advansys_set_latency(struct pci_dev *pdev)
14455 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
14456 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
14457 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
14458 } else {
14459 u8 latency;
14460 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
14461 if (latency < 0x20)
14462 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
14466 static int __devinit
14467 advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14469 int err, ioport;
14470 struct Scsi_Host *shost;
14471 struct asc_board *board;
14473 err = pci_enable_device(pdev);
14474 if (err)
14475 goto fail;
14476 err = pci_request_regions(pdev, DRV_NAME);
14477 if (err)
14478 goto disable_device;
14479 pci_set_master(pdev);
14480 advansys_set_latency(pdev);
14482 err = -ENODEV;
14483 if (pci_resource_len(pdev, 0) == 0)
14484 goto release_region;
14486 ioport = pci_resource_start(pdev, 0);
14488 err = -ENOMEM;
14489 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14490 if (!shost)
14491 goto release_region;
14493 board = shost_priv(shost);
14494 board->irq = pdev->irq;
14495 board->dev = &pdev->dev;
14497 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
14498 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
14499 pdev->device == PCI_DEVICE_ID_38C1600_REV1) {
14500 board->flags |= ASC_IS_WIDE_BOARD;
14503 err = advansys_board_found(shost, ioport, ASC_IS_PCI);
14504 if (err)
14505 goto free_host;
14507 pci_set_drvdata(pdev, shost);
14508 return 0;
14510 free_host:
14511 scsi_host_put(shost);
14512 release_region:
14513 pci_release_regions(pdev);
14514 disable_device:
14515 pci_disable_device(pdev);
14516 fail:
14517 return err;
14520 static void __devexit advansys_pci_remove(struct pci_dev *pdev)
14522 advansys_release(pci_get_drvdata(pdev));
14523 pci_release_regions(pdev);
14524 pci_disable_device(pdev);
14527 static struct pci_driver advansys_pci_driver = {
14528 .name = DRV_NAME,
14529 .id_table = advansys_pci_tbl,
14530 .probe = advansys_pci_probe,
14531 .remove = __devexit_p(advansys_pci_remove),
14534 static int __init advansys_init(void)
14536 int error;
14538 error = isa_register_driver(&advansys_isa_driver,
14539 ASC_IOADR_TABLE_MAX_IX);
14540 if (error)
14541 goto fail;
14543 error = isa_register_driver(&advansys_vlb_driver,
14544 ASC_IOADR_TABLE_MAX_IX);
14545 if (error)
14546 goto unregister_isa;
14548 error = eisa_driver_register(&advansys_eisa_driver);
14549 if (error)
14550 goto unregister_vlb;
14552 error = pci_register_driver(&advansys_pci_driver);
14553 if (error)
14554 goto unregister_eisa;
14556 return 0;
14558 unregister_eisa:
14559 eisa_driver_unregister(&advansys_eisa_driver);
14560 unregister_vlb:
14561 isa_unregister_driver(&advansys_vlb_driver);
14562 unregister_isa:
14563 isa_unregister_driver(&advansys_isa_driver);
14564 fail:
14565 return error;
14568 static void __exit advansys_exit(void)
14570 pci_unregister_driver(&advansys_pci_driver);
14571 eisa_driver_unregister(&advansys_eisa_driver);
14572 isa_unregister_driver(&advansys_vlb_driver);
14573 isa_unregister_driver(&advansys_isa_driver);
14576 module_init(advansys_init);
14577 module_exit(advansys_exit);
14579 MODULE_LICENSE("GPL");