added 2.6.29.6 aldebaran kernel
[nao-ulib.git] / kernel / 2.6.29.6-aldebaran-rt / drivers / scsi / advansys.c
blob90d86db7de7da7fbfea65089e41165e9177d0765
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. Add module_param to override ISA/VLB ioport array
71 #ifdef CONFIG_ALLOW_WARNINGS
72 # warning this driver is still not properly converted to the DMA API
73 #endif
75 /* Enable driver /proc statistics. */
76 #define ADVANSYS_STATS
78 /* Enable driver tracing. */
79 #undef ADVANSYS_DEBUG
82 * Portable Data Types
84 * Any instance where a 32-bit long or pointer type is assumed
85 * for precision or HW defined structures, the following define
86 * types must be used. In Linux the char, short, and int types
87 * are all consistent at 8, 16, and 32 bits respectively. Pointers
88 * and long types are 64 bits on Alpha and UltraSPARC.
90 #define ASC_PADDR __u32 /* Physical/Bus address data type. */
91 #define ASC_VADDR __u32 /* Virtual address data type. */
92 #define ASC_DCNT __u32 /* Unsigned Data count type. */
93 #define ASC_SDCNT __s32 /* Signed Data count type. */
95 typedef unsigned char uchar;
97 #ifndef TRUE
98 #define TRUE (1)
99 #endif
100 #ifndef FALSE
101 #define FALSE (0)
102 #endif
104 #define ERR (-1)
105 #define UW_ERR (uint)(0xFFFF)
106 #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
108 #define PCI_VENDOR_ID_ASP 0x10cd
109 #define PCI_DEVICE_ID_ASP_1200A 0x1100
110 #define PCI_DEVICE_ID_ASP_ABP940 0x1200
111 #define PCI_DEVICE_ID_ASP_ABP940U 0x1300
112 #define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
113 #define PCI_DEVICE_ID_38C0800_REV1 0x2500
114 #define PCI_DEVICE_ID_38C1600_REV1 0x2700
117 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
118 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
119 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
120 * SRB structure.
122 #define CC_VERY_LONG_SG_LIST 0
123 #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
125 #define PortAddr unsigned int /* port address size */
126 #define inp(port) inb(port)
127 #define outp(port, byte) outb((byte), (port))
129 #define inpw(port) inw(port)
130 #define outpw(port, word) outw((word), (port))
132 #define ASC_MAX_SG_QUEUE 7
133 #define ASC_MAX_SG_LIST 255
135 #define ASC_CS_TYPE unsigned short
137 #define ASC_IS_ISA (0x0001)
138 #define ASC_IS_ISAPNP (0x0081)
139 #define ASC_IS_EISA (0x0002)
140 #define ASC_IS_PCI (0x0004)
141 #define ASC_IS_PCI_ULTRA (0x0104)
142 #define ASC_IS_PCMCIA (0x0008)
143 #define ASC_IS_MCA (0x0020)
144 #define ASC_IS_VL (0x0040)
145 #define ASC_IS_WIDESCSI_16 (0x0100)
146 #define ASC_IS_WIDESCSI_32 (0x0200)
147 #define ASC_IS_BIG_ENDIAN (0x8000)
149 #define ASC_CHIP_MIN_VER_VL (0x01)
150 #define ASC_CHIP_MAX_VER_VL (0x07)
151 #define ASC_CHIP_MIN_VER_PCI (0x09)
152 #define ASC_CHIP_MAX_VER_PCI (0x0F)
153 #define ASC_CHIP_VER_PCI_BIT (0x08)
154 #define ASC_CHIP_MIN_VER_ISA (0x11)
155 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
156 #define ASC_CHIP_MAX_VER_ISA (0x27)
157 #define ASC_CHIP_VER_ISA_BIT (0x30)
158 #define ASC_CHIP_VER_ISAPNP_BIT (0x20)
159 #define ASC_CHIP_VER_ASYN_BUG (0x21)
160 #define ASC_CHIP_VER_PCI 0x08
161 #define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
162 #define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
163 #define ASC_CHIP_MIN_VER_EISA (0x41)
164 #define ASC_CHIP_MAX_VER_EISA (0x47)
165 #define ASC_CHIP_VER_EISA_BIT (0x40)
166 #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
167 #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
168 #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
169 #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
171 #define ASC_SCSI_ID_BITS 3
172 #define ASC_SCSI_TIX_TYPE uchar
173 #define ASC_ALL_DEVICE_BIT_SET 0xFF
174 #define ASC_SCSI_BIT_ID_TYPE uchar
175 #define ASC_MAX_TID 7
176 #define ASC_MAX_LUN 7
177 #define ASC_SCSI_WIDTH_BIT_SET 0xFF
178 #define ASC_MAX_SENSE_LEN 32
179 #define ASC_MIN_SENSE_LEN 14
180 #define ASC_SCSI_RESET_HOLD_TIME_US 60
183 * Narrow boards only support 12-byte commands, while wide boards
184 * extend to 16-byte commands.
186 #define ASC_MAX_CDB_LEN 12
187 #define ADV_MAX_CDB_LEN 16
189 #define MS_SDTR_LEN 0x03
190 #define MS_WDTR_LEN 0x02
192 #define ASC_SG_LIST_PER_Q 7
193 #define QS_FREE 0x00
194 #define QS_READY 0x01
195 #define QS_DISC1 0x02
196 #define QS_DISC2 0x04
197 #define QS_BUSY 0x08
198 #define QS_ABORTED 0x40
199 #define QS_DONE 0x80
200 #define QC_NO_CALLBACK 0x01
201 #define QC_SG_SWAP_QUEUE 0x02
202 #define QC_SG_HEAD 0x04
203 #define QC_DATA_IN 0x08
204 #define QC_DATA_OUT 0x10
205 #define QC_URGENT 0x20
206 #define QC_MSG_OUT 0x40
207 #define QC_REQ_SENSE 0x80
208 #define QCSG_SG_XFER_LIST 0x02
209 #define QCSG_SG_XFER_MORE 0x04
210 #define QCSG_SG_XFER_END 0x08
211 #define QD_IN_PROGRESS 0x00
212 #define QD_NO_ERROR 0x01
213 #define QD_ABORTED_BY_HOST 0x02
214 #define QD_WITH_ERROR 0x04
215 #define QD_INVALID_REQUEST 0x80
216 #define QD_INVALID_HOST_NUM 0x81
217 #define QD_INVALID_DEVICE 0x82
218 #define QD_ERR_INTERNAL 0xFF
219 #define QHSTA_NO_ERROR 0x00
220 #define QHSTA_M_SEL_TIMEOUT 0x11
221 #define QHSTA_M_DATA_OVER_RUN 0x12
222 #define QHSTA_M_DATA_UNDER_RUN 0x12
223 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
224 #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
225 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
226 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
227 #define QHSTA_D_HOST_ABORT_FAILED 0x23
228 #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
229 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
230 #define QHSTA_D_ASPI_NO_BUF_POOL 0x26
231 #define QHSTA_M_WTM_TIMEOUT 0x41
232 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
233 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
234 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
235 #define QHSTA_M_TARGET_STATUS_BUSY 0x45
236 #define QHSTA_M_BAD_TAG_CODE 0x46
237 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
238 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
239 #define QHSTA_D_LRAM_CMP_ERROR 0x81
240 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
241 #define ASC_FLAG_SCSIQ_REQ 0x01
242 #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
243 #define ASC_FLAG_BIOS_ASYNC_IO 0x04
244 #define ASC_FLAG_SRB_LINEAR_ADDR 0x08
245 #define ASC_FLAG_WIN16 0x10
246 #define ASC_FLAG_WIN32 0x20
247 #define ASC_FLAG_ISA_OVER_16MB 0x40
248 #define ASC_FLAG_DOS_VM_CALLBACK 0x80
249 #define ASC_TAG_FLAG_EXTRA_BYTES 0x10
250 #define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
251 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
252 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
253 #define ASC_SCSIQ_CPY_BEG 4
254 #define ASC_SCSIQ_SGHD_CPY_BEG 2
255 #define ASC_SCSIQ_B_FWD 0
256 #define ASC_SCSIQ_B_BWD 1
257 #define ASC_SCSIQ_B_STATUS 2
258 #define ASC_SCSIQ_B_QNO 3
259 #define ASC_SCSIQ_B_CNTL 4
260 #define ASC_SCSIQ_B_SG_QUEUE_CNT 5
261 #define ASC_SCSIQ_D_DATA_ADDR 8
262 #define ASC_SCSIQ_D_DATA_CNT 12
263 #define ASC_SCSIQ_B_SENSE_LEN 20
264 #define ASC_SCSIQ_DONE_INFO_BEG 22
265 #define ASC_SCSIQ_D_SRBPTR 22
266 #define ASC_SCSIQ_B_TARGET_IX 26
267 #define ASC_SCSIQ_B_CDB_LEN 28
268 #define ASC_SCSIQ_B_TAG_CODE 29
269 #define ASC_SCSIQ_W_VM_ID 30
270 #define ASC_SCSIQ_DONE_STATUS 32
271 #define ASC_SCSIQ_HOST_STATUS 33
272 #define ASC_SCSIQ_SCSI_STATUS 34
273 #define ASC_SCSIQ_CDB_BEG 36
274 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
275 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
276 #define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
277 #define ASC_SCSIQ_B_SG_WK_QP 49
278 #define ASC_SCSIQ_B_SG_WK_IX 50
279 #define ASC_SCSIQ_W_ALT_DC1 52
280 #define ASC_SCSIQ_B_LIST_CNT 6
281 #define ASC_SCSIQ_B_CUR_LIST_CNT 7
282 #define ASC_SGQ_B_SG_CNTL 4
283 #define ASC_SGQ_B_SG_HEAD_QP 5
284 #define ASC_SGQ_B_SG_LIST_CNT 6
285 #define ASC_SGQ_B_SG_CUR_LIST_CNT 7
286 #define ASC_SGQ_LIST_BEG 8
287 #define ASC_DEF_SCSI1_QNG 4
288 #define ASC_MAX_SCSI1_QNG 4
289 #define ASC_DEF_SCSI2_QNG 16
290 #define ASC_MAX_SCSI2_QNG 32
291 #define ASC_TAG_CODE_MASK 0x23
292 #define ASC_STOP_REQ_RISC_STOP 0x01
293 #define ASC_STOP_ACK_RISC_STOP 0x03
294 #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
295 #define ASC_STOP_CLEAN_UP_DISC_Q 0x20
296 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
297 #define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
298 #define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
299 #define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
300 #define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
301 #define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
302 #define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
303 #define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
305 typedef struct asc_scsiq_1 {
306 uchar status;
307 uchar q_no;
308 uchar cntl;
309 uchar sg_queue_cnt;
310 uchar target_id;
311 uchar target_lun;
312 ASC_PADDR data_addr;
313 ASC_DCNT data_cnt;
314 ASC_PADDR sense_addr;
315 uchar sense_len;
316 uchar extra_bytes;
317 } ASC_SCSIQ_1;
319 typedef struct asc_scsiq_2 {
320 ASC_VADDR srb_ptr;
321 uchar target_ix;
322 uchar flag;
323 uchar cdb_len;
324 uchar tag_code;
325 ushort vm_id;
326 } ASC_SCSIQ_2;
328 typedef struct asc_scsiq_3 {
329 uchar done_stat;
330 uchar host_stat;
331 uchar scsi_stat;
332 uchar scsi_msg;
333 } ASC_SCSIQ_3;
335 typedef struct asc_scsiq_4 {
336 uchar cdb[ASC_MAX_CDB_LEN];
337 uchar y_first_sg_list_qp;
338 uchar y_working_sg_qp;
339 uchar y_working_sg_ix;
340 uchar y_res;
341 ushort x_req_count;
342 ushort x_reconnect_rtn;
343 ASC_PADDR x_saved_data_addr;
344 ASC_DCNT x_saved_data_cnt;
345 } ASC_SCSIQ_4;
347 typedef struct asc_q_done_info {
348 ASC_SCSIQ_2 d2;
349 ASC_SCSIQ_3 d3;
350 uchar q_status;
351 uchar q_no;
352 uchar cntl;
353 uchar sense_len;
354 uchar extra_bytes;
355 uchar res;
356 ASC_DCNT remain_bytes;
357 } ASC_QDONE_INFO;
359 typedef struct asc_sg_list {
360 ASC_PADDR addr;
361 ASC_DCNT bytes;
362 } ASC_SG_LIST;
364 typedef struct asc_sg_head {
365 ushort entry_cnt;
366 ushort queue_cnt;
367 ushort entry_to_copy;
368 ushort res;
369 ASC_SG_LIST sg_list[0];
370 } ASC_SG_HEAD;
372 typedef struct asc_scsi_q {
373 ASC_SCSIQ_1 q1;
374 ASC_SCSIQ_2 q2;
375 uchar *cdbptr;
376 ASC_SG_HEAD *sg_head;
377 ushort remain_sg_entry_cnt;
378 ushort next_sg_index;
379 } ASC_SCSI_Q;
381 typedef struct asc_scsi_req_q {
382 ASC_SCSIQ_1 r1;
383 ASC_SCSIQ_2 r2;
384 uchar *cdbptr;
385 ASC_SG_HEAD *sg_head;
386 uchar *sense_ptr;
387 ASC_SCSIQ_3 r3;
388 uchar cdb[ASC_MAX_CDB_LEN];
389 uchar sense[ASC_MIN_SENSE_LEN];
390 } ASC_SCSI_REQ_Q;
392 typedef struct asc_scsi_bios_req_q {
393 ASC_SCSIQ_1 r1;
394 ASC_SCSIQ_2 r2;
395 uchar *cdbptr;
396 ASC_SG_HEAD *sg_head;
397 uchar *sense_ptr;
398 ASC_SCSIQ_3 r3;
399 uchar cdb[ASC_MAX_CDB_LEN];
400 uchar sense[ASC_MIN_SENSE_LEN];
401 } ASC_SCSI_BIOS_REQ_Q;
403 typedef struct asc_risc_q {
404 uchar fwd;
405 uchar bwd;
406 ASC_SCSIQ_1 i1;
407 ASC_SCSIQ_2 i2;
408 ASC_SCSIQ_3 i3;
409 ASC_SCSIQ_4 i4;
410 } ASC_RISC_Q;
412 typedef struct asc_sg_list_q {
413 uchar seq_no;
414 uchar q_no;
415 uchar cntl;
416 uchar sg_head_qp;
417 uchar sg_list_cnt;
418 uchar sg_cur_list_cnt;
419 } ASC_SG_LIST_Q;
421 typedef struct asc_risc_sg_list_q {
422 uchar fwd;
423 uchar bwd;
424 ASC_SG_LIST_Q sg;
425 ASC_SG_LIST sg_list[7];
426 } ASC_RISC_SG_LIST_Q;
428 #define ASCQ_ERR_Q_STATUS 0x0D
429 #define ASCQ_ERR_CUR_QNG 0x17
430 #define ASCQ_ERR_SG_Q_LINKS 0x18
431 #define ASCQ_ERR_ISR_RE_ENTRY 0x1A
432 #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
433 #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
436 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
438 #define ASC_WARN_NO_ERROR 0x0000
439 #define ASC_WARN_IO_PORT_ROTATE 0x0001
440 #define ASC_WARN_EEPROM_CHKSUM 0x0002
441 #define ASC_WARN_IRQ_MODIFIED 0x0004
442 #define ASC_WARN_AUTO_CONFIG 0x0008
443 #define ASC_WARN_CMD_QNG_CONFLICT 0x0010
444 #define ASC_WARN_EEPROM_RECOVER 0x0020
445 #define ASC_WARN_CFG_MSW_RECOVER 0x0040
448 * Error code values are set in {ASC/ADV}_DVC_VAR 'err_code'.
450 #define ASC_IERR_NO_CARRIER 0x0001 /* No more carrier memory */
451 #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
452 #define ASC_IERR_SET_PC_ADDR 0x0004
453 #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
454 #define ASC_IERR_ILLEGAL_CONNECTION 0x0010 /* Illegal cable connection */
455 #define ASC_IERR_SINGLE_END_DEVICE 0x0020 /* SE device on DIFF bus */
456 #define ASC_IERR_REVERSED_CABLE 0x0040 /* Narrow flat cable reversed */
457 #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
458 #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD device on LVD port */
459 #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
460 #define ASC_IERR_NO_BUS_TYPE 0x0400
461 #define ASC_IERR_BIST_PRE_TEST 0x0800 /* BIST pre-test error */
462 #define ASC_IERR_BIST_RAM_TEST 0x1000 /* BIST RAM test error */
463 #define ASC_IERR_BAD_CHIPTYPE 0x2000 /* Invalid chip_type setting */
465 #define ASC_DEF_MAX_TOTAL_QNG (0xF0)
466 #define ASC_MIN_TAG_Q_PER_DVC (0x04)
467 #define ASC_MIN_FREE_Q (0x02)
468 #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
469 #define ASC_MAX_TOTAL_QNG 240
470 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
471 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
472 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
473 #define ASC_MAX_INRAM_TAG_QNG 16
474 #define ASC_IOADR_GAP 0x10
475 #define ASC_SYN_MAX_OFFSET 0x0F
476 #define ASC_DEF_SDTR_OFFSET 0x0F
477 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
478 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
480 /* The narrow chip only supports a limited selection of transfer rates.
481 * These are encoded in the range 0..7 or 0..15 depending whether the chip
482 * is Ultra-capable or not. These tables let us convert from one to the other.
484 static const unsigned char asc_syn_xfer_period[8] = {
485 25, 30, 35, 40, 50, 60, 70, 85
488 static const unsigned char asc_syn_ultra_xfer_period[16] = {
489 12, 19, 25, 32, 38, 44, 50, 57, 63, 69, 75, 82, 88, 94, 100, 107
492 typedef struct ext_msg {
493 uchar msg_type;
494 uchar msg_len;
495 uchar msg_req;
496 union {
497 struct {
498 uchar sdtr_xfer_period;
499 uchar sdtr_req_ack_offset;
500 } sdtr;
501 struct {
502 uchar wdtr_width;
503 } wdtr;
504 struct {
505 uchar mdp_b3;
506 uchar mdp_b2;
507 uchar mdp_b1;
508 uchar mdp_b0;
509 } mdp;
510 } u_ext_msg;
511 uchar res;
512 } EXT_MSG;
514 #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
515 #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
516 #define wdtr_width u_ext_msg.wdtr.wdtr_width
517 #define mdp_b3 u_ext_msg.mdp_b3
518 #define mdp_b2 u_ext_msg.mdp_b2
519 #define mdp_b1 u_ext_msg.mdp_b1
520 #define mdp_b0 u_ext_msg.mdp_b0
522 typedef struct asc_dvc_cfg {
523 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
524 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
525 ASC_SCSI_BIT_ID_TYPE disc_enable;
526 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
527 uchar chip_scsi_id;
528 uchar isa_dma_speed;
529 uchar isa_dma_channel;
530 uchar chip_version;
531 ushort mcode_date;
532 ushort mcode_version;
533 uchar max_tag_qng[ASC_MAX_TID + 1];
534 uchar sdtr_period_offset[ASC_MAX_TID + 1];
535 uchar adapter_info[6];
536 } ASC_DVC_CFG;
538 #define ASC_DEF_DVC_CNTL 0xFFFF
539 #define ASC_DEF_CHIP_SCSI_ID 7
540 #define ASC_DEF_ISA_DMA_SPEED 4
541 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001
542 #define ASC_INIT_STATE_END_GET_CFG 0x0002
543 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004
544 #define ASC_INIT_STATE_END_SET_CFG 0x0008
545 #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
546 #define ASC_INIT_STATE_END_LOAD_MC 0x0020
547 #define ASC_INIT_STATE_BEG_INQUIRY 0x0040
548 #define ASC_INIT_STATE_END_INQUIRY 0x0080
549 #define ASC_INIT_RESET_SCSI_DONE 0x0100
550 #define ASC_INIT_STATE_WITHOUT_EEP 0x8000
551 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001
552 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
553 #define ASC_MIN_TAGGED_CMD 7
554 #define ASC_MAX_SCSI_RESET_WAIT 30
555 #define ASC_OVERRUN_BSIZE 64
557 struct asc_dvc_var; /* Forward Declaration. */
559 typedef struct asc_dvc_var {
560 PortAddr iop_base;
561 ushort err_code;
562 ushort dvc_cntl;
563 ushort bug_fix_cntl;
564 ushort bus_type;
565 ASC_SCSI_BIT_ID_TYPE init_sdtr;
566 ASC_SCSI_BIT_ID_TYPE sdtr_done;
567 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
568 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
569 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
570 ASC_SCSI_BIT_ID_TYPE start_motor;
571 uchar *overrun_buf;
572 dma_addr_t overrun_dma;
573 uchar scsi_reset_wait;
574 uchar chip_no;
575 char is_in_int;
576 uchar max_total_qng;
577 uchar cur_total_qng;
578 uchar in_critical_cnt;
579 uchar last_q_shortage;
580 ushort init_state;
581 uchar cur_dvc_qng[ASC_MAX_TID + 1];
582 uchar max_dvc_qng[ASC_MAX_TID + 1];
583 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
584 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
585 const uchar *sdtr_period_tbl;
586 ASC_DVC_CFG *cfg;
587 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
588 char redo_scam;
589 ushort res2;
590 uchar dos_int13_table[ASC_MAX_TID + 1];
591 ASC_DCNT max_dma_count;
592 ASC_SCSI_BIT_ID_TYPE no_scam;
593 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
594 uchar min_sdtr_index;
595 uchar max_sdtr_index;
596 struct asc_board *drv_ptr;
597 int ptr_map_count;
598 void **ptr_map;
599 ASC_DCNT uc_break;
600 } ASC_DVC_VAR;
602 typedef struct asc_dvc_inq_info {
603 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
604 } ASC_DVC_INQ_INFO;
606 typedef struct asc_cap_info {
607 ASC_DCNT lba;
608 ASC_DCNT blk_size;
609 } ASC_CAP_INFO;
611 typedef struct asc_cap_info_array {
612 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
613 } ASC_CAP_INFO_ARRAY;
615 #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
616 #define ASC_MCNTL_NULL_TARGET (ushort)0x0002
617 #define ASC_CNTL_INITIATOR (ushort)0x0001
618 #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
619 #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
620 #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
621 #define ASC_CNTL_NO_SCAM (ushort)0x0010
622 #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
623 #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
624 #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
625 #define ASC_CNTL_RESET_SCSI (ushort)0x0200
626 #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
627 #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
628 #define ASC_CNTL_SCSI_PARITY (ushort)0x1000
629 #define ASC_CNTL_BURST_MODE (ushort)0x2000
630 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
631 #define ASC_EEP_DVC_CFG_BEG_VL 2
632 #define ASC_EEP_MAX_DVC_ADDR_VL 15
633 #define ASC_EEP_DVC_CFG_BEG 32
634 #define ASC_EEP_MAX_DVC_ADDR 45
635 #define ASC_EEP_MAX_RETRY 20
638 * These macros keep the chip SCSI id and ISA DMA speed
639 * bitfields in board order. C bitfields aren't portable
640 * between big and little-endian platforms so they are
641 * not used.
644 #define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
645 #define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
646 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
647 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
648 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
649 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
651 typedef struct asceep_config {
652 ushort cfg_lsw;
653 ushort cfg_msw;
654 uchar init_sdtr;
655 uchar disc_enable;
656 uchar use_cmd_qng;
657 uchar start_motor;
658 uchar max_total_qng;
659 uchar max_tag_qng;
660 uchar bios_scan;
661 uchar power_up_wait;
662 uchar no_scam;
663 uchar id_speed; /* low order 4 bits is chip scsi id */
664 /* high order 4 bits is isa dma speed */
665 uchar dos_int13_table[ASC_MAX_TID + 1];
666 uchar adapter_info[6];
667 ushort cntl;
668 ushort chksum;
669 } ASCEEP_CONFIG;
671 #define ASC_EEP_CMD_READ 0x80
672 #define ASC_EEP_CMD_WRITE 0x40
673 #define ASC_EEP_CMD_WRITE_ABLE 0x30
674 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
675 #define ASCV_MSGOUT_BEG 0x0000
676 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
677 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
678 #define ASCV_BREAK_SAVED_CODE (ushort)0x0006
679 #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
680 #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
681 #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
682 #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
683 #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
684 #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
685 #define ASCV_BREAK_ADDR (ushort)0x0028
686 #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
687 #define ASCV_BREAK_CONTROL (ushort)0x002C
688 #define ASCV_BREAK_HIT_COUNT (ushort)0x002E
690 #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
691 #define ASCV_MCODE_CHKSUM_W (ushort)0x0032
692 #define ASCV_MCODE_SIZE_W (ushort)0x0034
693 #define ASCV_STOP_CODE_B (ushort)0x0036
694 #define ASCV_DVC_ERR_CODE_B (ushort)0x0037
695 #define ASCV_OVERRUN_PADDR_D (ushort)0x0038
696 #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
697 #define ASCV_HALTCODE_W (ushort)0x0040
698 #define ASCV_CHKSUM_W (ushort)0x0042
699 #define ASCV_MC_DATE_W (ushort)0x0044
700 #define ASCV_MC_VER_W (ushort)0x0046
701 #define ASCV_NEXTRDY_B (ushort)0x0048
702 #define ASCV_DONENEXT_B (ushort)0x0049
703 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
704 #define ASCV_SCSIBUSY_B (ushort)0x004B
705 #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
706 #define ASCV_CURCDB_B (ushort)0x004D
707 #define ASCV_RCLUN_B (ushort)0x004E
708 #define ASCV_BUSY_QHEAD_B (ushort)0x004F
709 #define ASCV_DISC1_QHEAD_B (ushort)0x0050
710 #define ASCV_DISC_ENABLE_B (ushort)0x0052
711 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
712 #define ASCV_HOSTSCSI_ID_B (ushort)0x0055
713 #define ASCV_MCODE_CNTL_B (ushort)0x0056
714 #define ASCV_NULL_TARGET_B (ushort)0x0057
715 #define ASCV_FREE_Q_HEAD_W (ushort)0x0058
716 #define ASCV_DONE_Q_TAIL_W (ushort)0x005A
717 #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
718 #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
719 #define ASCV_HOST_FLAG_B (ushort)0x005D
720 #define ASCV_TOTAL_READY_Q_B (ushort)0x0064
721 #define ASCV_VER_SERIAL_B (ushort)0x0065
722 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
723 #define ASCV_WTM_FLAG_B (ushort)0x0068
724 #define ASCV_RISC_FLAG_B (ushort)0x006A
725 #define ASCV_REQ_SG_LIST_QP (ushort)0x006B
726 #define ASC_HOST_FLAG_IN_ISR 0x01
727 #define ASC_HOST_FLAG_ACK_INT 0x02
728 #define ASC_RISC_FLAG_GEN_INT 0x01
729 #define ASC_RISC_FLAG_REQ_SG_LIST 0x02
730 #define IOP_CTRL (0x0F)
731 #define IOP_STATUS (0x0E)
732 #define IOP_INT_ACK IOP_STATUS
733 #define IOP_REG_IFC (0x0D)
734 #define IOP_SYN_OFFSET (0x0B)
735 #define IOP_EXTRA_CONTROL (0x0D)
736 #define IOP_REG_PC (0x0C)
737 #define IOP_RAM_ADDR (0x0A)
738 #define IOP_RAM_DATA (0x08)
739 #define IOP_EEP_DATA (0x06)
740 #define IOP_EEP_CMD (0x07)
741 #define IOP_VERSION (0x03)
742 #define IOP_CONFIG_HIGH (0x04)
743 #define IOP_CONFIG_LOW (0x02)
744 #define IOP_SIG_BYTE (0x01)
745 #define IOP_SIG_WORD (0x00)
746 #define IOP_REG_DC1 (0x0E)
747 #define IOP_REG_DC0 (0x0C)
748 #define IOP_REG_SB (0x0B)
749 #define IOP_REG_DA1 (0x0A)
750 #define IOP_REG_DA0 (0x08)
751 #define IOP_REG_SC (0x09)
752 #define IOP_DMA_SPEED (0x07)
753 #define IOP_REG_FLAG (0x07)
754 #define IOP_FIFO_H (0x06)
755 #define IOP_FIFO_L (0x04)
756 #define IOP_REG_ID (0x05)
757 #define IOP_REG_QP (0x03)
758 #define IOP_REG_IH (0x02)
759 #define IOP_REG_IX (0x01)
760 #define IOP_REG_AX (0x00)
761 #define IFC_REG_LOCK (0x00)
762 #define IFC_REG_UNLOCK (0x09)
763 #define IFC_WR_EN_FILTER (0x10)
764 #define IFC_RD_NO_EEPROM (0x10)
765 #define IFC_SLEW_RATE (0x20)
766 #define IFC_ACT_NEG (0x40)
767 #define IFC_INP_FILTER (0x80)
768 #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
769 #define SC_SEL (uchar)(0x80)
770 #define SC_BSY (uchar)(0x40)
771 #define SC_ACK (uchar)(0x20)
772 #define SC_REQ (uchar)(0x10)
773 #define SC_ATN (uchar)(0x08)
774 #define SC_IO (uchar)(0x04)
775 #define SC_CD (uchar)(0x02)
776 #define SC_MSG (uchar)(0x01)
777 #define SEC_SCSI_CTL (uchar)(0x80)
778 #define SEC_ACTIVE_NEGATE (uchar)(0x40)
779 #define SEC_SLEW_RATE (uchar)(0x20)
780 #define SEC_ENABLE_FILTER (uchar)(0x10)
781 #define ASC_HALT_EXTMSG_IN (ushort)0x8000
782 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
783 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
784 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
785 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
786 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
787 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
788 #define ASC_MAX_QNO 0xF8
789 #define ASC_DATA_SEC_BEG (ushort)0x0080
790 #define ASC_DATA_SEC_END (ushort)0x0080
791 #define ASC_CODE_SEC_BEG (ushort)0x0080
792 #define ASC_CODE_SEC_END (ushort)0x0080
793 #define ASC_QADR_BEG (0x4000)
794 #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
795 #define ASC_QADR_END (ushort)0x7FFF
796 #define ASC_QLAST_ADR (ushort)0x7FC0
797 #define ASC_QBLK_SIZE 0x40
798 #define ASC_BIOS_DATA_QBEG 0xF8
799 #define ASC_MIN_ACTIVE_QNO 0x01
800 #define ASC_QLINK_END 0xFF
801 #define ASC_EEPROM_WORDS 0x10
802 #define ASC_MAX_MGS_LEN 0x10
803 #define ASC_BIOS_ADDR_DEF 0xDC00
804 #define ASC_BIOS_SIZE 0x3800
805 #define ASC_BIOS_RAM_OFF 0x3800
806 #define ASC_BIOS_RAM_SIZE 0x800
807 #define ASC_BIOS_MIN_ADDR 0xC000
808 #define ASC_BIOS_MAX_ADDR 0xEC00
809 #define ASC_BIOS_BANK_SIZE 0x0400
810 #define ASC_MCODE_START_ADDR 0x0080
811 #define ASC_CFG0_HOST_INT_ON 0x0020
812 #define ASC_CFG0_BIOS_ON 0x0040
813 #define ASC_CFG0_VERA_BURST_ON 0x0080
814 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
815 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
816 #define ASC_CFG1_LRAM_8BITS_ON 0x0800
817 #define ASC_CFG_MSW_CLR_MASK 0x3080
818 #define CSW_TEST1 (ASC_CS_TYPE)0x8000
819 #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
820 #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
821 #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
822 #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
823 #define CSW_TEST2 (ASC_CS_TYPE)0x0400
824 #define CSW_TEST3 (ASC_CS_TYPE)0x0200
825 #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
826 #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
827 #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
828 #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
829 #define CSW_HALTED (ASC_CS_TYPE)0x0010
830 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
831 #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
832 #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
833 #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
834 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
835 #define CIW_INT_ACK (ASC_CS_TYPE)0x0100
836 #define CIW_TEST1 (ASC_CS_TYPE)0x0200
837 #define CIW_TEST2 (ASC_CS_TYPE)0x0400
838 #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
839 #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
840 #define CC_CHIP_RESET (uchar)0x80
841 #define CC_SCSI_RESET (uchar)0x40
842 #define CC_HALT (uchar)0x20
843 #define CC_SINGLE_STEP (uchar)0x10
844 #define CC_DMA_ABLE (uchar)0x08
845 #define CC_TEST (uchar)0x04
846 #define CC_BANK_ONE (uchar)0x02
847 #define CC_DIAG (uchar)0x01
848 #define ASC_1000_ID0W 0x04C1
849 #define ASC_1000_ID0W_FIX 0x00C1
850 #define ASC_1000_ID1B 0x25
851 #define ASC_EISA_REV_IOP_MASK (0x0C83)
852 #define ASC_EISA_CFG_IOP_MASK (0x0C86)
853 #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
854 #define INS_HALTINT (ushort)0x6281
855 #define INS_HALT (ushort)0x6280
856 #define INS_SINT (ushort)0x6200
857 #define INS_RFLAG_WTM (ushort)0x7380
858 #define ASC_MC_SAVE_CODE_WSIZE 0x500
859 #define ASC_MC_SAVE_DATA_WSIZE 0x40
861 typedef struct asc_mc_saved {
862 ushort data[ASC_MC_SAVE_DATA_WSIZE];
863 ushort code[ASC_MC_SAVE_CODE_WSIZE];
864 } ASC_MC_SAVED;
866 #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
867 #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
868 #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
869 #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
870 #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
871 #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
872 #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
873 #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
874 #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
875 #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
876 #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data))
877 #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id))
878 #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data)
879 #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id))
880 #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
881 #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
882 #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
883 #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
884 #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
885 #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
886 #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
887 #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
888 #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
889 #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
890 #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
891 #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
892 #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
893 #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
894 #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
895 #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
896 #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
897 #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
898 #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
899 #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
900 #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
901 #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
902 #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
903 #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
904 #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
905 #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
906 #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
907 #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
908 #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
909 #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
910 #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
911 #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
912 #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
913 #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
914 #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
915 #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
916 #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
917 #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
918 #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
919 #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
920 #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
921 #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
922 #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
923 #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
924 #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
925 #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
926 #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
927 #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
928 #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
929 #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
930 #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
931 #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
932 #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
935 * Portable Data Types
937 * Any instance where a 32-bit long or pointer type is assumed
938 * for precision or HW defined structures, the following define
939 * types must be used. In Linux the char, short, and int types
940 * are all consistent at 8, 16, and 32 bits respectively. Pointers
941 * and long types are 64 bits on Alpha and UltraSPARC.
943 #define ADV_PADDR __u32 /* Physical address data type. */
944 #define ADV_VADDR __u32 /* Virtual address data type. */
945 #define ADV_DCNT __u32 /* Unsigned Data count type. */
946 #define ADV_SDCNT __s32 /* Signed Data count type. */
949 * These macros are used to convert a virtual address to a
950 * 32-bit value. This currently can be used on Linux Alpha
951 * which uses 64-bit virtual address but a 32-bit bus address.
952 * This is likely to break in the future, but doing this now
953 * will give us time to change the HW and FW to handle 64-bit
954 * addresses.
956 #define ADV_VADDR_TO_U32 virt_to_bus
957 #define ADV_U32_TO_VADDR bus_to_virt
959 #define AdvPortAddr void __iomem * /* Virtual memory address size */
962 * Define Adv Library required memory access macros.
964 #define ADV_MEM_READB(addr) readb(addr)
965 #define ADV_MEM_READW(addr) readw(addr)
966 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
967 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
968 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
970 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
973 * Define total number of simultaneous maximum element scatter-gather
974 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
975 * maximum number of outstanding commands per wide host adapter. Each
976 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
977 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
978 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
979 * structures or 255 scatter-gather elements.
981 #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
984 * Define maximum number of scatter-gather elements per request.
986 #define ADV_MAX_SG_LIST 255
987 #define NO_OF_SG_PER_BLOCK 15
989 #define ADV_EEP_DVC_CFG_BEGIN (0x00)
990 #define ADV_EEP_DVC_CFG_END (0x15)
991 #define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
992 #define ADV_EEP_MAX_WORD_ADDR (0x1E)
994 #define ADV_EEP_DELAY_MS 100
996 #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
997 #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
999 * For the ASC3550 Bit 13 is Termination Polarity control bit.
1000 * For later ICs Bit 13 controls whether the CIS (Card Information
1001 * Service Section) is loaded from EEPROM.
1003 #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
1004 #define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1006 * ASC38C1600 Bit 11
1008 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1009 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1010 * Function 0 will specify INT B.
1012 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1013 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1014 * Function 1 will specify INT A.
1016 #define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
1018 typedef struct adveep_3550_config {
1019 /* Word Offset, Description */
1021 ushort cfg_lsw; /* 00 power up initialization */
1022 /* bit 13 set - Term Polarity Control */
1023 /* bit 14 set - BIOS Enable */
1024 /* bit 15 set - Big Endian Mode */
1025 ushort cfg_msw; /* 01 unused */
1026 ushort disc_enable; /* 02 disconnect enable */
1027 ushort wdtr_able; /* 03 Wide DTR able */
1028 ushort sdtr_able; /* 04 Synchronous DTR able */
1029 ushort start_motor; /* 05 send start up motor */
1030 ushort tagqng_able; /* 06 tag queuing able */
1031 ushort bios_scan; /* 07 BIOS device control */
1032 ushort scam_tolerant; /* 08 no scam */
1034 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1035 uchar bios_boot_delay; /* power up wait */
1037 uchar scsi_reset_delay; /* 10 reset delay */
1038 uchar bios_id_lun; /* first boot device scsi id & lun */
1039 /* high nibble is lun */
1040 /* low nibble is scsi id */
1042 uchar termination; /* 11 0 - automatic */
1043 /* 1 - low off / high off */
1044 /* 2 - low off / high on */
1045 /* 3 - low on / high on */
1046 /* There is no low on / high off */
1048 uchar reserved1; /* reserved byte (not used) */
1050 ushort bios_ctrl; /* 12 BIOS control bits */
1051 /* bit 0 BIOS don't act as initiator. */
1052 /* bit 1 BIOS > 1 GB support */
1053 /* bit 2 BIOS > 2 Disk Support */
1054 /* bit 3 BIOS don't support removables */
1055 /* bit 4 BIOS support bootable CD */
1056 /* bit 5 BIOS scan enabled */
1057 /* bit 6 BIOS support multiple LUNs */
1058 /* bit 7 BIOS display of message */
1059 /* bit 8 SCAM disabled */
1060 /* bit 9 Reset SCSI bus during init. */
1061 /* bit 10 */
1062 /* bit 11 No verbose initialization. */
1063 /* bit 12 SCSI parity enabled */
1064 /* bit 13 */
1065 /* bit 14 */
1066 /* bit 15 */
1067 ushort ultra_able; /* 13 ULTRA speed able */
1068 ushort reserved2; /* 14 reserved */
1069 uchar max_host_qng; /* 15 maximum host queuing */
1070 uchar max_dvc_qng; /* maximum per device queuing */
1071 ushort dvc_cntl; /* 16 control bit for driver */
1072 ushort bug_fix; /* 17 control bit for bug fix */
1073 ushort serial_number_word1; /* 18 Board serial number word 1 */
1074 ushort serial_number_word2; /* 19 Board serial number word 2 */
1075 ushort serial_number_word3; /* 20 Board serial number word 3 */
1076 ushort check_sum; /* 21 EEP check sum */
1077 uchar oem_name[16]; /* 22 OEM name */
1078 ushort dvc_err_code; /* 30 last device driver error code */
1079 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1080 ushort adv_err_addr; /* 32 last uc error address */
1081 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1082 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1083 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1084 ushort num_of_err; /* 36 number of error */
1085 } ADVEEP_3550_CONFIG;
1087 typedef struct adveep_38C0800_config {
1088 /* Word Offset, Description */
1090 ushort cfg_lsw; /* 00 power up initialization */
1091 /* bit 13 set - Load CIS */
1092 /* bit 14 set - BIOS Enable */
1093 /* bit 15 set - Big Endian Mode */
1094 ushort cfg_msw; /* 01 unused */
1095 ushort disc_enable; /* 02 disconnect enable */
1096 ushort wdtr_able; /* 03 Wide DTR able */
1097 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1098 ushort start_motor; /* 05 send start up motor */
1099 ushort tagqng_able; /* 06 tag queuing able */
1100 ushort bios_scan; /* 07 BIOS device control */
1101 ushort scam_tolerant; /* 08 no scam */
1103 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1104 uchar bios_boot_delay; /* power up wait */
1106 uchar scsi_reset_delay; /* 10 reset delay */
1107 uchar bios_id_lun; /* first boot device scsi id & lun */
1108 /* high nibble is lun */
1109 /* low nibble is scsi id */
1111 uchar termination_se; /* 11 0 - automatic */
1112 /* 1 - low off / high off */
1113 /* 2 - low off / high on */
1114 /* 3 - low on / high on */
1115 /* There is no low on / high off */
1117 uchar termination_lvd; /* 11 0 - automatic */
1118 /* 1 - low off / high off */
1119 /* 2 - low off / high on */
1120 /* 3 - low on / high on */
1121 /* There is no low on / high off */
1123 ushort bios_ctrl; /* 12 BIOS control bits */
1124 /* bit 0 BIOS don't act as initiator. */
1125 /* bit 1 BIOS > 1 GB support */
1126 /* bit 2 BIOS > 2 Disk Support */
1127 /* bit 3 BIOS don't support removables */
1128 /* bit 4 BIOS support bootable CD */
1129 /* bit 5 BIOS scan enabled */
1130 /* bit 6 BIOS support multiple LUNs */
1131 /* bit 7 BIOS display of message */
1132 /* bit 8 SCAM disabled */
1133 /* bit 9 Reset SCSI bus during init. */
1134 /* bit 10 */
1135 /* bit 11 No verbose initialization. */
1136 /* bit 12 SCSI parity enabled */
1137 /* bit 13 */
1138 /* bit 14 */
1139 /* bit 15 */
1140 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1141 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1142 uchar max_host_qng; /* 15 maximum host queueing */
1143 uchar max_dvc_qng; /* maximum per device queuing */
1144 ushort dvc_cntl; /* 16 control bit for driver */
1145 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1146 ushort serial_number_word1; /* 18 Board serial number word 1 */
1147 ushort serial_number_word2; /* 19 Board serial number word 2 */
1148 ushort serial_number_word3; /* 20 Board serial number word 3 */
1149 ushort check_sum; /* 21 EEP check sum */
1150 uchar oem_name[16]; /* 22 OEM name */
1151 ushort dvc_err_code; /* 30 last device driver error code */
1152 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1153 ushort adv_err_addr; /* 32 last uc error address */
1154 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1155 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1156 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1157 ushort reserved36; /* 36 reserved */
1158 ushort reserved37; /* 37 reserved */
1159 ushort reserved38; /* 38 reserved */
1160 ushort reserved39; /* 39 reserved */
1161 ushort reserved40; /* 40 reserved */
1162 ushort reserved41; /* 41 reserved */
1163 ushort reserved42; /* 42 reserved */
1164 ushort reserved43; /* 43 reserved */
1165 ushort reserved44; /* 44 reserved */
1166 ushort reserved45; /* 45 reserved */
1167 ushort reserved46; /* 46 reserved */
1168 ushort reserved47; /* 47 reserved */
1169 ushort reserved48; /* 48 reserved */
1170 ushort reserved49; /* 49 reserved */
1171 ushort reserved50; /* 50 reserved */
1172 ushort reserved51; /* 51 reserved */
1173 ushort reserved52; /* 52 reserved */
1174 ushort reserved53; /* 53 reserved */
1175 ushort reserved54; /* 54 reserved */
1176 ushort reserved55; /* 55 reserved */
1177 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1178 ushort cisprt_msw; /* 57 CIS PTR MSW */
1179 ushort subsysvid; /* 58 SubSystem Vendor ID */
1180 ushort subsysid; /* 59 SubSystem ID */
1181 ushort reserved60; /* 60 reserved */
1182 ushort reserved61; /* 61 reserved */
1183 ushort reserved62; /* 62 reserved */
1184 ushort reserved63; /* 63 reserved */
1185 } ADVEEP_38C0800_CONFIG;
1187 typedef struct adveep_38C1600_config {
1188 /* Word Offset, Description */
1190 ushort cfg_lsw; /* 00 power up initialization */
1191 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
1192 /* clear - Func. 0 INTA, Func. 1 INTB */
1193 /* bit 13 set - Load CIS */
1194 /* bit 14 set - BIOS Enable */
1195 /* bit 15 set - Big Endian Mode */
1196 ushort cfg_msw; /* 01 unused */
1197 ushort disc_enable; /* 02 disconnect enable */
1198 ushort wdtr_able; /* 03 Wide DTR able */
1199 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1200 ushort start_motor; /* 05 send start up motor */
1201 ushort tagqng_able; /* 06 tag queuing able */
1202 ushort bios_scan; /* 07 BIOS device control */
1203 ushort scam_tolerant; /* 08 no scam */
1205 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1206 uchar bios_boot_delay; /* power up wait */
1208 uchar scsi_reset_delay; /* 10 reset delay */
1209 uchar bios_id_lun; /* first boot device scsi id & lun */
1210 /* high nibble is lun */
1211 /* low nibble is scsi id */
1213 uchar termination_se; /* 11 0 - automatic */
1214 /* 1 - low off / high off */
1215 /* 2 - low off / high on */
1216 /* 3 - low on / high on */
1217 /* There is no low on / high off */
1219 uchar termination_lvd; /* 11 0 - automatic */
1220 /* 1 - low off / high off */
1221 /* 2 - low off / high on */
1222 /* 3 - low on / high on */
1223 /* There is no low on / high off */
1225 ushort bios_ctrl; /* 12 BIOS control bits */
1226 /* bit 0 BIOS don't act as initiator. */
1227 /* bit 1 BIOS > 1 GB support */
1228 /* bit 2 BIOS > 2 Disk Support */
1229 /* bit 3 BIOS don't support removables */
1230 /* bit 4 BIOS support bootable CD */
1231 /* bit 5 BIOS scan enabled */
1232 /* bit 6 BIOS support multiple LUNs */
1233 /* bit 7 BIOS display of message */
1234 /* bit 8 SCAM disabled */
1235 /* bit 9 Reset SCSI bus during init. */
1236 /* bit 10 Basic Integrity Checking disabled */
1237 /* bit 11 No verbose initialization. */
1238 /* bit 12 SCSI parity enabled */
1239 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
1240 /* bit 14 */
1241 /* bit 15 */
1242 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1243 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1244 uchar max_host_qng; /* 15 maximum host queueing */
1245 uchar max_dvc_qng; /* maximum per device queuing */
1246 ushort dvc_cntl; /* 16 control bit for driver */
1247 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1248 ushort serial_number_word1; /* 18 Board serial number word 1 */
1249 ushort serial_number_word2; /* 19 Board serial number word 2 */
1250 ushort serial_number_word3; /* 20 Board serial number word 3 */
1251 ushort check_sum; /* 21 EEP check sum */
1252 uchar oem_name[16]; /* 22 OEM name */
1253 ushort dvc_err_code; /* 30 last device driver error code */
1254 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1255 ushort adv_err_addr; /* 32 last uc error address */
1256 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1257 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1258 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1259 ushort reserved36; /* 36 reserved */
1260 ushort reserved37; /* 37 reserved */
1261 ushort reserved38; /* 38 reserved */
1262 ushort reserved39; /* 39 reserved */
1263 ushort reserved40; /* 40 reserved */
1264 ushort reserved41; /* 41 reserved */
1265 ushort reserved42; /* 42 reserved */
1266 ushort reserved43; /* 43 reserved */
1267 ushort reserved44; /* 44 reserved */
1268 ushort reserved45; /* 45 reserved */
1269 ushort reserved46; /* 46 reserved */
1270 ushort reserved47; /* 47 reserved */
1271 ushort reserved48; /* 48 reserved */
1272 ushort reserved49; /* 49 reserved */
1273 ushort reserved50; /* 50 reserved */
1274 ushort reserved51; /* 51 reserved */
1275 ushort reserved52; /* 52 reserved */
1276 ushort reserved53; /* 53 reserved */
1277 ushort reserved54; /* 54 reserved */
1278 ushort reserved55; /* 55 reserved */
1279 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1280 ushort cisprt_msw; /* 57 CIS PTR MSW */
1281 ushort subsysvid; /* 58 SubSystem Vendor ID */
1282 ushort subsysid; /* 59 SubSystem ID */
1283 ushort reserved60; /* 60 reserved */
1284 ushort reserved61; /* 61 reserved */
1285 ushort reserved62; /* 62 reserved */
1286 ushort reserved63; /* 63 reserved */
1287 } ADVEEP_38C1600_CONFIG;
1290 * EEPROM Commands
1292 #define ASC_EEP_CMD_DONE 0x0200
1294 /* bios_ctrl */
1295 #define BIOS_CTRL_BIOS 0x0001
1296 #define BIOS_CTRL_EXTENDED_XLAT 0x0002
1297 #define BIOS_CTRL_GT_2_DISK 0x0004
1298 #define BIOS_CTRL_BIOS_REMOVABLE 0x0008
1299 #define BIOS_CTRL_BOOTABLE_CD 0x0010
1300 #define BIOS_CTRL_MULTIPLE_LUN 0x0040
1301 #define BIOS_CTRL_DISPLAY_MSG 0x0080
1302 #define BIOS_CTRL_NO_SCAM 0x0100
1303 #define BIOS_CTRL_RESET_SCSI_BUS 0x0200
1304 #define BIOS_CTRL_INIT_VERBOSE 0x0800
1305 #define BIOS_CTRL_SCSI_PARITY 0x1000
1306 #define BIOS_CTRL_AIPP_DIS 0x2000
1308 #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
1310 #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1313 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
1314 * a special 16K Adv Library and Microcode version. After the issue is
1315 * resolved, should restore 32K support.
1317 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
1319 #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1322 * Byte I/O register address from base of 'iop_base'.
1324 #define IOPB_INTR_STATUS_REG 0x00
1325 #define IOPB_CHIP_ID_1 0x01
1326 #define IOPB_INTR_ENABLES 0x02
1327 #define IOPB_CHIP_TYPE_REV 0x03
1328 #define IOPB_RES_ADDR_4 0x04
1329 #define IOPB_RES_ADDR_5 0x05
1330 #define IOPB_RAM_DATA 0x06
1331 #define IOPB_RES_ADDR_7 0x07
1332 #define IOPB_FLAG_REG 0x08
1333 #define IOPB_RES_ADDR_9 0x09
1334 #define IOPB_RISC_CSR 0x0A
1335 #define IOPB_RES_ADDR_B 0x0B
1336 #define IOPB_RES_ADDR_C 0x0C
1337 #define IOPB_RES_ADDR_D 0x0D
1338 #define IOPB_SOFT_OVER_WR 0x0E
1339 #define IOPB_RES_ADDR_F 0x0F
1340 #define IOPB_MEM_CFG 0x10
1341 #define IOPB_RES_ADDR_11 0x11
1342 #define IOPB_GPIO_DATA 0x12
1343 #define IOPB_RES_ADDR_13 0x13
1344 #define IOPB_FLASH_PAGE 0x14
1345 #define IOPB_RES_ADDR_15 0x15
1346 #define IOPB_GPIO_CNTL 0x16
1347 #define IOPB_RES_ADDR_17 0x17
1348 #define IOPB_FLASH_DATA 0x18
1349 #define IOPB_RES_ADDR_19 0x19
1350 #define IOPB_RES_ADDR_1A 0x1A
1351 #define IOPB_RES_ADDR_1B 0x1B
1352 #define IOPB_RES_ADDR_1C 0x1C
1353 #define IOPB_RES_ADDR_1D 0x1D
1354 #define IOPB_RES_ADDR_1E 0x1E
1355 #define IOPB_RES_ADDR_1F 0x1F
1356 #define IOPB_DMA_CFG0 0x20
1357 #define IOPB_DMA_CFG1 0x21
1358 #define IOPB_TICKLE 0x22
1359 #define IOPB_DMA_REG_WR 0x23
1360 #define IOPB_SDMA_STATUS 0x24
1361 #define IOPB_SCSI_BYTE_CNT 0x25
1362 #define IOPB_HOST_BYTE_CNT 0x26
1363 #define IOPB_BYTE_LEFT_TO_XFER 0x27
1364 #define IOPB_BYTE_TO_XFER_0 0x28
1365 #define IOPB_BYTE_TO_XFER_1 0x29
1366 #define IOPB_BYTE_TO_XFER_2 0x2A
1367 #define IOPB_BYTE_TO_XFER_3 0x2B
1368 #define IOPB_ACC_GRP 0x2C
1369 #define IOPB_RES_ADDR_2D 0x2D
1370 #define IOPB_DEV_ID 0x2E
1371 #define IOPB_RES_ADDR_2F 0x2F
1372 #define IOPB_SCSI_DATA 0x30
1373 #define IOPB_RES_ADDR_31 0x31
1374 #define IOPB_RES_ADDR_32 0x32
1375 #define IOPB_SCSI_DATA_HSHK 0x33
1376 #define IOPB_SCSI_CTRL 0x34
1377 #define IOPB_RES_ADDR_35 0x35
1378 #define IOPB_RES_ADDR_36 0x36
1379 #define IOPB_RES_ADDR_37 0x37
1380 #define IOPB_RAM_BIST 0x38
1381 #define IOPB_PLL_TEST 0x39
1382 #define IOPB_PCI_INT_CFG 0x3A
1383 #define IOPB_RES_ADDR_3B 0x3B
1384 #define IOPB_RFIFO_CNT 0x3C
1385 #define IOPB_RES_ADDR_3D 0x3D
1386 #define IOPB_RES_ADDR_3E 0x3E
1387 #define IOPB_RES_ADDR_3F 0x3F
1390 * Word I/O register address from base of 'iop_base'.
1392 #define IOPW_CHIP_ID_0 0x00 /* CID0 */
1393 #define IOPW_CTRL_REG 0x02 /* CC */
1394 #define IOPW_RAM_ADDR 0x04 /* LA */
1395 #define IOPW_RAM_DATA 0x06 /* LD */
1396 #define IOPW_RES_ADDR_08 0x08
1397 #define IOPW_RISC_CSR 0x0A /* CSR */
1398 #define IOPW_SCSI_CFG0 0x0C /* CFG0 */
1399 #define IOPW_SCSI_CFG1 0x0E /* CFG1 */
1400 #define IOPW_RES_ADDR_10 0x10
1401 #define IOPW_SEL_MASK 0x12 /* SM */
1402 #define IOPW_RES_ADDR_14 0x14
1403 #define IOPW_FLASH_ADDR 0x16 /* FA */
1404 #define IOPW_RES_ADDR_18 0x18
1405 #define IOPW_EE_CMD 0x1A /* EC */
1406 #define IOPW_EE_DATA 0x1C /* ED */
1407 #define IOPW_SFIFO_CNT 0x1E /* SFC */
1408 #define IOPW_RES_ADDR_20 0x20
1409 #define IOPW_Q_BASE 0x22 /* QB */
1410 #define IOPW_QP 0x24 /* QP */
1411 #define IOPW_IX 0x26 /* IX */
1412 #define IOPW_SP 0x28 /* SP */
1413 #define IOPW_PC 0x2A /* PC */
1414 #define IOPW_RES_ADDR_2C 0x2C
1415 #define IOPW_RES_ADDR_2E 0x2E
1416 #define IOPW_SCSI_DATA 0x30 /* SD */
1417 #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
1418 #define IOPW_SCSI_CTRL 0x34 /* SC */
1419 #define IOPW_HSHK_CFG 0x36 /* HCFG */
1420 #define IOPW_SXFR_STATUS 0x36 /* SXS */
1421 #define IOPW_SXFR_CNTL 0x38 /* SXL */
1422 #define IOPW_SXFR_CNTH 0x3A /* SXH */
1423 #define IOPW_RES_ADDR_3C 0x3C
1424 #define IOPW_RFIFO_DATA 0x3E /* RFD */
1427 * Doubleword I/O register address from base of 'iop_base'.
1429 #define IOPDW_RES_ADDR_0 0x00
1430 #define IOPDW_RAM_DATA 0x04
1431 #define IOPDW_RES_ADDR_8 0x08
1432 #define IOPDW_RES_ADDR_C 0x0C
1433 #define IOPDW_RES_ADDR_10 0x10
1434 #define IOPDW_COMMA 0x14
1435 #define IOPDW_COMMB 0x18
1436 #define IOPDW_RES_ADDR_1C 0x1C
1437 #define IOPDW_SDMA_ADDR0 0x20
1438 #define IOPDW_SDMA_ADDR1 0x24
1439 #define IOPDW_SDMA_COUNT 0x28
1440 #define IOPDW_SDMA_ERROR 0x2C
1441 #define IOPDW_RDMA_ADDR0 0x30
1442 #define IOPDW_RDMA_ADDR1 0x34
1443 #define IOPDW_RDMA_COUNT 0x38
1444 #define IOPDW_RDMA_ERROR 0x3C
1446 #define ADV_CHIP_ID_BYTE 0x25
1447 #define ADV_CHIP_ID_WORD 0x04C1
1449 #define ADV_INTR_ENABLE_HOST_INTR 0x01
1450 #define ADV_INTR_ENABLE_SEL_INTR 0x02
1451 #define ADV_INTR_ENABLE_DPR_INTR 0x04
1452 #define ADV_INTR_ENABLE_RTA_INTR 0x08
1453 #define ADV_INTR_ENABLE_RMA_INTR 0x10
1454 #define ADV_INTR_ENABLE_RST_INTR 0x20
1455 #define ADV_INTR_ENABLE_DPE_INTR 0x40
1456 #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
1458 #define ADV_INTR_STATUS_INTRA 0x01
1459 #define ADV_INTR_STATUS_INTRB 0x02
1460 #define ADV_INTR_STATUS_INTRC 0x04
1462 #define ADV_RISC_CSR_STOP (0x0000)
1463 #define ADV_RISC_TEST_COND (0x2000)
1464 #define ADV_RISC_CSR_RUN (0x4000)
1465 #define ADV_RISC_CSR_SINGLE_STEP (0x8000)
1467 #define ADV_CTRL_REG_HOST_INTR 0x0100
1468 #define ADV_CTRL_REG_SEL_INTR 0x0200
1469 #define ADV_CTRL_REG_DPR_INTR 0x0400
1470 #define ADV_CTRL_REG_RTA_INTR 0x0800
1471 #define ADV_CTRL_REG_RMA_INTR 0x1000
1472 #define ADV_CTRL_REG_RES_BIT14 0x2000
1473 #define ADV_CTRL_REG_DPE_INTR 0x4000
1474 #define ADV_CTRL_REG_POWER_DONE 0x8000
1475 #define ADV_CTRL_REG_ANY_INTR 0xFF00
1477 #define ADV_CTRL_REG_CMD_RESET 0x00C6
1478 #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
1479 #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
1480 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
1481 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
1483 #define ADV_TICKLE_NOP 0x00
1484 #define ADV_TICKLE_A 0x01
1485 #define ADV_TICKLE_B 0x02
1486 #define ADV_TICKLE_C 0x03
1488 #define AdvIsIntPending(port) \
1489 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
1492 * SCSI_CFG0 Register bit definitions
1494 #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
1495 #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
1496 #define EVEN_PARITY 0x1000 /* Select Even Parity */
1497 #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
1498 #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
1499 #define PRIM_MODE 0x0100 /* Primitive SCSI mode */
1500 #define SCAM_EN 0x0080 /* Enable SCAM selection */
1501 #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
1502 #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
1503 #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
1504 #define OUR_ID 0x000F /* SCSI ID */
1507 * SCSI_CFG1 Register bit definitions
1509 #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
1510 #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
1511 #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
1512 #define FILTER_SEL 0x0C00 /* Filter Period Selection */
1513 #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
1514 #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
1515 #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
1516 #define ACTIVE_DBL 0x0200 /* Disable Active Negation */
1517 #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
1518 #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
1519 #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
1520 #define TERM_CTL 0x0030 /* External SCSI Termination Bits */
1521 #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
1522 #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
1523 #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
1526 * Addendum for ASC-38C0800 Chip
1528 * The ASC-38C1600 Chip uses the same definitions except that the
1529 * bus mode override bits [12:10] have been moved to byte register
1530 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
1531 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
1532 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
1533 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
1534 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
1536 #define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
1537 #define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
1538 #define HVD 0x1000 /* HVD Device Detect */
1539 #define LVD 0x0800 /* LVD Device Detect */
1540 #define SE 0x0400 /* SE Device Detect */
1541 #define TERM_LVD 0x00C0 /* LVD Termination Bits */
1542 #define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
1543 #define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
1544 #define TERM_SE 0x0030 /* SE Termination Bits */
1545 #define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
1546 #define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
1547 #define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
1548 #define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
1549 #define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
1550 #define C_DET_SE 0x0003 /* SE Cable Detect Bits */
1551 #define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
1552 #define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
1554 #define CABLE_ILLEGAL_A 0x7
1555 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
1557 #define CABLE_ILLEGAL_B 0xB
1558 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
1561 * MEM_CFG Register bit definitions
1563 #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
1564 #define FAST_EE_CLK 0x20 /* Diagnostic Bit */
1565 #define RAM_SZ 0x1C /* Specify size of RAM to RISC */
1566 #define RAM_SZ_2KB 0x00 /* 2 KB */
1567 #define RAM_SZ_4KB 0x04 /* 4 KB */
1568 #define RAM_SZ_8KB 0x08 /* 8 KB */
1569 #define RAM_SZ_16KB 0x0C /* 16 KB */
1570 #define RAM_SZ_32KB 0x10 /* 32 KB */
1571 #define RAM_SZ_64KB 0x14 /* 64 KB */
1574 * DMA_CFG0 Register bit definitions
1576 * This register is only accessible to the host.
1578 #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
1579 #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
1580 #define FIFO_THRESH_16B 0x00 /* 16 bytes */
1581 #define FIFO_THRESH_32B 0x20 /* 32 bytes */
1582 #define FIFO_THRESH_48B 0x30 /* 48 bytes */
1583 #define FIFO_THRESH_64B 0x40 /* 64 bytes */
1584 #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
1585 #define FIFO_THRESH_96B 0x60 /* 96 bytes */
1586 #define FIFO_THRESH_112B 0x70 /* 112 bytes */
1587 #define START_CTL 0x0C /* DMA start conditions */
1588 #define START_CTL_TH 0x00 /* Wait threshold level (default) */
1589 #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
1590 #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
1591 #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
1592 #define READ_CMD 0x03 /* Memory Read Method */
1593 #define READ_CMD_MR 0x00 /* Memory Read */
1594 #define READ_CMD_MRL 0x02 /* Memory Read Long */
1595 #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
1598 * ASC-38C0800 RAM BIST Register bit definitions
1600 #define RAM_TEST_MODE 0x80
1601 #define PRE_TEST_MODE 0x40
1602 #define NORMAL_MODE 0x00
1603 #define RAM_TEST_DONE 0x10
1604 #define RAM_TEST_STATUS 0x0F
1605 #define RAM_TEST_HOST_ERROR 0x08
1606 #define RAM_TEST_INTRAM_ERROR 0x04
1607 #define RAM_TEST_RISC_ERROR 0x02
1608 #define RAM_TEST_SCSI_ERROR 0x01
1609 #define RAM_TEST_SUCCESS 0x00
1610 #define PRE_TEST_VALUE 0x05
1611 #define NORMAL_VALUE 0x00
1614 * ASC38C1600 Definitions
1616 * IOPB_PCI_INT_CFG Bit Field Definitions
1619 #define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
1622 * Bit 1 can be set to change the interrupt for the Function to operate in
1623 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
1624 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
1625 * mode, otherwise the operating mode is undefined.
1627 #define TOTEMPOLE 0x02
1630 * Bit 0 can be used to change the Int Pin for the Function. The value is
1631 * 0 by default for both Functions with Function 0 using INT A and Function
1632 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
1633 * INT A is used.
1635 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
1636 * value specified in the PCI Configuration Space.
1638 #define INTAB 0x01
1641 * Adv Library Status Definitions
1643 #define ADV_TRUE 1
1644 #define ADV_FALSE 0
1645 #define ADV_SUCCESS 1
1646 #define ADV_BUSY 0
1647 #define ADV_ERROR (-1)
1650 * ADV_DVC_VAR 'warn_code' values
1652 #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
1653 #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
1654 #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
1655 #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
1657 #define ADV_MAX_TID 15 /* max. target identifier */
1658 #define ADV_MAX_LUN 7 /* max. logical unit number */
1661 * Fixed locations of microcode operating variables.
1663 #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
1664 #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
1665 #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
1666 #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
1667 #define ASC_MC_VERSION_NUM 0x003A /* microcode number */
1668 #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
1669 #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
1670 #define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
1671 #define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
1672 #define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
1673 #define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
1674 #define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
1675 #define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
1676 #define ASC_MC_CHIP_TYPE 0x009A
1677 #define ASC_MC_INTRB_CODE 0x009B
1678 #define ASC_MC_WDTR_ABLE 0x009C
1679 #define ASC_MC_SDTR_ABLE 0x009E
1680 #define ASC_MC_TAGQNG_ABLE 0x00A0
1681 #define ASC_MC_DISC_ENABLE 0x00A2
1682 #define ASC_MC_IDLE_CMD_STATUS 0x00A4
1683 #define ASC_MC_IDLE_CMD 0x00A6
1684 #define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
1685 #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
1686 #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
1687 #define ASC_MC_DEFAULT_MEM_CFG 0x00B0
1688 #define ASC_MC_DEFAULT_SEL_MASK 0x00B2
1689 #define ASC_MC_SDTR_DONE 0x00B6
1690 #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
1691 #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
1692 #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
1693 #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
1694 #define ASC_MC_WDTR_DONE 0x0124
1695 #define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
1696 #define ASC_MC_ICQ 0x0160
1697 #define ASC_MC_IRQ 0x0164
1698 #define ASC_MC_PPR_ABLE 0x017A
1701 * BIOS LRAM variable absolute offsets.
1703 #define BIOS_CODESEG 0x54
1704 #define BIOS_CODELEN 0x56
1705 #define BIOS_SIGNATURE 0x58
1706 #define BIOS_VERSION 0x5A
1709 * Microcode Control Flags
1711 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
1712 * and handled by the microcode.
1714 #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
1715 #define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
1718 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
1720 #define HSHK_CFG_WIDE_XFR 0x8000
1721 #define HSHK_CFG_RATE 0x0F00
1722 #define HSHK_CFG_OFFSET 0x001F
1724 #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
1725 #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
1726 #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
1727 #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
1729 #define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
1730 #define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
1731 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
1732 #define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
1733 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
1735 #define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
1736 #define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
1737 #define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
1738 #define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
1739 #define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
1741 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
1742 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
1744 #define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
1745 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
1748 * All fields here are accessed by the board microcode and need to be
1749 * little-endian.
1751 typedef struct adv_carr_t {
1752 ADV_VADDR carr_va; /* Carrier Virtual Address */
1753 ADV_PADDR carr_pa; /* Carrier Physical Address */
1754 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
1756 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
1758 * next_vpa [3:1] Reserved Bits
1759 * next_vpa [0] Done Flag set in Response Queue.
1761 ADV_VADDR next_vpa;
1762 } ADV_CARR_T;
1765 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
1767 #define ASC_NEXT_VPA_MASK 0xFFFFFFF0
1769 #define ASC_RQ_DONE 0x00000001
1770 #define ASC_RQ_GOOD 0x00000002
1771 #define ASC_CQ_STOPPER 0x00000000
1773 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
1775 #define ADV_CARRIER_NUM_PAGE_CROSSING \
1776 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + (PAGE_SIZE - 1))/PAGE_SIZE)
1778 #define ADV_CARRIER_BUFSIZE \
1779 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
1782 * ASC_SCSI_REQ_Q 'a_flag' definitions
1784 * The Adv Library should limit use to the lower nibble (4 bits) of
1785 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
1787 #define ADV_POLL_REQUEST 0x01 /* poll for request completion */
1788 #define ADV_SCSIQ_DONE 0x02 /* request done */
1789 #define ADV_DONT_RETRY 0x08 /* don't do retry */
1791 #define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
1792 #define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
1793 #define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
1796 * Adapter temporary configuration structure
1798 * This structure can be discarded after initialization. Don't add
1799 * fields here needed after initialization.
1801 * Field naming convention:
1803 * *_enable indicates the field enables or disables a feature. The
1804 * value of the field is never reset.
1806 typedef struct adv_dvc_cfg {
1807 ushort disc_enable; /* enable disconnection */
1808 uchar chip_version; /* chip version */
1809 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
1810 ushort control_flag; /* Microcode Control Flag */
1811 ushort mcode_date; /* Microcode date */
1812 ushort mcode_version; /* Microcode version */
1813 ushort serial1; /* EEPROM serial number word 1 */
1814 ushort serial2; /* EEPROM serial number word 2 */
1815 ushort serial3; /* EEPROM serial number word 3 */
1816 } ADV_DVC_CFG;
1818 struct adv_dvc_var;
1819 struct adv_scsi_req_q;
1821 typedef struct asc_sg_block {
1822 uchar reserved1;
1823 uchar reserved2;
1824 uchar reserved3;
1825 uchar sg_cnt; /* Valid entries in block. */
1826 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
1827 struct {
1828 ADV_PADDR sg_addr; /* SG element address. */
1829 ADV_DCNT sg_count; /* SG element count. */
1830 } sg_list[NO_OF_SG_PER_BLOCK];
1831 } ADV_SG_BLOCK;
1834 * ADV_SCSI_REQ_Q - microcode request structure
1836 * All fields in this structure up to byte 60 are used by the microcode.
1837 * The microcode makes assumptions about the size and ordering of fields
1838 * in this structure. Do not change the structure definition here without
1839 * coordinating the change with the microcode.
1841 * All fields accessed by microcode must be maintained in little_endian
1842 * order.
1844 typedef struct adv_scsi_req_q {
1845 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
1846 uchar target_cmd;
1847 uchar target_id; /* Device target identifier. */
1848 uchar target_lun; /* Device target logical unit number. */
1849 ADV_PADDR data_addr; /* Data buffer physical address. */
1850 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
1851 ADV_PADDR sense_addr;
1852 ADV_PADDR carr_pa;
1853 uchar mflag;
1854 uchar sense_len;
1855 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
1856 uchar scsi_cntl;
1857 uchar done_status; /* Completion status. */
1858 uchar scsi_status; /* SCSI status byte. */
1859 uchar host_status; /* Ucode host status. */
1860 uchar sg_working_ix;
1861 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
1862 ADV_PADDR sg_real_addr; /* SG list physical address. */
1863 ADV_PADDR scsiq_rptr;
1864 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
1865 ADV_VADDR scsiq_ptr;
1866 ADV_VADDR carr_va;
1868 * End of microcode structure - 60 bytes. The rest of the structure
1869 * is used by the Adv Library and ignored by the microcode.
1871 ADV_VADDR srb_ptr;
1872 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
1873 char *vdata_addr; /* Data buffer virtual address. */
1874 uchar a_flag;
1875 uchar pad[2]; /* Pad out to a word boundary. */
1876 } ADV_SCSI_REQ_Q;
1879 * The following two structures are used to process Wide Board requests.
1881 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
1882 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
1883 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
1884 * Mid-Level SCSI request structure.
1886 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
1887 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
1888 * up to 255 scatter-gather elements may be used per request or
1889 * ADV_SCSI_REQ_Q.
1891 * Both structures must be 32 byte aligned.
1893 typedef struct adv_sgblk {
1894 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
1895 uchar align[32]; /* Sgblock structure padding. */
1896 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
1897 } adv_sgblk_t;
1899 typedef struct adv_req {
1900 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
1901 uchar align[32]; /* Request structure padding. */
1902 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
1903 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
1904 struct adv_req *next_reqp; /* Next Request Structure. */
1905 } adv_req_t;
1908 * Adapter operation variable structure.
1910 * One structure is required per host adapter.
1912 * Field naming convention:
1914 * *_able indicates both whether a feature should be enabled or disabled
1915 * and whether a device isi capable of the feature. At initialization
1916 * this field may be set, but later if a device is found to be incapable
1917 * of the feature, the field is cleared.
1919 typedef struct adv_dvc_var {
1920 AdvPortAddr iop_base; /* I/O port address */
1921 ushort err_code; /* fatal error code */
1922 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
1923 ushort wdtr_able; /* try WDTR for a device */
1924 ushort sdtr_able; /* try SDTR for a device */
1925 ushort ultra_able; /* try SDTR Ultra speed for a device */
1926 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
1927 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
1928 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
1929 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
1930 ushort tagqng_able; /* try tagged queuing with a device */
1931 ushort ppr_able; /* PPR message capable per TID bitmask. */
1932 uchar max_dvc_qng; /* maximum number of tagged commands per device */
1933 ushort start_motor; /* start motor command allowed */
1934 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
1935 uchar chip_no; /* should be assigned by caller */
1936 uchar max_host_qng; /* maximum number of Q'ed command allowed */
1937 ushort no_scam; /* scam_tolerant of EEPROM */
1938 struct asc_board *drv_ptr; /* driver pointer to private structure */
1939 uchar chip_scsi_id; /* chip SCSI target ID */
1940 uchar chip_type;
1941 uchar bist_err_code;
1942 ADV_CARR_T *carrier_buf;
1943 ADV_CARR_T *carr_freelist; /* Carrier free list. */
1944 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
1945 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
1946 ushort carr_pending_cnt; /* Count of pending carriers. */
1947 struct adv_req *orig_reqp; /* adv_req_t memory block. */
1949 * Note: The following fields will not be used after initialization. The
1950 * driver may discard the buffer after initialization is done.
1952 ADV_DVC_CFG *cfg; /* temporary configuration structure */
1953 } ADV_DVC_VAR;
1956 * Microcode idle loop commands
1958 #define IDLE_CMD_COMPLETED 0
1959 #define IDLE_CMD_STOP_CHIP 0x0001
1960 #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
1961 #define IDLE_CMD_SEND_INT 0x0004
1962 #define IDLE_CMD_ABORT 0x0008
1963 #define IDLE_CMD_DEVICE_RESET 0x0010
1964 #define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
1965 #define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
1966 #define IDLE_CMD_SCSIREQ 0x0080
1968 #define IDLE_CMD_STATUS_SUCCESS 0x0001
1969 #define IDLE_CMD_STATUS_FAILURE 0x0002
1972 * AdvSendIdleCmd() flag definitions.
1974 #define ADV_NOWAIT 0x01
1977 * Wait loop time out values.
1979 #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
1980 #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
1981 #define SCSI_MAX_RETRY 10 /* retry count */
1983 #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
1984 #define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
1985 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
1986 #define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
1988 #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
1990 /* Read byte from a register. */
1991 #define AdvReadByteRegister(iop_base, reg_off) \
1992 (ADV_MEM_READB((iop_base) + (reg_off)))
1994 /* Write byte to a register. */
1995 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
1996 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
1998 /* Read word (2 bytes) from a register. */
1999 #define AdvReadWordRegister(iop_base, reg_off) \
2000 (ADV_MEM_READW((iop_base) + (reg_off)))
2002 /* Write word (2 bytes) to a register. */
2003 #define AdvWriteWordRegister(iop_base, reg_off, word) \
2004 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
2006 /* Write dword (4 bytes) to a register. */
2007 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
2008 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
2010 /* Read byte from LRAM. */
2011 #define AdvReadByteLram(iop_base, addr, byte) \
2012 do { \
2013 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2014 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
2015 } while (0)
2017 /* Write byte to LRAM. */
2018 #define AdvWriteByteLram(iop_base, addr, byte) \
2019 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2020 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
2022 /* Read word (2 bytes) from LRAM. */
2023 #define AdvReadWordLram(iop_base, addr, word) \
2024 do { \
2025 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2026 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
2027 } while (0)
2029 /* Write word (2 bytes) to LRAM. */
2030 #define AdvWriteWordLram(iop_base, addr, word) \
2031 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2032 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2034 /* Write little-endian double word (4 bytes) to LRAM */
2035 /* Because of unspecified C language ordering don't use auto-increment. */
2036 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
2037 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2038 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2039 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
2040 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
2041 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2042 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
2044 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
2045 #define AdvReadWordAutoIncLram(iop_base) \
2046 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
2048 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
2049 #define AdvWriteWordAutoIncLram(iop_base, word) \
2050 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2053 * Define macro to check for Condor signature.
2055 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
2056 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
2058 #define AdvFindSignature(iop_base) \
2059 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
2060 ADV_CHIP_ID_BYTE) && \
2061 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
2062 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
2065 * Define macro to Return the version number of the chip at 'iop_base'.
2067 * The second parameter 'bus_type' is currently unused.
2069 #define AdvGetChipVersion(iop_base, bus_type) \
2070 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
2073 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
2074 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
2076 * If the request has not yet been sent to the device it will simply be
2077 * aborted from RISC memory. If the request is disconnected it will be
2078 * aborted on reselection by sending an Abort Message to the target ID.
2080 * Return value:
2081 * ADV_TRUE(1) - Queue was successfully aborted.
2082 * ADV_FALSE(0) - Queue was not found on the active queue list.
2084 #define AdvAbortQueue(asc_dvc, scsiq) \
2085 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
2086 (ADV_DCNT) (scsiq))
2089 * Send a Bus Device Reset Message to the specified target ID.
2091 * All outstanding commands will be purged if sending the
2092 * Bus Device Reset Message is successful.
2094 * Return Value:
2095 * ADV_TRUE(1) - All requests on the target are purged.
2096 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
2097 * are not purged.
2099 #define AdvResetDevice(asc_dvc, target_id) \
2100 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
2101 (ADV_DCNT) (target_id))
2104 * SCSI Wide Type definition.
2106 #define ADV_SCSI_BIT_ID_TYPE ushort
2109 * AdvInitScsiTarget() 'cntl_flag' options.
2111 #define ADV_SCAN_LUN 0x01
2112 #define ADV_CAPINFO_NOLUN 0x02
2115 * Convert target id to target id bit mask.
2117 #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
2120 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
2123 #define QD_NO_STATUS 0x00 /* Request not completed yet. */
2124 #define QD_NO_ERROR 0x01
2125 #define QD_ABORTED_BY_HOST 0x02
2126 #define QD_WITH_ERROR 0x04
2128 #define QHSTA_NO_ERROR 0x00
2129 #define QHSTA_M_SEL_TIMEOUT 0x11
2130 #define QHSTA_M_DATA_OVER_RUN 0x12
2131 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
2132 #define QHSTA_M_QUEUE_ABORTED 0x15
2133 #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
2134 #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
2135 #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
2136 #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
2137 #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
2138 #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
2139 #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
2140 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
2141 #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
2142 #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
2143 #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
2144 #define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
2145 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
2146 #define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
2147 #define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
2148 #define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
2149 #define QHSTA_M_WTM_TIMEOUT 0x41
2150 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
2151 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
2152 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
2153 #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
2154 #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
2155 #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
2157 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
2158 #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
2159 #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
2160 #define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
2163 * Total contiguous memory needed for driver SG blocks.
2165 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
2166 * number of scatter-gather elements the driver supports in a
2167 * single request.
2170 #define ADV_SG_LIST_MAX_BYTE_SIZE \
2171 (sizeof(ADV_SG_BLOCK) * \
2172 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
2174 /* struct asc_board flags */
2175 #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
2177 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
2179 #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
2181 #define ASC_INFO_SIZE 128 /* advansys_info() line size */
2183 #ifdef CONFIG_PROC_FS
2184 /* /proc/scsi/advansys/[0...] related definitions */
2185 #define ASC_PRTBUF_SIZE 2048
2186 #define ASC_PRTLINE_SIZE 160
2188 #define ASC_PRT_NEXT() \
2189 if (cp) { \
2190 totlen += len; \
2191 leftlen -= len; \
2192 if (leftlen == 0) { \
2193 return totlen; \
2195 cp += len; \
2197 #endif /* CONFIG_PROC_FS */
2199 /* Asc Library return codes */
2200 #define ASC_TRUE 1
2201 #define ASC_FALSE 0
2202 #define ASC_NOERROR 1
2203 #define ASC_BUSY 0
2204 #define ASC_ERROR (-1)
2206 /* struct scsi_cmnd function return codes */
2207 #define STATUS_BYTE(byte) (byte)
2208 #define MSG_BYTE(byte) ((byte) << 8)
2209 #define HOST_BYTE(byte) ((byte) << 16)
2210 #define DRIVER_BYTE(byte) ((byte) << 24)
2212 #define ASC_STATS(shost, counter) ASC_STATS_ADD(shost, counter, 1)
2213 #ifndef ADVANSYS_STATS
2214 #define ASC_STATS_ADD(shost, counter, count)
2215 #else /* ADVANSYS_STATS */
2216 #define ASC_STATS_ADD(shost, counter, count) \
2217 (((struct asc_board *) shost_priv(shost))->asc_stats.counter += (count))
2218 #endif /* ADVANSYS_STATS */
2220 /* If the result wraps when calculating tenths, return 0. */
2221 #define ASC_TENTHS(num, den) \
2222 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
2223 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
2226 * Display a message to the console.
2228 #define ASC_PRINT(s) \
2230 printk("advansys: "); \
2231 printk(s); \
2234 #define ASC_PRINT1(s, a1) \
2236 printk("advansys: "); \
2237 printk((s), (a1)); \
2240 #define ASC_PRINT2(s, a1, a2) \
2242 printk("advansys: "); \
2243 printk((s), (a1), (a2)); \
2246 #define ASC_PRINT3(s, a1, a2, a3) \
2248 printk("advansys: "); \
2249 printk((s), (a1), (a2), (a3)); \
2252 #define ASC_PRINT4(s, a1, a2, a3, a4) \
2254 printk("advansys: "); \
2255 printk((s), (a1), (a2), (a3), (a4)); \
2258 #ifndef ADVANSYS_DEBUG
2260 #define ASC_DBG(lvl, s...)
2261 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2262 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
2263 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2264 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
2265 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2266 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
2267 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
2268 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
2269 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2271 #else /* ADVANSYS_DEBUG */
2274 * Debugging Message Levels:
2275 * 0: Errors Only
2276 * 1: High-Level Tracing
2277 * 2-N: Verbose Tracing
2280 #define ASC_DBG(lvl, format, arg...) { \
2281 if (asc_dbglvl >= (lvl)) \
2282 printk(KERN_DEBUG "%s: %s: " format, DRV_NAME, \
2283 __func__ , ## arg); \
2286 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2288 if (asc_dbglvl >= (lvl)) { \
2289 asc_prt_scsi_host(s); \
2293 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
2295 if (asc_dbglvl >= (lvl)) { \
2296 asc_prt_asc_scsi_q(scsiqp); \
2300 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
2302 if (asc_dbglvl >= (lvl)) { \
2303 asc_prt_asc_qdone_info(qdone); \
2307 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
2309 if (asc_dbglvl >= (lvl)) { \
2310 asc_prt_adv_scsi_req_q(scsiqp); \
2314 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2316 if (asc_dbglvl >= (lvl)) { \
2317 asc_prt_hex((name), (start), (length)); \
2321 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2322 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2324 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2325 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2327 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2328 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2329 #endif /* ADVANSYS_DEBUG */
2331 #ifdef ADVANSYS_STATS
2333 /* Per board statistics structure */
2334 struct asc_stats {
2335 /* Driver Entrypoint Statistics */
2336 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
2337 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
2338 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
2339 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
2340 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
2341 ADV_DCNT done; /* # calls to request's scsi_done function */
2342 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
2343 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
2344 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
2345 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
2346 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
2347 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
2348 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
2349 ADV_DCNT exe_unknown; /* # unknown returns. */
2350 /* Data Transfer Statistics */
2351 ADV_DCNT xfer_cnt; /* # I/O requests received */
2352 ADV_DCNT xfer_elem; /* # scatter-gather elements */
2353 ADV_DCNT xfer_sect; /* # 512-byte blocks */
2355 #endif /* ADVANSYS_STATS */
2358 * Structure allocated for each board.
2360 * This structure is allocated by scsi_host_alloc() at the end
2361 * of the 'Scsi_Host' structure starting at the 'hostdata'
2362 * field. It is guaranteed to be allocated from DMA-able memory.
2364 struct asc_board {
2365 struct device *dev;
2366 uint flags; /* Board flags */
2367 unsigned int irq;
2368 union {
2369 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
2370 ADV_DVC_VAR adv_dvc_var; /* Wide board */
2371 } dvc_var;
2372 union {
2373 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
2374 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
2375 } dvc_cfg;
2376 ushort asc_n_io_port; /* Number I/O ports. */
2377 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
2378 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
2379 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
2380 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
2381 union {
2382 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
2383 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
2384 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
2385 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
2386 } eep_config;
2387 ulong last_reset; /* Saved last reset time */
2388 /* /proc/scsi/advansys/[0...] */
2389 char *prtbuf; /* /proc print buffer */
2390 #ifdef ADVANSYS_STATS
2391 struct asc_stats asc_stats; /* Board statistics */
2392 #endif /* ADVANSYS_STATS */
2394 * The following fields are used only for Narrow Boards.
2396 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
2398 * The following fields are used only for Wide Boards.
2400 void __iomem *ioremap_addr; /* I/O Memory remap address. */
2401 ushort ioport; /* I/O Port address. */
2402 adv_req_t *adv_reqp; /* Request structures. */
2403 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
2404 ushort bios_signature; /* BIOS Signature. */
2405 ushort bios_version; /* BIOS Version. */
2406 ushort bios_codeseg; /* BIOS Code Segment. */
2407 ushort bios_codelen; /* BIOS Code Segment Length. */
2410 #define asc_dvc_to_board(asc_dvc) container_of(asc_dvc, struct asc_board, \
2411 dvc_var.asc_dvc_var)
2412 #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
2413 dvc_var.adv_dvc_var)
2414 #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
2416 #ifdef ADVANSYS_DEBUG
2417 static int asc_dbglvl = 3;
2420 * asc_prt_asc_dvc_var()
2422 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
2424 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
2426 printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
2427 "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
2429 printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
2430 (unsigned)h->init_sdtr);
2432 printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
2433 "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
2434 (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
2435 (unsigned)h->chip_no);
2437 printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
2438 "%u,\n", (unsigned)h->queue_full_or_busy,
2439 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2441 printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
2442 "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
2443 (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
2444 (unsigned)h->in_critical_cnt);
2446 printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
2447 "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
2448 (unsigned)h->init_state, (unsigned)h->no_scam,
2449 (unsigned)h->pci_fix_asyn_xfer);
2451 printk(" cfg 0x%lx\n", (ulong)h->cfg);
2455 * asc_prt_asc_dvc_cfg()
2457 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
2459 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
2461 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
2462 h->can_tagged_qng, h->cmd_qng_enabled);
2463 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
2464 h->disc_enable, h->sdtr_enable);
2466 printk(" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, "
2467 "chip_version %d,\n", h->chip_scsi_id, h->isa_dma_speed,
2468 h->isa_dma_channel, h->chip_version);
2470 printk(" mcode_date 0x%x, mcode_version %d\n",
2471 h->mcode_date, h->mcode_version);
2475 * asc_prt_adv_dvc_var()
2477 * Display an ADV_DVC_VAR structure.
2479 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
2481 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
2483 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
2484 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
2486 printk(" sdtr_able 0x%x, wdtr_able 0x%x\n",
2487 (unsigned)h->sdtr_able, (unsigned)h->wdtr_able);
2489 printk(" start_motor 0x%x, scsi_reset_wait 0x%x\n",
2490 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2492 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
2493 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
2494 (ulong)h->carr_freelist);
2496 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
2497 (ulong)h->icq_sp, (ulong)h->irq_sp);
2499 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
2500 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
2502 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
2503 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
2507 * asc_prt_adv_dvc_cfg()
2509 * Display an ADV_DVC_CFG structure.
2511 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
2513 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
2515 printk(" disc_enable 0x%x, termination 0x%x\n",
2516 h->disc_enable, h->termination);
2518 printk(" chip_version 0x%x, mcode_date 0x%x\n",
2519 h->chip_version, h->mcode_date);
2521 printk(" mcode_version 0x%x, control_flag 0x%x\n",
2522 h->mcode_version, h->control_flag);
2526 * asc_prt_scsi_host()
2528 static void asc_prt_scsi_host(struct Scsi_Host *s)
2530 struct asc_board *boardp = shost_priv(s);
2532 printk("Scsi_Host at addr 0x%p, device %s\n", s, dev_name(boardp->dev));
2533 printk(" host_busy %u, host_no %d, last_reset %d,\n",
2534 s->host_busy, s->host_no, (unsigned)s->last_reset);
2536 printk(" base 0x%lx, io_port 0x%lx, irq %d,\n",
2537 (ulong)s->base, (ulong)s->io_port, boardp->irq);
2539 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
2540 s->dma_channel, s->this_id, s->can_queue);
2542 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
2543 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
2545 if (ASC_NARROW_BOARD(boardp)) {
2546 asc_prt_asc_dvc_var(&boardp->dvc_var.asc_dvc_var);
2547 asc_prt_asc_dvc_cfg(&boardp->dvc_cfg.asc_dvc_cfg);
2548 } else {
2549 asc_prt_adv_dvc_var(&boardp->dvc_var.adv_dvc_var);
2550 asc_prt_adv_dvc_cfg(&boardp->dvc_cfg.adv_dvc_cfg);
2555 * asc_prt_hex()
2557 * Print hexadecimal output in 4 byte groupings 32 bytes
2558 * or 8 double-words per line.
2560 static void asc_prt_hex(char *f, uchar *s, int l)
2562 int i;
2563 int j;
2564 int k;
2565 int m;
2567 printk("%s: (%d bytes)\n", f, l);
2569 for (i = 0; i < l; i += 32) {
2571 /* Display a maximum of 8 double-words per line. */
2572 if ((k = (l - i) / 4) >= 8) {
2573 k = 8;
2574 m = 0;
2575 } else {
2576 m = (l - i) % 4;
2579 for (j = 0; j < k; j++) {
2580 printk(" %2.2X%2.2X%2.2X%2.2X",
2581 (unsigned)s[i + (j * 4)],
2582 (unsigned)s[i + (j * 4) + 1],
2583 (unsigned)s[i + (j * 4) + 2],
2584 (unsigned)s[i + (j * 4) + 3]);
2587 switch (m) {
2588 case 0:
2589 default:
2590 break;
2591 case 1:
2592 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
2593 break;
2594 case 2:
2595 printk(" %2.2X%2.2X",
2596 (unsigned)s[i + (j * 4)],
2597 (unsigned)s[i + (j * 4) + 1]);
2598 break;
2599 case 3:
2600 printk(" %2.2X%2.2X%2.2X",
2601 (unsigned)s[i + (j * 4) + 1],
2602 (unsigned)s[i + (j * 4) + 2],
2603 (unsigned)s[i + (j * 4) + 3]);
2604 break;
2607 printk("\n");
2612 * asc_prt_asc_scsi_q()
2614 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
2616 ASC_SG_HEAD *sgp;
2617 int i;
2619 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
2621 printk
2622 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
2623 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
2624 q->q2.tag_code);
2626 printk
2627 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2628 (ulong)le32_to_cpu(q->q1.data_addr),
2629 (ulong)le32_to_cpu(q->q1.data_cnt),
2630 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
2632 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
2633 (ulong)q->cdbptr, q->q2.cdb_len,
2634 (ulong)q->sg_head, q->q1.sg_queue_cnt);
2636 if (q->sg_head) {
2637 sgp = q->sg_head;
2638 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
2639 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
2640 sgp->queue_cnt);
2641 for (i = 0; i < sgp->entry_cnt; i++) {
2642 printk(" [%u]: addr 0x%lx, bytes %lu\n",
2643 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
2644 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
2651 * asc_prt_asc_qdone_info()
2653 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
2655 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
2656 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
2657 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
2658 q->d2.tag_code);
2659 printk
2660 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
2661 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
2665 * asc_prt_adv_sgblock()
2667 * Display an ADV_SG_BLOCK structure.
2669 static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
2671 int i;
2673 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
2674 (ulong)b, sgblockno);
2675 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
2676 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
2677 BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK);
2678 if (b->sg_ptr != 0)
2679 BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK);
2680 for (i = 0; i < b->sg_cnt; i++) {
2681 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
2682 i, (ulong)b->sg_list[i].sg_addr,
2683 (ulong)b->sg_list[i].sg_count);
2688 * asc_prt_adv_scsi_req_q()
2690 * Display an ADV_SCSI_REQ_Q structure.
2692 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
2694 int sg_blk_cnt;
2695 struct asc_sg_block *sg_ptr;
2697 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
2699 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
2700 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
2702 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
2703 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
2705 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2706 (ulong)le32_to_cpu(q->data_cnt),
2707 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
2709 printk
2710 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
2711 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
2713 printk(" sg_working_ix 0x%x, target_cmd %u\n",
2714 q->sg_working_ix, q->target_cmd);
2716 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
2717 (ulong)le32_to_cpu(q->scsiq_rptr),
2718 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
2720 /* Display the request's ADV_SG_BLOCK structures. */
2721 if (q->sg_list_ptr != NULL) {
2722 sg_blk_cnt = 0;
2723 while (1) {
2725 * 'sg_ptr' is a physical address. Convert it to a virtual
2726 * address by indexing 'sg_blk_cnt' into the virtual address
2727 * array 'sg_list_ptr'.
2729 * XXX - Assumes all SG physical blocks are virtually contiguous.
2731 sg_ptr =
2732 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
2733 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
2734 if (sg_ptr->sg_ptr == 0) {
2735 break;
2737 sg_blk_cnt++;
2741 #endif /* ADVANSYS_DEBUG */
2744 * The advansys chip/microcode contains a 32-bit identifier for each command
2745 * known as the 'srb'. I don't know what it stands for. The driver used
2746 * to encode the scsi_cmnd pointer by calling virt_to_bus and retrieve it
2747 * with bus_to_virt. Now the driver keeps a per-host map of integers to
2748 * pointers. It auto-expands when full, unless it can't allocate memory.
2749 * Note that an srb of 0 is treated specially by the chip/firmware, hence
2750 * the return of i+1 in this routine, and the corresponding subtraction in
2751 * the inverse routine.
2753 #define BAD_SRB 0
2754 static u32 advansys_ptr_to_srb(struct asc_dvc_var *asc_dvc, void *ptr)
2756 int i;
2757 void **new_ptr;
2759 for (i = 0; i < asc_dvc->ptr_map_count; i++) {
2760 if (!asc_dvc->ptr_map[i])
2761 goto out;
2764 if (asc_dvc->ptr_map_count == 0)
2765 asc_dvc->ptr_map_count = 1;
2766 else
2767 asc_dvc->ptr_map_count *= 2;
2769 new_ptr = krealloc(asc_dvc->ptr_map,
2770 asc_dvc->ptr_map_count * sizeof(void *), GFP_ATOMIC);
2771 if (!new_ptr)
2772 return BAD_SRB;
2773 asc_dvc->ptr_map = new_ptr;
2774 out:
2775 ASC_DBG(3, "Putting ptr %p into array offset %d\n", ptr, i);
2776 asc_dvc->ptr_map[i] = ptr;
2777 return i + 1;
2780 static void * advansys_srb_to_ptr(struct asc_dvc_var *asc_dvc, u32 srb)
2782 void *ptr;
2784 srb--;
2785 if (srb >= asc_dvc->ptr_map_count) {
2786 printk("advansys: bad SRB %u, max %u\n", srb,
2787 asc_dvc->ptr_map_count);
2788 return NULL;
2790 ptr = asc_dvc->ptr_map[srb];
2791 asc_dvc->ptr_map[srb] = NULL;
2792 ASC_DBG(3, "Returning ptr %p from array offset %d\n", ptr, srb);
2793 return ptr;
2797 * advansys_info()
2799 * Return suitable for printing on the console with the argument
2800 * adapter's configuration information.
2802 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
2803 * otherwise the static 'info' array will be overrun.
2805 static const char *advansys_info(struct Scsi_Host *shost)
2807 static char info[ASC_INFO_SIZE];
2808 struct asc_board *boardp = shost_priv(shost);
2809 ASC_DVC_VAR *asc_dvc_varp;
2810 ADV_DVC_VAR *adv_dvc_varp;
2811 char *busname;
2812 char *widename = NULL;
2814 if (ASC_NARROW_BOARD(boardp)) {
2815 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
2816 ASC_DBG(1, "begin\n");
2817 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
2818 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
2819 ASC_IS_ISAPNP) {
2820 busname = "ISA PnP";
2821 } else {
2822 busname = "ISA";
2824 sprintf(info,
2825 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
2826 ASC_VERSION, busname,
2827 (ulong)shost->io_port,
2828 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2829 boardp->irq, shost->dma_channel);
2830 } else {
2831 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
2832 busname = "VL";
2833 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
2834 busname = "EISA";
2835 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
2836 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
2837 == ASC_IS_PCI_ULTRA) {
2838 busname = "PCI Ultra";
2839 } else {
2840 busname = "PCI";
2842 } else {
2843 busname = "?";
2844 shost_printk(KERN_ERR, shost, "unknown bus "
2845 "type %d\n", asc_dvc_varp->bus_type);
2847 sprintf(info,
2848 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
2849 ASC_VERSION, busname, (ulong)shost->io_port,
2850 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2851 boardp->irq);
2853 } else {
2855 * Wide Adapter Information
2857 * Memory-mapped I/O is used instead of I/O space to access
2858 * the adapter, but display the I/O Port range. The Memory
2859 * I/O address is displayed through the driver /proc file.
2861 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
2862 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
2863 widename = "Ultra-Wide";
2864 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
2865 widename = "Ultra2-Wide";
2866 } else {
2867 widename = "Ultra3-Wide";
2869 sprintf(info,
2870 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
2871 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
2872 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, boardp->irq);
2874 BUG_ON(strlen(info) >= ASC_INFO_SIZE);
2875 ASC_DBG(1, "end\n");
2876 return info;
2879 #ifdef CONFIG_PROC_FS
2881 * asc_prt_line()
2883 * If 'cp' is NULL print to the console, otherwise print to a buffer.
2885 * Return 0 if printing to the console, otherwise return the number of
2886 * bytes written to the buffer.
2888 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
2889 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
2891 static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
2893 va_list args;
2894 int ret;
2895 char s[ASC_PRTLINE_SIZE];
2897 va_start(args, fmt);
2898 ret = vsprintf(s, fmt, args);
2899 BUG_ON(ret >= ASC_PRTLINE_SIZE);
2900 if (buf == NULL) {
2901 (void)printk(s);
2902 ret = 0;
2903 } else {
2904 ret = min(buflen, ret);
2905 memcpy(buf, s, ret);
2907 va_end(args);
2908 return ret;
2912 * asc_prt_board_devices()
2914 * Print driver information for devices attached to the board.
2916 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
2917 * cf. asc_prt_line().
2919 * Return the number of characters copied into 'cp'. No more than
2920 * 'cplen' characters will be copied to 'cp'.
2922 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
2924 struct asc_board *boardp = shost_priv(shost);
2925 int leftlen;
2926 int totlen;
2927 int len;
2928 int chip_scsi_id;
2929 int i;
2931 leftlen = cplen;
2932 totlen = len = 0;
2934 len = asc_prt_line(cp, leftlen,
2935 "\nDevice Information for AdvanSys SCSI Host %d:\n",
2936 shost->host_no);
2937 ASC_PRT_NEXT();
2939 if (ASC_NARROW_BOARD(boardp)) {
2940 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
2941 } else {
2942 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
2945 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
2946 ASC_PRT_NEXT();
2947 for (i = 0; i <= ADV_MAX_TID; i++) {
2948 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
2949 len = asc_prt_line(cp, leftlen, " %X,", i);
2950 ASC_PRT_NEXT();
2953 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
2954 ASC_PRT_NEXT();
2956 return totlen;
2960 * Display Wide Board BIOS Information.
2962 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
2964 struct asc_board *boardp = shost_priv(shost);
2965 int leftlen;
2966 int totlen;
2967 int len;
2968 ushort major, minor, letter;
2970 leftlen = cplen;
2971 totlen = len = 0;
2973 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
2974 ASC_PRT_NEXT();
2977 * If the BIOS saved a valid signature, then fill in
2978 * the BIOS code segment base address.
2980 if (boardp->bios_signature != 0x55AA) {
2981 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
2982 ASC_PRT_NEXT();
2983 len = asc_prt_line(cp, leftlen,
2984 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
2985 ASC_PRT_NEXT();
2986 len = asc_prt_line(cp, leftlen,
2987 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
2988 ASC_PRT_NEXT();
2989 } else {
2990 major = (boardp->bios_version >> 12) & 0xF;
2991 minor = (boardp->bios_version >> 8) & 0xF;
2992 letter = (boardp->bios_version & 0xFF);
2994 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
2995 major, minor,
2996 letter >= 26 ? '?' : letter + 'A');
2997 ASC_PRT_NEXT();
3000 * Current available ROM BIOS release is 3.1I for UW
3001 * and 3.2I for U2W. This code doesn't differentiate
3002 * UW and U2W boards.
3004 if (major < 3 || (major <= 3 && minor < 1) ||
3005 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
3006 len = asc_prt_line(cp, leftlen,
3007 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
3008 ASC_PRT_NEXT();
3009 len = asc_prt_line(cp, leftlen,
3010 "ftp://ftp.connectcom.net/pub\n");
3011 ASC_PRT_NEXT();
3015 return totlen;
3019 * Add serial number to information bar if signature AAh
3020 * is found in at bit 15-9 (7 bits) of word 1.
3022 * Serial Number consists fo 12 alpha-numeric digits.
3024 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
3025 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
3026 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
3027 * 5 - Product revision (A-J) Word0: " "
3029 * Signature Word1: 15-9 (7 bits)
3030 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
3031 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
3033 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
3035 * Note 1: Only production cards will have a serial number.
3037 * Note 2: Signature is most significant 7 bits (0xFE).
3039 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
3041 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
3043 ushort w, num;
3045 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
3046 return ASC_FALSE;
3047 } else {
3049 * First word - 6 digits.
3051 w = serialnum[0];
3053 /* Product type - 1st digit. */
3054 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
3055 /* Product type is P=Prototype */
3056 *cp += 0x8;
3058 cp++;
3060 /* Manufacturing location - 2nd digit. */
3061 *cp++ = 'A' + ((w & 0x1C00) >> 10);
3063 /* Product ID - 3rd, 4th digits. */
3064 num = w & 0x3FF;
3065 *cp++ = '0' + (num / 100);
3066 num %= 100;
3067 *cp++ = '0' + (num / 10);
3069 /* Product revision - 5th digit. */
3070 *cp++ = 'A' + (num % 10);
3073 * Second word
3075 w = serialnum[1];
3078 * Year - 6th digit.
3080 * If bit 15 of third word is set, then the
3081 * last digit of the year is greater than 7.
3083 if (serialnum[2] & 0x8000) {
3084 *cp++ = '8' + ((w & 0x1C0) >> 6);
3085 } else {
3086 *cp++ = '0' + ((w & 0x1C0) >> 6);
3089 /* Week of year - 7th, 8th digits. */
3090 num = w & 0x003F;
3091 *cp++ = '0' + num / 10;
3092 num %= 10;
3093 *cp++ = '0' + num;
3096 * Third word
3098 w = serialnum[2] & 0x7FFF;
3100 /* Serial number - 9th digit. */
3101 *cp++ = 'A' + (w / 1000);
3103 /* 10th, 11th, 12th digits. */
3104 num = w % 1000;
3105 *cp++ = '0' + num / 100;
3106 num %= 100;
3107 *cp++ = '0' + num / 10;
3108 num %= 10;
3109 *cp++ = '0' + num;
3111 *cp = '\0'; /* Null Terminate the string. */
3112 return ASC_TRUE;
3117 * asc_prt_asc_board_eeprom()
3119 * Print board EEPROM configuration.
3121 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3122 * cf. asc_prt_line().
3124 * Return the number of characters copied into 'cp'. No more than
3125 * 'cplen' characters will be copied to 'cp'.
3127 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
3129 struct asc_board *boardp = shost_priv(shost);
3130 ASC_DVC_VAR *asc_dvc_varp;
3131 int leftlen;
3132 int totlen;
3133 int len;
3134 ASCEEP_CONFIG *ep;
3135 int i;
3136 #ifdef CONFIG_ISA
3137 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
3138 #endif /* CONFIG_ISA */
3139 uchar serialstr[13];
3141 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3142 ep = &boardp->eep_config.asc_eep;
3144 leftlen = cplen;
3145 totlen = len = 0;
3147 len = asc_prt_line(cp, leftlen,
3148 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3149 shost->host_no);
3150 ASC_PRT_NEXT();
3152 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
3153 == ASC_TRUE) {
3154 len =
3155 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
3156 serialstr);
3157 ASC_PRT_NEXT();
3158 } else {
3159 if (ep->adapter_info[5] == 0xBB) {
3160 len = asc_prt_line(cp, leftlen,
3161 " Default Settings Used for EEPROM-less Adapter.\n");
3162 ASC_PRT_NEXT();
3163 } else {
3164 len = asc_prt_line(cp, leftlen,
3165 " Serial Number Signature Not Present.\n");
3166 ASC_PRT_NEXT();
3170 len = asc_prt_line(cp, leftlen,
3171 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3172 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
3173 ep->max_tag_qng);
3174 ASC_PRT_NEXT();
3176 len = asc_prt_line(cp, leftlen,
3177 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
3178 ASC_PRT_NEXT();
3180 len = asc_prt_line(cp, leftlen, " Target ID: ");
3181 ASC_PRT_NEXT();
3182 for (i = 0; i <= ASC_MAX_TID; i++) {
3183 len = asc_prt_line(cp, leftlen, " %d", i);
3184 ASC_PRT_NEXT();
3186 len = asc_prt_line(cp, leftlen, "\n");
3187 ASC_PRT_NEXT();
3189 len = asc_prt_line(cp, leftlen, " Disconnects: ");
3190 ASC_PRT_NEXT();
3191 for (i = 0; i <= ASC_MAX_TID; i++) {
3192 len = asc_prt_line(cp, leftlen, " %c",
3193 (ep->
3194 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3195 'N');
3196 ASC_PRT_NEXT();
3198 len = asc_prt_line(cp, leftlen, "\n");
3199 ASC_PRT_NEXT();
3201 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
3202 ASC_PRT_NEXT();
3203 for (i = 0; i <= ASC_MAX_TID; i++) {
3204 len = asc_prt_line(cp, leftlen, " %c",
3205 (ep->
3206 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3207 'N');
3208 ASC_PRT_NEXT();
3210 len = asc_prt_line(cp, leftlen, "\n");
3211 ASC_PRT_NEXT();
3213 len = asc_prt_line(cp, leftlen, " Start Motor: ");
3214 ASC_PRT_NEXT();
3215 for (i = 0; i <= ASC_MAX_TID; i++) {
3216 len = asc_prt_line(cp, leftlen, " %c",
3217 (ep->
3218 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3219 'N');
3220 ASC_PRT_NEXT();
3222 len = asc_prt_line(cp, leftlen, "\n");
3223 ASC_PRT_NEXT();
3225 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3226 ASC_PRT_NEXT();
3227 for (i = 0; i <= ASC_MAX_TID; i++) {
3228 len = asc_prt_line(cp, leftlen, " %c",
3229 (ep->
3230 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3231 'N');
3232 ASC_PRT_NEXT();
3234 len = asc_prt_line(cp, leftlen, "\n");
3235 ASC_PRT_NEXT();
3237 #ifdef CONFIG_ISA
3238 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3239 len = asc_prt_line(cp, leftlen,
3240 " Host ISA DMA speed: %d MB/S\n",
3241 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
3242 ASC_PRT_NEXT();
3244 #endif /* CONFIG_ISA */
3246 return totlen;
3250 * asc_prt_adv_board_eeprom()
3252 * Print board EEPROM configuration.
3254 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3255 * cf. asc_prt_line().
3257 * Return the number of characters copied into 'cp'. No more than
3258 * 'cplen' characters will be copied to 'cp'.
3260 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
3262 struct asc_board *boardp = shost_priv(shost);
3263 ADV_DVC_VAR *adv_dvc_varp;
3264 int leftlen;
3265 int totlen;
3266 int len;
3267 int i;
3268 char *termstr;
3269 uchar serialstr[13];
3270 ADVEEP_3550_CONFIG *ep_3550 = NULL;
3271 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
3272 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
3273 ushort word;
3274 ushort *wordp;
3275 ushort sdtr_speed = 0;
3277 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3278 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3279 ep_3550 = &boardp->eep_config.adv_3550_eep;
3280 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3281 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
3282 } else {
3283 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
3286 leftlen = cplen;
3287 totlen = len = 0;
3289 len = asc_prt_line(cp, leftlen,
3290 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3291 shost->host_no);
3292 ASC_PRT_NEXT();
3294 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3295 wordp = &ep_3550->serial_number_word1;
3296 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3297 wordp = &ep_38C0800->serial_number_word1;
3298 } else {
3299 wordp = &ep_38C1600->serial_number_word1;
3302 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
3303 len =
3304 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
3305 serialstr);
3306 ASC_PRT_NEXT();
3307 } else {
3308 len = asc_prt_line(cp, leftlen,
3309 " Serial Number Signature Not Present.\n");
3310 ASC_PRT_NEXT();
3313 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3314 len = asc_prt_line(cp, leftlen,
3315 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3316 ep_3550->adapter_scsi_id,
3317 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
3318 ASC_PRT_NEXT();
3319 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3320 len = asc_prt_line(cp, leftlen,
3321 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3322 ep_38C0800->adapter_scsi_id,
3323 ep_38C0800->max_host_qng,
3324 ep_38C0800->max_dvc_qng);
3325 ASC_PRT_NEXT();
3326 } else {
3327 len = asc_prt_line(cp, leftlen,
3328 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3329 ep_38C1600->adapter_scsi_id,
3330 ep_38C1600->max_host_qng,
3331 ep_38C1600->max_dvc_qng);
3332 ASC_PRT_NEXT();
3334 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3335 word = ep_3550->termination;
3336 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3337 word = ep_38C0800->termination_lvd;
3338 } else {
3339 word = ep_38C1600->termination_lvd;
3341 switch (word) {
3342 case 1:
3343 termstr = "Low Off/High Off";
3344 break;
3345 case 2:
3346 termstr = "Low Off/High On";
3347 break;
3348 case 3:
3349 termstr = "Low On/High On";
3350 break;
3351 default:
3352 case 0:
3353 termstr = "Automatic";
3354 break;
3357 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3358 len = asc_prt_line(cp, leftlen,
3359 " termination: %u (%s), bios_ctrl: 0x%x\n",
3360 ep_3550->termination, termstr,
3361 ep_3550->bios_ctrl);
3362 ASC_PRT_NEXT();
3363 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3364 len = asc_prt_line(cp, leftlen,
3365 " termination: %u (%s), bios_ctrl: 0x%x\n",
3366 ep_38C0800->termination_lvd, termstr,
3367 ep_38C0800->bios_ctrl);
3368 ASC_PRT_NEXT();
3369 } else {
3370 len = asc_prt_line(cp, leftlen,
3371 " termination: %u (%s), bios_ctrl: 0x%x\n",
3372 ep_38C1600->termination_lvd, termstr,
3373 ep_38C1600->bios_ctrl);
3374 ASC_PRT_NEXT();
3377 len = asc_prt_line(cp, leftlen, " Target ID: ");
3378 ASC_PRT_NEXT();
3379 for (i = 0; i <= ADV_MAX_TID; i++) {
3380 len = asc_prt_line(cp, leftlen, " %X", i);
3381 ASC_PRT_NEXT();
3383 len = asc_prt_line(cp, leftlen, "\n");
3384 ASC_PRT_NEXT();
3386 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3387 word = ep_3550->disc_enable;
3388 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3389 word = ep_38C0800->disc_enable;
3390 } else {
3391 word = ep_38C1600->disc_enable;
3393 len = asc_prt_line(cp, leftlen, " Disconnects: ");
3394 ASC_PRT_NEXT();
3395 for (i = 0; i <= ADV_MAX_TID; i++) {
3396 len = asc_prt_line(cp, leftlen, " %c",
3397 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3398 ASC_PRT_NEXT();
3400 len = asc_prt_line(cp, leftlen, "\n");
3401 ASC_PRT_NEXT();
3403 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3404 word = ep_3550->tagqng_able;
3405 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3406 word = ep_38C0800->tagqng_able;
3407 } else {
3408 word = ep_38C1600->tagqng_able;
3410 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
3411 ASC_PRT_NEXT();
3412 for (i = 0; i <= ADV_MAX_TID; i++) {
3413 len = asc_prt_line(cp, leftlen, " %c",
3414 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3415 ASC_PRT_NEXT();
3417 len = asc_prt_line(cp, leftlen, "\n");
3418 ASC_PRT_NEXT();
3420 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3421 word = ep_3550->start_motor;
3422 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3423 word = ep_38C0800->start_motor;
3424 } else {
3425 word = ep_38C1600->start_motor;
3427 len = asc_prt_line(cp, leftlen, " Start Motor: ");
3428 ASC_PRT_NEXT();
3429 for (i = 0; i <= ADV_MAX_TID; i++) {
3430 len = asc_prt_line(cp, leftlen, " %c",
3431 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3432 ASC_PRT_NEXT();
3434 len = asc_prt_line(cp, leftlen, "\n");
3435 ASC_PRT_NEXT();
3437 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3438 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3439 ASC_PRT_NEXT();
3440 for (i = 0; i <= ADV_MAX_TID; i++) {
3441 len = asc_prt_line(cp, leftlen, " %c",
3442 (ep_3550->
3443 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
3444 'Y' : 'N');
3445 ASC_PRT_NEXT();
3447 len = asc_prt_line(cp, leftlen, "\n");
3448 ASC_PRT_NEXT();
3451 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3452 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
3453 ASC_PRT_NEXT();
3454 for (i = 0; i <= ADV_MAX_TID; i++) {
3455 len = asc_prt_line(cp, leftlen, " %c",
3456 (ep_3550->
3457 ultra_able & ADV_TID_TO_TIDMASK(i))
3458 ? 'Y' : 'N');
3459 ASC_PRT_NEXT();
3461 len = asc_prt_line(cp, leftlen, "\n");
3462 ASC_PRT_NEXT();
3465 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3466 word = ep_3550->wdtr_able;
3467 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3468 word = ep_38C0800->wdtr_able;
3469 } else {
3470 word = ep_38C1600->wdtr_able;
3472 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
3473 ASC_PRT_NEXT();
3474 for (i = 0; i <= ADV_MAX_TID; i++) {
3475 len = asc_prt_line(cp, leftlen, " %c",
3476 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3477 ASC_PRT_NEXT();
3479 len = asc_prt_line(cp, leftlen, "\n");
3480 ASC_PRT_NEXT();
3482 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
3483 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
3484 len = asc_prt_line(cp, leftlen,
3485 " Synchronous Transfer Speed (Mhz):\n ");
3486 ASC_PRT_NEXT();
3487 for (i = 0; i <= ADV_MAX_TID; i++) {
3488 char *speed_str;
3490 if (i == 0) {
3491 sdtr_speed = adv_dvc_varp->sdtr_speed1;
3492 } else if (i == 4) {
3493 sdtr_speed = adv_dvc_varp->sdtr_speed2;
3494 } else if (i == 8) {
3495 sdtr_speed = adv_dvc_varp->sdtr_speed3;
3496 } else if (i == 12) {
3497 sdtr_speed = adv_dvc_varp->sdtr_speed4;
3499 switch (sdtr_speed & ADV_MAX_TID) {
3500 case 0:
3501 speed_str = "Off";
3502 break;
3503 case 1:
3504 speed_str = " 5";
3505 break;
3506 case 2:
3507 speed_str = " 10";
3508 break;
3509 case 3:
3510 speed_str = " 20";
3511 break;
3512 case 4:
3513 speed_str = " 40";
3514 break;
3515 case 5:
3516 speed_str = " 80";
3517 break;
3518 default:
3519 speed_str = "Unk";
3520 break;
3522 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
3523 ASC_PRT_NEXT();
3524 if (i == 7) {
3525 len = asc_prt_line(cp, leftlen, "\n ");
3526 ASC_PRT_NEXT();
3528 sdtr_speed >>= 4;
3530 len = asc_prt_line(cp, leftlen, "\n");
3531 ASC_PRT_NEXT();
3534 return totlen;
3538 * asc_prt_driver_conf()
3540 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3541 * cf. asc_prt_line().
3543 * Return the number of characters copied into 'cp'. No more than
3544 * 'cplen' characters will be copied to 'cp'.
3546 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
3548 struct asc_board *boardp = shost_priv(shost);
3549 int leftlen;
3550 int totlen;
3551 int len;
3552 int chip_scsi_id;
3554 leftlen = cplen;
3555 totlen = len = 0;
3557 len = asc_prt_line(cp, leftlen,
3558 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
3559 shost->host_no);
3560 ASC_PRT_NEXT();
3562 len = asc_prt_line(cp, leftlen,
3563 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
3564 shost->host_busy, shost->last_reset, shost->max_id,
3565 shost->max_lun, shost->max_channel);
3566 ASC_PRT_NEXT();
3568 len = asc_prt_line(cp, leftlen,
3569 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
3570 shost->unique_id, shost->can_queue, shost->this_id,
3571 shost->sg_tablesize, shost->cmd_per_lun);
3572 ASC_PRT_NEXT();
3574 len = asc_prt_line(cp, leftlen,
3575 " unchecked_isa_dma %d, use_clustering %d\n",
3576 shost->unchecked_isa_dma, shost->use_clustering);
3577 ASC_PRT_NEXT();
3579 len = asc_prt_line(cp, leftlen,
3580 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
3581 boardp->flags, boardp->last_reset, jiffies,
3582 boardp->asc_n_io_port);
3583 ASC_PRT_NEXT();
3585 len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
3586 ASC_PRT_NEXT();
3588 if (ASC_NARROW_BOARD(boardp)) {
3589 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
3590 } else {
3591 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
3594 return totlen;
3598 * asc_prt_asc_board_info()
3600 * Print dynamic board configuration information.
3602 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3603 * cf. asc_prt_line().
3605 * Return the number of characters copied into 'cp'. No more than
3606 * 'cplen' characters will be copied to 'cp'.
3608 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
3610 struct asc_board *boardp = shost_priv(shost);
3611 int chip_scsi_id;
3612 int leftlen;
3613 int totlen;
3614 int len;
3615 ASC_DVC_VAR *v;
3616 ASC_DVC_CFG *c;
3617 int i;
3618 int renegotiate = 0;
3620 v = &boardp->dvc_var.asc_dvc_var;
3621 c = &boardp->dvc_cfg.asc_dvc_cfg;
3622 chip_scsi_id = c->chip_scsi_id;
3624 leftlen = cplen;
3625 totlen = len = 0;
3627 len = asc_prt_line(cp, leftlen,
3628 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3629 shost->host_no);
3630 ASC_PRT_NEXT();
3632 len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, "
3633 "mcode_version 0x%x, err_code %u\n",
3634 c->chip_version, c->mcode_date, c->mcode_version,
3635 v->err_code);
3636 ASC_PRT_NEXT();
3638 /* Current number of commands waiting for the host. */
3639 len = asc_prt_line(cp, leftlen,
3640 " Total Command Pending: %d\n", v->cur_total_qng);
3641 ASC_PRT_NEXT();
3643 len = asc_prt_line(cp, leftlen, " Command Queuing:");
3644 ASC_PRT_NEXT();
3645 for (i = 0; i <= ASC_MAX_TID; i++) {
3646 if ((chip_scsi_id == i) ||
3647 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3648 continue;
3650 len = asc_prt_line(cp, leftlen, " %X:%c",
3652 (v->
3653 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
3654 'Y' : 'N');
3655 ASC_PRT_NEXT();
3657 len = asc_prt_line(cp, leftlen, "\n");
3658 ASC_PRT_NEXT();
3660 /* Current number of commands waiting for a device. */
3661 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
3662 ASC_PRT_NEXT();
3663 for (i = 0; i <= ASC_MAX_TID; i++) {
3664 if ((chip_scsi_id == i) ||
3665 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3666 continue;
3668 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
3669 ASC_PRT_NEXT();
3671 len = asc_prt_line(cp, leftlen, "\n");
3672 ASC_PRT_NEXT();
3674 /* Current limit on number of commands that can be sent to a device. */
3675 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
3676 ASC_PRT_NEXT();
3677 for (i = 0; i <= ASC_MAX_TID; i++) {
3678 if ((chip_scsi_id == i) ||
3679 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3680 continue;
3682 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
3683 ASC_PRT_NEXT();
3685 len = asc_prt_line(cp, leftlen, "\n");
3686 ASC_PRT_NEXT();
3688 /* Indicate whether the device has returned queue full status. */
3689 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
3690 ASC_PRT_NEXT();
3691 for (i = 0; i <= ASC_MAX_TID; i++) {
3692 if ((chip_scsi_id == i) ||
3693 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3694 continue;
3696 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
3697 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
3698 i, boardp->queue_full_cnt[i]);
3699 } else {
3700 len = asc_prt_line(cp, leftlen, " %X:N", i);
3702 ASC_PRT_NEXT();
3704 len = asc_prt_line(cp, leftlen, "\n");
3705 ASC_PRT_NEXT();
3707 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3708 ASC_PRT_NEXT();
3709 for (i = 0; i <= ASC_MAX_TID; i++) {
3710 if ((chip_scsi_id == i) ||
3711 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3712 continue;
3714 len = asc_prt_line(cp, leftlen, " %X:%c",
3716 (v->
3717 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3718 'N');
3719 ASC_PRT_NEXT();
3721 len = asc_prt_line(cp, leftlen, "\n");
3722 ASC_PRT_NEXT();
3724 for (i = 0; i <= ASC_MAX_TID; i++) {
3725 uchar syn_period_ix;
3727 if ((chip_scsi_id == i) ||
3728 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3729 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
3730 continue;
3733 len = asc_prt_line(cp, leftlen, " %X:", i);
3734 ASC_PRT_NEXT();
3736 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
3737 len = asc_prt_line(cp, leftlen, " Asynchronous");
3738 ASC_PRT_NEXT();
3739 } else {
3740 syn_period_ix =
3741 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
3744 len = asc_prt_line(cp, leftlen,
3745 " Transfer Period Factor: %d (%d.%d Mhz),",
3746 v->sdtr_period_tbl[syn_period_ix],
3747 250 /
3748 v->sdtr_period_tbl[syn_period_ix],
3749 ASC_TENTHS(250,
3751 sdtr_period_tbl
3752 [syn_period_ix]));
3753 ASC_PRT_NEXT();
3755 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
3756 boardp->
3757 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
3758 ASC_PRT_NEXT();
3761 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3762 len = asc_prt_line(cp, leftlen, "*\n");
3763 renegotiate = 1;
3764 } else {
3765 len = asc_prt_line(cp, leftlen, "\n");
3767 ASC_PRT_NEXT();
3770 if (renegotiate) {
3771 len = asc_prt_line(cp, leftlen,
3772 " * = Re-negotiation pending before next command.\n");
3773 ASC_PRT_NEXT();
3776 return totlen;
3780 * asc_prt_adv_board_info()
3782 * Print dynamic board configuration information.
3784 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3785 * cf. asc_prt_line().
3787 * Return the number of characters copied into 'cp'. No more than
3788 * 'cplen' characters will be copied to 'cp'.
3790 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
3792 struct asc_board *boardp = shost_priv(shost);
3793 int leftlen;
3794 int totlen;
3795 int len;
3796 int i;
3797 ADV_DVC_VAR *v;
3798 ADV_DVC_CFG *c;
3799 AdvPortAddr iop_base;
3800 ushort chip_scsi_id;
3801 ushort lramword;
3802 uchar lrambyte;
3803 ushort tagqng_able;
3804 ushort sdtr_able, wdtr_able;
3805 ushort wdtr_done, sdtr_done;
3806 ushort period = 0;
3807 int renegotiate = 0;
3809 v = &boardp->dvc_var.adv_dvc_var;
3810 c = &boardp->dvc_cfg.adv_dvc_cfg;
3811 iop_base = v->iop_base;
3812 chip_scsi_id = v->chip_scsi_id;
3814 leftlen = cplen;
3815 totlen = len = 0;
3817 len = asc_prt_line(cp, leftlen,
3818 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3819 shost->host_no);
3820 ASC_PRT_NEXT();
3822 len = asc_prt_line(cp, leftlen,
3823 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
3824 v->iop_base,
3825 AdvReadWordRegister(iop_base,
3826 IOPW_SCSI_CFG1) & CABLE_DETECT,
3827 v->err_code);
3828 ASC_PRT_NEXT();
3830 len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, "
3831 "mcode_version 0x%x\n", c->chip_version,
3832 c->mcode_date, c->mcode_version);
3833 ASC_PRT_NEXT();
3835 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
3836 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
3837 ASC_PRT_NEXT();
3838 for (i = 0; i <= ADV_MAX_TID; i++) {
3839 if ((chip_scsi_id == i) ||
3840 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3841 continue;
3844 len = asc_prt_line(cp, leftlen, " %X:%c",
3846 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3847 'N');
3848 ASC_PRT_NEXT();
3850 len = asc_prt_line(cp, leftlen, "\n");
3851 ASC_PRT_NEXT();
3853 len = asc_prt_line(cp, leftlen, " Queue Limit:");
3854 ASC_PRT_NEXT();
3855 for (i = 0; i <= ADV_MAX_TID; i++) {
3856 if ((chip_scsi_id == i) ||
3857 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3858 continue;
3861 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
3862 lrambyte);
3864 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
3865 ASC_PRT_NEXT();
3867 len = asc_prt_line(cp, leftlen, "\n");
3868 ASC_PRT_NEXT();
3870 len = asc_prt_line(cp, leftlen, " Command Pending:");
3871 ASC_PRT_NEXT();
3872 for (i = 0; i <= ADV_MAX_TID; i++) {
3873 if ((chip_scsi_id == i) ||
3874 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3875 continue;
3878 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
3879 lrambyte);
3881 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
3882 ASC_PRT_NEXT();
3884 len = asc_prt_line(cp, leftlen, "\n");
3885 ASC_PRT_NEXT();
3887 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
3888 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
3889 ASC_PRT_NEXT();
3890 for (i = 0; i <= ADV_MAX_TID; i++) {
3891 if ((chip_scsi_id == i) ||
3892 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3893 continue;
3896 len = asc_prt_line(cp, leftlen, " %X:%c",
3898 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3899 'N');
3900 ASC_PRT_NEXT();
3902 len = asc_prt_line(cp, leftlen, "\n");
3903 ASC_PRT_NEXT();
3905 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
3906 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
3907 ASC_PRT_NEXT();
3908 for (i = 0; i <= ADV_MAX_TID; i++) {
3909 if ((chip_scsi_id == i) ||
3910 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3911 continue;
3914 AdvReadWordLram(iop_base,
3915 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
3916 lramword);
3918 len = asc_prt_line(cp, leftlen, " %X:%d",
3919 i, (lramword & 0x8000) ? 16 : 8);
3920 ASC_PRT_NEXT();
3922 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
3923 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3924 len = asc_prt_line(cp, leftlen, "*");
3925 ASC_PRT_NEXT();
3926 renegotiate = 1;
3929 len = asc_prt_line(cp, leftlen, "\n");
3930 ASC_PRT_NEXT();
3932 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
3933 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
3934 ASC_PRT_NEXT();
3935 for (i = 0; i <= ADV_MAX_TID; i++) {
3936 if ((chip_scsi_id == i) ||
3937 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3938 continue;
3941 len = asc_prt_line(cp, leftlen, " %X:%c",
3943 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3944 'N');
3945 ASC_PRT_NEXT();
3947 len = asc_prt_line(cp, leftlen, "\n");
3948 ASC_PRT_NEXT();
3950 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
3951 for (i = 0; i <= ADV_MAX_TID; i++) {
3953 AdvReadWordLram(iop_base,
3954 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
3955 lramword);
3956 lramword &= ~0x8000;
3958 if ((chip_scsi_id == i) ||
3959 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3960 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
3961 continue;
3964 len = asc_prt_line(cp, leftlen, " %X:", i);
3965 ASC_PRT_NEXT();
3967 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
3968 len = asc_prt_line(cp, leftlen, " Asynchronous");
3969 ASC_PRT_NEXT();
3970 } else {
3971 len =
3972 asc_prt_line(cp, leftlen,
3973 " Transfer Period Factor: ");
3974 ASC_PRT_NEXT();
3976 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
3977 len =
3978 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
3979 ASC_PRT_NEXT();
3980 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
3981 len =
3982 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
3983 ASC_PRT_NEXT();
3984 } else { /* 20 Mhz or below. */
3986 period = (((lramword >> 8) * 25) + 50) / 4;
3988 if (period == 0) { /* Should never happen. */
3989 len =
3990 asc_prt_line(cp, leftlen,
3991 "%d (? Mhz), ");
3992 ASC_PRT_NEXT();
3993 } else {
3994 len = asc_prt_line(cp, leftlen,
3995 "%d (%d.%d Mhz),",
3996 period, 250 / period,
3997 ASC_TENTHS(250,
3998 period));
3999 ASC_PRT_NEXT();
4003 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
4004 lramword & 0x1F);
4005 ASC_PRT_NEXT();
4008 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
4009 len = asc_prt_line(cp, leftlen, "*\n");
4010 renegotiate = 1;
4011 } else {
4012 len = asc_prt_line(cp, leftlen, "\n");
4014 ASC_PRT_NEXT();
4017 if (renegotiate) {
4018 len = asc_prt_line(cp, leftlen,
4019 " * = Re-negotiation pending before next command.\n");
4020 ASC_PRT_NEXT();
4023 return totlen;
4027 * asc_proc_copy()
4029 * Copy proc information to a read buffer taking into account the current
4030 * read offset in the file and the remaining space in the read buffer.
4032 static int
4033 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
4034 char *cp, int cplen)
4036 int cnt = 0;
4038 ASC_DBG(2, "offset %d, advoffset %d, cplen %d\n",
4039 (unsigned)offset, (unsigned)advoffset, cplen);
4040 if (offset <= advoffset) {
4041 /* Read offset below current offset, copy everything. */
4042 cnt = min(cplen, leftlen);
4043 ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n",
4044 (ulong)curbuf, (ulong)cp, cnt);
4045 memcpy(curbuf, cp, cnt);
4046 } else if (offset < advoffset + cplen) {
4047 /* Read offset within current range, partial copy. */
4048 cnt = (advoffset + cplen) - offset;
4049 cp = (cp + cplen) - cnt;
4050 cnt = min(cnt, leftlen);
4051 ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n",
4052 (ulong)curbuf, (ulong)cp, cnt);
4053 memcpy(curbuf, cp, cnt);
4055 return cnt;
4058 #ifdef ADVANSYS_STATS
4060 * asc_prt_board_stats()
4062 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4063 * cf. asc_prt_line().
4065 * Return the number of characters copied into 'cp'. No more than
4066 * 'cplen' characters will be copied to 'cp'.
4068 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
4070 struct asc_board *boardp = shost_priv(shost);
4071 struct asc_stats *s = &boardp->asc_stats;
4073 int leftlen = cplen;
4074 int len, totlen = 0;
4076 len = asc_prt_line(cp, leftlen,
4077 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
4078 shost->host_no);
4079 ASC_PRT_NEXT();
4081 len = asc_prt_line(cp, leftlen,
4082 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
4083 s->queuecommand, s->reset, s->biosparam,
4084 s->interrupt);
4085 ASC_PRT_NEXT();
4087 len = asc_prt_line(cp, leftlen,
4088 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
4089 s->callback, s->done, s->build_error,
4090 s->adv_build_noreq, s->adv_build_nosg);
4091 ASC_PRT_NEXT();
4093 len = asc_prt_line(cp, leftlen,
4094 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
4095 s->exe_noerror, s->exe_busy, s->exe_error,
4096 s->exe_unknown);
4097 ASC_PRT_NEXT();
4100 * Display data transfer statistics.
4102 if (s->xfer_cnt > 0) {
4103 len = asc_prt_line(cp, leftlen, " xfer_cnt %lu, xfer_elem %lu, ",
4104 s->xfer_cnt, s->xfer_elem);
4105 ASC_PRT_NEXT();
4107 len = asc_prt_line(cp, leftlen, "xfer_bytes %lu.%01lu kb\n",
4108 s->xfer_sect / 2, ASC_TENTHS(s->xfer_sect, 2));
4109 ASC_PRT_NEXT();
4111 /* Scatter gather transfer statistics */
4112 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
4113 s->xfer_elem / s->xfer_cnt,
4114 ASC_TENTHS(s->xfer_elem, s->xfer_cnt));
4115 ASC_PRT_NEXT();
4117 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
4118 (s->xfer_sect / 2) / s->xfer_elem,
4119 ASC_TENTHS((s->xfer_sect / 2), s->xfer_elem));
4120 ASC_PRT_NEXT();
4122 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
4123 (s->xfer_sect / 2) / s->xfer_cnt,
4124 ASC_TENTHS((s->xfer_sect / 2), s->xfer_cnt));
4125 ASC_PRT_NEXT();
4128 return totlen;
4130 #endif /* ADVANSYS_STATS */
4133 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
4135 * *buffer: I/O buffer
4136 * **start: if inout == FALSE pointer into buffer where user read should start
4137 * offset: current offset into a /proc/scsi/advansys/[0...] file
4138 * length: length of buffer
4139 * hostno: Scsi_Host host_no
4140 * inout: TRUE - user is writing; FALSE - user is reading
4142 * Return the number of bytes read from or written to a
4143 * /proc/scsi/advansys/[0...] file.
4145 * Note: This function uses the per board buffer 'prtbuf' which is
4146 * allocated when the board is initialized in advansys_detect(). The
4147 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4148 * used to write to the buffer. The way asc_proc_copy() is written
4149 * if 'prtbuf' is too small it will not be overwritten. Instead the
4150 * user just won't get all the available statistics.
4152 static int
4153 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4154 off_t offset, int length, int inout)
4156 struct asc_board *boardp = shost_priv(shost);
4157 char *cp;
4158 int cplen;
4159 int cnt;
4160 int totcnt;
4161 int leftlen;
4162 char *curbuf;
4163 off_t advoffset;
4165 ASC_DBG(1, "begin\n");
4168 * User write not supported.
4170 if (inout == TRUE)
4171 return -ENOSYS;
4174 * User read of /proc/scsi/advansys/[0...] file.
4177 /* Copy read data starting at the beginning of the buffer. */
4178 *start = buffer;
4179 curbuf = buffer;
4180 advoffset = 0;
4181 totcnt = 0;
4182 leftlen = length;
4185 * Get board configuration information.
4187 * advansys_info() returns the board string from its own static buffer.
4189 cp = (char *)advansys_info(shost);
4190 strcat(cp, "\n");
4191 cplen = strlen(cp);
4192 /* Copy board information. */
4193 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4194 totcnt += cnt;
4195 leftlen -= cnt;
4196 if (leftlen == 0) {
4197 ASC_DBG(1, "totcnt %d\n", totcnt);
4198 return totcnt;
4200 advoffset += cplen;
4201 curbuf += cnt;
4204 * Display Wide Board BIOS Information.
4206 if (!ASC_NARROW_BOARD(boardp)) {
4207 cp = boardp->prtbuf;
4208 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
4209 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4210 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4211 cplen);
4212 totcnt += cnt;
4213 leftlen -= cnt;
4214 if (leftlen == 0) {
4215 ASC_DBG(1, "totcnt %d\n", totcnt);
4216 return totcnt;
4218 advoffset += cplen;
4219 curbuf += cnt;
4223 * Display driver information for each device attached to the board.
4225 cp = boardp->prtbuf;
4226 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
4227 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4228 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4229 totcnt += cnt;
4230 leftlen -= cnt;
4231 if (leftlen == 0) {
4232 ASC_DBG(1, "totcnt %d\n", totcnt);
4233 return totcnt;
4235 advoffset += cplen;
4236 curbuf += cnt;
4239 * Display EEPROM configuration for the board.
4241 cp = boardp->prtbuf;
4242 if (ASC_NARROW_BOARD(boardp)) {
4243 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4244 } else {
4245 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4247 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4248 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4249 totcnt += cnt;
4250 leftlen -= cnt;
4251 if (leftlen == 0) {
4252 ASC_DBG(1, "totcnt %d\n", totcnt);
4253 return totcnt;
4255 advoffset += cplen;
4256 curbuf += cnt;
4259 * Display driver configuration and information for the board.
4261 cp = boardp->prtbuf;
4262 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
4263 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4264 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4265 totcnt += cnt;
4266 leftlen -= cnt;
4267 if (leftlen == 0) {
4268 ASC_DBG(1, "totcnt %d\n", totcnt);
4269 return totcnt;
4271 advoffset += cplen;
4272 curbuf += cnt;
4274 #ifdef ADVANSYS_STATS
4276 * Display driver statistics for the board.
4278 cp = boardp->prtbuf;
4279 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
4280 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4281 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4282 totcnt += cnt;
4283 leftlen -= cnt;
4284 if (leftlen == 0) {
4285 ASC_DBG(1, "totcnt %d\n", totcnt);
4286 return totcnt;
4288 advoffset += cplen;
4289 curbuf += cnt;
4290 #endif /* ADVANSYS_STATS */
4293 * Display Asc Library dynamic configuration information
4294 * for the board.
4296 cp = boardp->prtbuf;
4297 if (ASC_NARROW_BOARD(boardp)) {
4298 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
4299 } else {
4300 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
4302 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4303 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4304 totcnt += cnt;
4305 leftlen -= cnt;
4306 if (leftlen == 0) {
4307 ASC_DBG(1, "totcnt %d\n", totcnt);
4308 return totcnt;
4310 advoffset += cplen;
4311 curbuf += cnt;
4313 ASC_DBG(1, "totcnt %d\n", totcnt);
4315 return totcnt;
4317 #endif /* CONFIG_PROC_FS */
4319 static void asc_scsi_done(struct scsi_cmnd *scp)
4321 scsi_dma_unmap(scp);
4322 ASC_STATS(scp->device->host, done);
4323 scp->scsi_done(scp);
4326 static void AscSetBank(PortAddr iop_base, uchar bank)
4328 uchar val;
4330 val = AscGetChipControl(iop_base) &
4332 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
4333 CC_CHIP_RESET));
4334 if (bank == 1) {
4335 val |= CC_BANK_ONE;
4336 } else if (bank == 2) {
4337 val |= CC_DIAG | CC_BANK_ONE;
4338 } else {
4339 val &= ~CC_BANK_ONE;
4341 AscSetChipControl(iop_base, val);
4344 static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
4346 AscSetBank(iop_base, 1);
4347 AscWriteChipIH(iop_base, ins_code);
4348 AscSetBank(iop_base, 0);
4351 static int AscStartChip(PortAddr iop_base)
4353 AscSetChipControl(iop_base, 0);
4354 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4355 return (0);
4357 return (1);
4360 static int AscStopChip(PortAddr iop_base)
4362 uchar cc_val;
4364 cc_val =
4365 AscGetChipControl(iop_base) &
4366 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
4367 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
4368 AscSetChipIH(iop_base, INS_HALT);
4369 AscSetChipIH(iop_base, INS_RFLAG_WTM);
4370 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
4371 return (0);
4373 return (1);
4376 static int AscIsChipHalted(PortAddr iop_base)
4378 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4379 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
4380 return (1);
4383 return (0);
4386 static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
4388 PortAddr iop_base;
4389 int i = 10;
4391 iop_base = asc_dvc->iop_base;
4392 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
4393 && (i-- > 0)) {
4394 mdelay(100);
4396 AscStopChip(iop_base);
4397 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
4398 udelay(60);
4399 AscSetChipIH(iop_base, INS_RFLAG_WTM);
4400 AscSetChipIH(iop_base, INS_HALT);
4401 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
4402 AscSetChipControl(iop_base, CC_HALT);
4403 mdelay(200);
4404 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
4405 AscSetChipStatus(iop_base, 0);
4406 return (AscIsChipHalted(iop_base));
4409 static int AscFindSignature(PortAddr iop_base)
4411 ushort sig_word;
4413 ASC_DBG(1, "AscGetChipSignatureByte(0x%x) 0x%x\n",
4414 iop_base, AscGetChipSignatureByte(iop_base));
4415 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
4416 ASC_DBG(1, "AscGetChipSignatureWord(0x%x) 0x%x\n",
4417 iop_base, AscGetChipSignatureWord(iop_base));
4418 sig_word = AscGetChipSignatureWord(iop_base);
4419 if ((sig_word == (ushort)ASC_1000_ID0W) ||
4420 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
4421 return (1);
4424 return (0);
4427 static void AscEnableInterrupt(PortAddr iop_base)
4429 ushort cfg;
4431 cfg = AscGetChipCfgLsw(iop_base);
4432 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
4435 static void AscDisableInterrupt(PortAddr iop_base)
4437 ushort cfg;
4439 cfg = AscGetChipCfgLsw(iop_base);
4440 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
4443 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
4445 unsigned char byte_data;
4446 unsigned short word_data;
4448 if (isodd_word(addr)) {
4449 AscSetChipLramAddr(iop_base, addr - 1);
4450 word_data = AscGetChipLramData(iop_base);
4451 byte_data = (word_data >> 8) & 0xFF;
4452 } else {
4453 AscSetChipLramAddr(iop_base, addr);
4454 word_data = AscGetChipLramData(iop_base);
4455 byte_data = word_data & 0xFF;
4457 return byte_data;
4460 static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
4462 ushort word_data;
4464 AscSetChipLramAddr(iop_base, addr);
4465 word_data = AscGetChipLramData(iop_base);
4466 return (word_data);
4469 #if CC_VERY_LONG_SG_LIST
4470 static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
4472 ushort val_low, val_high;
4473 ASC_DCNT dword_data;
4475 AscSetChipLramAddr(iop_base, addr);
4476 val_low = AscGetChipLramData(iop_base);
4477 val_high = AscGetChipLramData(iop_base);
4478 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
4479 return (dword_data);
4481 #endif /* CC_VERY_LONG_SG_LIST */
4483 static void
4484 AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
4486 int i;
4488 AscSetChipLramAddr(iop_base, s_addr);
4489 for (i = 0; i < words; i++) {
4490 AscSetChipLramData(iop_base, set_wval);
4494 static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
4496 AscSetChipLramAddr(iop_base, addr);
4497 AscSetChipLramData(iop_base, word_val);
4500 static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
4502 ushort word_data;
4504 if (isodd_word(addr)) {
4505 addr--;
4506 word_data = AscReadLramWord(iop_base, addr);
4507 word_data &= 0x00FF;
4508 word_data |= (((ushort)byte_val << 8) & 0xFF00);
4509 } else {
4510 word_data = AscReadLramWord(iop_base, addr);
4511 word_data &= 0xFF00;
4512 word_data |= ((ushort)byte_val & 0x00FF);
4514 AscWriteLramWord(iop_base, addr, word_data);
4518 * Copy 2 bytes to LRAM.
4520 * The source data is assumed to be in little-endian order in memory
4521 * and is maintained in little-endian order when written to LRAM.
4523 static void
4524 AscMemWordCopyPtrToLram(PortAddr iop_base,
4525 ushort s_addr, uchar *s_buffer, int words)
4527 int i;
4529 AscSetChipLramAddr(iop_base, s_addr);
4530 for (i = 0; i < 2 * words; i += 2) {
4532 * On a little-endian system the second argument below
4533 * produces a little-endian ushort which is written to
4534 * LRAM in little-endian order. On a big-endian system
4535 * the second argument produces a big-endian ushort which
4536 * is "transparently" byte-swapped by outpw() and written
4537 * in little-endian order to LRAM.
4539 outpw(iop_base + IOP_RAM_DATA,
4540 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
4545 * Copy 4 bytes to LRAM.
4547 * The source data is assumed to be in little-endian order in memory
4548 * and is maintained in little-endian order when writen to LRAM.
4550 static void
4551 AscMemDWordCopyPtrToLram(PortAddr iop_base,
4552 ushort s_addr, uchar *s_buffer, int dwords)
4554 int i;
4556 AscSetChipLramAddr(iop_base, s_addr);
4557 for (i = 0; i < 4 * dwords; i += 4) {
4558 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
4559 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
4564 * Copy 2 bytes from LRAM.
4566 * The source data is assumed to be in little-endian order in LRAM
4567 * and is maintained in little-endian order when written to memory.
4569 static void
4570 AscMemWordCopyPtrFromLram(PortAddr iop_base,
4571 ushort s_addr, uchar *d_buffer, int words)
4573 int i;
4574 ushort word;
4576 AscSetChipLramAddr(iop_base, s_addr);
4577 for (i = 0; i < 2 * words; i += 2) {
4578 word = inpw(iop_base + IOP_RAM_DATA);
4579 d_buffer[i] = word & 0xff;
4580 d_buffer[i + 1] = (word >> 8) & 0xff;
4584 static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
4586 ASC_DCNT sum;
4587 int i;
4589 sum = 0L;
4590 for (i = 0; i < words; i++, s_addr += 2) {
4591 sum += AscReadLramWord(iop_base, s_addr);
4593 return (sum);
4596 static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
4598 uchar i;
4599 ushort s_addr;
4600 PortAddr iop_base;
4601 ushort warn_code;
4603 iop_base = asc_dvc->iop_base;
4604 warn_code = 0;
4605 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
4606 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
4607 64) >> 1));
4608 i = ASC_MIN_ACTIVE_QNO;
4609 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
4610 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4611 (uchar)(i + 1));
4612 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4613 (uchar)(asc_dvc->max_total_qng));
4614 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4615 (uchar)i);
4616 i++;
4617 s_addr += ASC_QBLK_SIZE;
4618 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
4619 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4620 (uchar)(i + 1));
4621 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4622 (uchar)(i - 1));
4623 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4624 (uchar)i);
4626 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4627 (uchar)ASC_QLINK_END);
4628 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4629 (uchar)(asc_dvc->max_total_qng - 1));
4630 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4631 (uchar)asc_dvc->max_total_qng);
4632 i++;
4633 s_addr += ASC_QBLK_SIZE;
4634 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
4635 i++, s_addr += ASC_QBLK_SIZE) {
4636 AscWriteLramByte(iop_base,
4637 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
4638 AscWriteLramByte(iop_base,
4639 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
4640 AscWriteLramByte(iop_base,
4641 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
4643 return warn_code;
4646 static ASC_DCNT
4647 AscLoadMicroCode(PortAddr iop_base,
4648 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
4650 ASC_DCNT chksum;
4651 ushort mcode_word_size;
4652 ushort mcode_chksum;
4654 /* Write the microcode buffer starting at LRAM address 0. */
4655 mcode_word_size = (ushort)(mcode_size >> 1);
4656 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
4657 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
4659 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
4660 ASC_DBG(1, "chksum 0x%lx\n", (ulong)chksum);
4661 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
4662 (ushort)ASC_CODE_SEC_BEG,
4663 (ushort)((mcode_size -
4664 s_addr - (ushort)
4665 ASC_CODE_SEC_BEG) /
4666 2));
4667 ASC_DBG(1, "mcode_chksum 0x%lx\n", (ulong)mcode_chksum);
4668 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
4669 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
4670 return chksum;
4673 /* Microcode buffer is kept after initialization for error recovery. */
4674 static uchar _asc_mcode_buf[] = {
4675 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4676 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
4677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4678 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4679 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05,
4681 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4682 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4683 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
4684 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
4685 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04,
4686 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
4687 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
4688 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98,
4689 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00,
4690 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
4691 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
4692 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23,
4693 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04,
4694 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
4695 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
4696 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88,
4697 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00,
4698 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
4699 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
4700 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01,
4701 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8,
4702 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
4703 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
4704 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01,
4705 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33,
4706 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
4707 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
4708 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
4709 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23,
4710 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
4711 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
4712 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
4713 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84,
4714 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
4715 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
4716 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
4717 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46,
4718 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
4719 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
4720 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02,
4721 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82,
4722 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
4723 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
4724 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02,
4725 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23,
4726 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
4727 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
4728 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01,
4729 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02,
4730 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
4731 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
4732 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01,
4733 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
4734 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
4735 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
4736 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39,
4737 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6,
4738 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
4739 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
4740 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42,
4741 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01,
4742 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
4743 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
4744 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33,
4745 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83,
4746 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
4747 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
4748 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83,
4749 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00,
4750 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
4751 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
4752 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42,
4753 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95,
4754 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
4755 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
4756 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32,
4757 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84,
4758 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
4759 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
4760 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95,
4761 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4,
4762 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
4763 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
4764 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84,
4765 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84,
4766 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
4767 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
4768 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2,
4769 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00,
4770 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
4771 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
4772 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04,
4773 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00,
4774 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
4775 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
4776 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE,
4777 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62,
4778 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
4779 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
4780 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC,
4781 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95,
4782 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
4783 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
4784 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01,
4785 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01,
4786 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
4787 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
4788 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01,
4789 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05,
4790 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
4791 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
4792 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85,
4793 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63,
4794 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
4795 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
4796 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85,
4797 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85,
4798 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
4799 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
4800 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23,
4801 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87,
4802 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
4803 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
4804 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33,
4805 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60,
4806 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
4807 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
4808 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA,
4809 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33,
4810 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
4811 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
4812 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67,
4813 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
4814 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
4815 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
4816 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6,
4817 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06,
4818 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
4819 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
4820 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03,
4821 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33,
4822 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
4823 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
4824 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B,
4825 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88,
4826 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
4827 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
4828 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07,
4829 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84,
4830 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
4831 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
4832 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04,
4833 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00,
4834 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
4835 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
4836 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01,
4837 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04,
4838 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
4839 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
4840 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05,
4841 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23,
4842 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
4843 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
4844 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
4845 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
4846 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
4847 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
4848 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43,
4849 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01,
4850 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
4851 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
4852 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95,
4853 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88,
4854 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
4855 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
4856 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09,
4857 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32,
4858 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
4859 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
4860 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
4861 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73,
4862 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
4863 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
4864 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77,
4865 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23,
4866 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
4869 static unsigned short _asc_mcode_size = sizeof(_asc_mcode_buf);
4870 static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
4872 /* Microcode buffer is kept after initialization for error recovery. */
4873 static unsigned char _adv_asc3550_buf[] = {
4874 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
4875 0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00,
4876 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7,
4877 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
4878 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
4879 0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54,
4880 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01,
4881 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
4882 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
4883 0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
4884 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
4885 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
4886 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
4887 0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
4888 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a,
4889 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
4890 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
4891 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00,
4892 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c,
4893 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
4894 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
4895 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10,
4896 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56,
4897 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
4898 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
4899 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00,
4900 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10,
4901 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
4902 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
4903 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55,
4904 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0,
4905 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
4906 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
4907 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01,
4908 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02,
4909 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
4910 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
4911 0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13,
4912 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18,
4913 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
4914 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
4915 0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90,
4916 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10,
4917 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
4918 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
4919 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00,
4920 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
4921 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
4922 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
4923 0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe,
4924 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02,
4925 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
4926 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
4927 0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe,
4928 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
4929 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
4930 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
4931 0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02,
4932 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02,
4933 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
4934 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
4935 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10,
4936 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d,
4937 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
4938 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
4939 0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0,
4940 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe,
4941 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
4942 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
4943 0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d,
4944 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a,
4945 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
4946 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
4947 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03,
4948 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe,
4949 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
4950 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
4951 0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0,
4952 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f,
4953 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
4954 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
4955 0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2,
4956 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11,
4957 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
4958 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
4959 0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe,
4960 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1,
4961 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
4962 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
4963 0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28,
4964 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02,
4965 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
4966 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
4967 0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04,
4968 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe,
4969 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
4970 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
4971 0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c,
4972 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe,
4973 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
4974 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
4975 0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90,
4976 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67,
4977 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
4978 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
4979 0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2,
4980 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04,
4981 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
4982 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
4983 0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05,
4984 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1,
4985 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
4986 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
4987 0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d,
4988 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b,
4989 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
4990 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
4991 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19,
4992 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05,
4993 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
4994 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
4995 0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48,
4996 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d,
4997 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
4998 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
4999 0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4,
5000 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87,
5001 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
5002 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
5003 0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a,
5004 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
5005 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
5006 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
5007 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
5008 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02,
5009 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
5010 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
5011 0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25,
5012 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c,
5013 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
5014 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
5015 0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a,
5016 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80,
5017 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
5018 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
5019 0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
5020 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52,
5021 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
5022 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
5023 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18,
5024 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58,
5025 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
5026 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
5027 0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35,
5028 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0,
5029 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
5030 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
5031 0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10,
5032 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61,
5033 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
5034 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
5035 0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe,
5036 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10,
5037 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
5038 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
5039 0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
5040 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d,
5041 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
5042 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
5043 0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01,
5044 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02,
5045 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
5046 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
5047 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
5048 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77,
5049 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
5050 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
5051 0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05,
5052 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56,
5053 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
5054 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
5055 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59,
5056 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00,
5057 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
5058 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
5059 0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a,
5060 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d,
5061 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
5062 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
5063 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe,
5064 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51,
5065 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
5066 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
5067 0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00,
5068 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33,
5069 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
5070 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
5071 0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe,
5072 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93,
5073 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
5074 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
5075 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0,
5076 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9,
5077 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
5078 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
5079 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd,
5080 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f,
5081 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
5082 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
5083 0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54,
5084 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01,
5085 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
5086 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
5087 0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e,
5088 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01,
5089 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
5090 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
5091 0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02,
5092 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe,
5093 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
5094 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
5095 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35,
5096 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f,
5097 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
5098 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
5099 0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b,
5100 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea,
5101 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
5102 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
5103 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47,
5104 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38,
5105 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
5106 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
5107 0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe,
5108 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce,
5109 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
5110 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
5111 0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe,
5112 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe,
5113 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
5114 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
5115 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4,
5116 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe,
5117 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
5118 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
5119 0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11,
5120 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12,
5121 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
5122 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
5123 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc,
5124 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23,
5125 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
5126 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
5127 0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe,
5128 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
5129 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
5130 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
5131 0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01,
5132 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
5133 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
5134 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
5135 0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76,
5136 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
5137 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
5138 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
5139 0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48,
5140 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08,
5141 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
5142 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
5143 0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0,
5144 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
5145 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
5146 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
5147 0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a,
5148 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
5149 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
5150 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
5151 0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03,
5152 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe,
5153 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
5154 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
5155 0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30,
5156 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16,
5157 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
5158 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
5159 0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01,
5160 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe,
5161 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
5162 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
5163 0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77,
5164 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c,
5165 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
5166 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
5167 0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40,
5168 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1,
5169 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
5170 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
5171 0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe,
5172 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
5173 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
5174 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
5175 0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5,
5176 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c,
5177 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
5178 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
5179 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19,
5180 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e,
5181 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
5182 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
5183 0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49,
5184 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f,
5185 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
5186 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
5187 0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe,
5188 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c,
5189 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
5190 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
5191 0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14,
5192 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a,
5193 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
5194 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
5195 0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe,
5196 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc,
5197 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
5198 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
5199 0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13,
5200 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56,
5201 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
5202 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
5203 0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c,
5204 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00,
5205 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
5206 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
5207 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01,
5208 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f,
5209 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
5210 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
5211 0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2,
5212 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78,
5213 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
5214 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
5215 0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00,
5216 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28,
5217 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
5218 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
5219 0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4,
5220 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe,
5221 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
5222 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
5223 0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe,
5224 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23,
5225 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
5226 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
5227 0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26,
5228 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08,
5229 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
5230 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
5231 0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44,
5232 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e,
5233 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
5234 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
5235 0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03,
5236 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01,
5237 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
5238 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
5239 0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03,
5240 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10,
5241 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
5242 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
5243 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01,
5244 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f,
5245 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
5246 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
5247 0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90,
5248 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe,
5249 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
5250 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
5251 0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
5252 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10,
5253 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
5254 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
5255 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f,
5256 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14,
5257 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
5258 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
5259 0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe,
5260 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe,
5261 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
5262 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
5263 0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17,
5264 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71,
5265 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
5266 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
5267 0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0,
5268 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
5269 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
5270 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
5271 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c,
5272 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17,
5273 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
5274 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
5275 0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73,
5276 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e,
5277 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
5278 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
5279 0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18,
5280 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2,
5281 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
5282 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
5283 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe,
5284 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12,
5285 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
5286 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
5287 0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26,
5288 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93,
5289 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
5290 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
5291 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
5292 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
5295 static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
5296 static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
5298 /* Microcode buffer is kept after initialization for error recovery. */
5299 static unsigned char _adv_asc38C0800_buf[] = {
5300 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
5301 0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19,
5302 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00,
5303 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
5304 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
5305 0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0,
5306 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc,
5307 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
5308 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
5309 0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc,
5310 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54,
5311 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
5312 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
5313 0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80,
5314 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00,
5315 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
5316 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
5317 0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0,
5318 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01,
5319 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
5320 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
5321 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
5322 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11,
5323 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
5324 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
5325 0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc,
5326 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00,
5327 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
5328 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
5329 0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17,
5330 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44,
5331 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
5332 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
5333 0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00,
5334 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00,
5335 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
5336 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
5337 0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f,
5338 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12,
5339 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
5340 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
5341 0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
5342 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10,
5343 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
5344 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
5345 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00,
5346 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5347 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
5348 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
5349 0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe,
5350 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06,
5351 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
5352 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
5353 0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe,
5354 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
5355 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
5356 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
5357 0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02,
5358 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02,
5359 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
5360 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
5361 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10,
5362 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59,
5363 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
5364 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
5365 0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0,
5366 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe,
5367 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
5368 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
5369 0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43,
5370 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54,
5371 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
5372 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
5373 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe,
5374 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02,
5375 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
5376 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
5377 0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe,
5378 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10,
5379 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
5380 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
5381 0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78,
5382 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9,
5383 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
5384 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
5385 0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a,
5386 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d,
5387 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
5388 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
5389 0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda,
5390 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28,
5391 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
5392 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
5393 0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
5394 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04,
5395 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
5396 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
5397 0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62,
5398 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52,
5399 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
5400 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
5401 0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe,
5402 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00,
5403 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
5404 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
5405 0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf,
5406 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08,
5407 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
5408 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
5409 0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe,
5410 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff,
5411 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
5412 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
5413 0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05,
5414 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab,
5415 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
5416 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
5417 0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39,
5418 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2,
5419 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
5420 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
5421 0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18,
5422 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe,
5423 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
5424 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
5425 0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01,
5426 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02,
5427 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
5428 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
5429 0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12,
5430 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2,
5431 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
5432 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
5433 0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05,
5434 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
5435 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
5436 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
5437 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01,
5438 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
5439 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
5440 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
5441 0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d,
5442 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0,
5443 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
5444 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
5445 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14,
5446 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12,
5447 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
5448 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
5449 0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe,
5450 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88,
5451 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
5452 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
5453 0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe,
5454 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b,
5455 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
5456 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
5457 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d,
5458 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08,
5459 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
5460 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
5461 0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06,
5462 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9,
5463 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
5464 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
5465 0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a,
5466 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09,
5467 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
5468 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
5469 0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58,
5470 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe,
5471 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
5472 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
5473 0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe,
5474 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76,
5475 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
5476 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
5477 0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10,
5478 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a,
5479 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
5480 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
5481 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f,
5482 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18,
5483 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
5484 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
5485 0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a,
5486 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09,
5487 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
5488 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
5489 0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a,
5490 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d,
5491 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
5492 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
5493 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe,
5494 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe,
5495 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
5496 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
5497 0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8,
5498 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40,
5499 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
5500 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
5501 0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05,
5502 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe,
5503 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
5504 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
5505 0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32,
5506 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe,
5507 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
5508 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
5509 0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
5510 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe,
5511 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
5512 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
5513 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6,
5514 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe,
5515 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
5516 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
5517 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd,
5518 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb,
5519 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
5520 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
5521 0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05,
5522 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27,
5523 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
5524 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
5525 0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6,
5526 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00,
5527 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
5528 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
5529 0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c,
5530 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe,
5531 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
5532 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
5533 0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09,
5534 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b,
5535 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
5536 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
5537 0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96,
5538 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f,
5539 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
5540 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
5541 0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c,
5542 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
5543 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
5544 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
5545 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41,
5546 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70,
5547 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
5548 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
5549 0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02,
5550 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45,
5551 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
5552 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
5553 0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09,
5554 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe,
5555 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
5556 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
5557 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe,
5558 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41,
5559 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
5560 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
5561 0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00,
5562 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
5563 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
5564 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
5565 0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01,
5566 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01,
5567 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
5568 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
5569 0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24,
5570 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03,
5571 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
5572 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
5573 0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05,
5574 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
5575 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
5576 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
5577 0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f,
5578 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01,
5579 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
5580 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
5581 0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe,
5582 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
5583 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
5584 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
5585 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe,
5586 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
5587 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
5588 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
5589 0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe,
5590 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22,
5591 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
5592 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
5593 0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b,
5594 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f,
5595 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
5596 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
5597 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe,
5598 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe,
5599 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
5600 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
5601 0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe,
5602 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7,
5603 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
5604 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
5605 0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17,
5606 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24,
5607 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
5608 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
5609 0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe,
5610 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c,
5611 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
5612 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
5613 0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01,
5614 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe,
5615 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
5616 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
5617 0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe,
5618 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a,
5619 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
5620 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
5621 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe,
5622 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50,
5623 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
5624 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
5625 0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a,
5626 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d,
5627 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
5628 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
5629 0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a,
5630 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf,
5631 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
5632 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
5633 0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06,
5634 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee,
5635 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
5636 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
5637 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01,
5638 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33,
5639 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
5640 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
5641 0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1,
5642 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15,
5643 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
5644 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
5645 0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01,
5646 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
5647 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
5648 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
5649 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
5650 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58,
5651 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
5652 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
5653 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c,
5654 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd,
5655 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
5656 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
5657 0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15,
5658 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe,
5659 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
5660 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
5661 0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83,
5662 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d,
5663 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
5664 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
5665 0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2,
5666 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90,
5667 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
5668 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
5669 0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e,
5670 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90,
5671 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
5672 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
5673 0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
5674 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16,
5675 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
5676 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
5677 0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
5678 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01,
5679 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
5680 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
5681 0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27,
5682 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d,
5683 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
5684 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
5685 0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8,
5686 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11,
5687 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
5688 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
5689 0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01,
5690 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75,
5691 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
5692 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
5693 0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04,
5694 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03,
5695 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
5696 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
5697 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79,
5698 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35,
5699 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
5700 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
5701 0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c,
5702 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe,
5703 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
5704 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
5705 0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23,
5706 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe,
5707 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
5708 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
5709 0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7,
5710 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04,
5711 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
5712 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
5713 0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2,
5714 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32,
5715 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
5716 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
5717 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11,
5718 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16,
5719 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
5720 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
5721 0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18,
5722 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73,
5723 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
5724 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
5725 0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46,
5726 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04,
5727 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
5728 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
5729 0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10,
5730 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00,
5731 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
5732 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
5733 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e,
5734 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08,
5735 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
5736 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
5737 0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09,
5738 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19,
5739 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
5740 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
5741 0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe,
5742 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0,
5743 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
5744 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
5747 static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
5748 static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
5750 /* Microcode buffer is kept after initialization for error recovery. */
5751 static unsigned char _adv_asc38C1600_buf[] = {
5752 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
5753 0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13,
5754 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff,
5755 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
5756 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
5757 0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4,
5758 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e,
5759 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
5760 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
5761 0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc,
5762 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12,
5763 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
5764 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
5765 0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4,
5766 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01,
5767 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
5768 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
5769 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
5770 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10,
5771 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
5772 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
5773 0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12,
5774 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c,
5775 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
5776 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
5777 0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00,
5778 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10,
5779 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
5780 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
5781 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7,
5782 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00,
5783 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
5784 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
5785 0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46,
5786 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6,
5787 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
5788 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
5789 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01,
5790 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01,
5791 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
5792 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
5793 0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13,
5794 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10,
5795 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
5796 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
5797 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00,
5798 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5799 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
5800 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
5801 0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe,
5802 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c,
5803 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
5804 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
5805 0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05,
5806 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1,
5807 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
5808 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
5809 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60,
5810 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52,
5811 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
5812 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
5813 0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7,
5814 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f,
5815 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
5816 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
5817 0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d,
5818 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe,
5819 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
5820 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
5821 0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec,
5822 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde,
5823 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
5824 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
5825 0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41,
5826 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03,
5827 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
5828 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
5829 0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40,
5830 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0,
5831 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
5832 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
5833 0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28,
5834 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01,
5835 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
5836 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
5837 0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe,
5838 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0,
5839 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
5840 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
5841 0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf,
5842 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a,
5843 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
5844 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
5845 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29,
5846 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00,
5847 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
5848 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
5849 0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13,
5850 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e,
5851 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
5852 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
5853 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe,
5854 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43,
5855 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
5856 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
5857 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe,
5858 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f,
5859 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
5860 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
5861 0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c,
5862 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0,
5863 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
5864 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
5865 0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe,
5866 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f,
5867 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
5868 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
5869 0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba,
5870 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2,
5871 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
5872 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
5873 0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27,
5874 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f,
5875 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
5876 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
5877 0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13,
5878 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06,
5879 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
5880 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
5881 0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13,
5882 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe,
5883 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
5884 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
5885 0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01,
5886 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15,
5887 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
5888 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
5889 0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01,
5890 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95,
5891 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
5892 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
5893 0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe,
5894 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21,
5895 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
5896 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
5897 0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00,
5898 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe,
5899 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
5900 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
5901 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe,
5902 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76,
5903 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
5904 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
5905 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00,
5906 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe,
5907 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
5908 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
5909 0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c,
5910 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08,
5911 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
5912 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
5913 0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe,
5914 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21,
5915 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
5916 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
5917 0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20,
5918 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
5919 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
5920 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
5921 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b,
5922 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12,
5923 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
5924 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
5925 0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90,
5926 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6,
5927 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
5928 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
5929 0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2,
5930 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34,
5931 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
5932 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
5933 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a,
5934 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a,
5935 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
5936 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
5937 0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d,
5938 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76,
5939 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
5940 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
5941 0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe,
5942 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b,
5943 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
5944 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
5945 0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5,
5946 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe,
5947 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
5948 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
5949 0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05,
5950 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06,
5951 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
5952 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
5953 0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42,
5954 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57,
5955 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
5956 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
5957 0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01,
5958 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c,
5959 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
5960 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
5961 0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06,
5962 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7,
5963 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
5964 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
5965 0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe,
5966 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a,
5967 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
5968 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
5969 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e,
5970 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26,
5971 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
5972 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
5973 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef,
5974 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe,
5975 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
5976 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
5977 0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18,
5978 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe,
5979 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
5980 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
5981 0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe,
5982 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe,
5983 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
5984 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
5985 0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12,
5986 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e,
5987 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
5988 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
5989 0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0,
5990 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41,
5991 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
5992 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
5993 0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01,
5994 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81,
5995 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
5996 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
5997 0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe,
5998 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00,
5999 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
6000 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
6001 0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f,
6002 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e,
6003 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
6004 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
6005 0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01,
6006 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d,
6007 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
6008 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
6009 0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
6010 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19,
6011 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
6012 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
6013 0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75,
6014 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d,
6015 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
6016 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
6017 0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e,
6018 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0,
6019 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
6020 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
6021 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe,
6022 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe,
6023 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
6024 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
6025 0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12,
6026 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe,
6027 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
6028 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
6029 0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe,
6030 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec,
6031 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
6032 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
6033 0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3,
6034 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10,
6035 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
6036 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
6037 0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13,
6038 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc,
6039 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
6040 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
6041 0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06,
6042 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83,
6043 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
6044 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
6045 0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c,
6046 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe,
6047 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
6048 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
6049 0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01,
6050 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01,
6051 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
6052 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
6053 0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64,
6054 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe,
6055 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
6056 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
6057 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03,
6058 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07,
6059 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
6060 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
6061 0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe,
6062 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13,
6063 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
6064 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
6065 0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
6066 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10,
6067 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
6068 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
6069 0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
6070 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01,
6071 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
6072 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
6073 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85,
6074 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec,
6075 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
6076 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
6077 0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee,
6078 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d,
6079 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
6080 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
6081 0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42,
6082 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a,
6083 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
6084 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
6085 0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34,
6086 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e,
6087 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
6088 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
6089 0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
6090 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa,
6091 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
6092 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
6093 0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56,
6094 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9,
6095 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
6096 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
6097 0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03,
6098 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e,
6099 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
6100 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
6101 0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13,
6102 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9,
6103 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
6104 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
6105 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d,
6106 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a,
6107 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
6108 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
6109 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45,
6110 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01,
6111 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
6112 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
6113 0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66,
6114 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56,
6115 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
6116 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
6117 0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe,
6118 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05,
6119 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
6120 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
6121 0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b,
6122 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d,
6123 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
6124 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
6125 0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17,
6126 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe,
6127 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
6128 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
6129 0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02,
6130 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30,
6131 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
6132 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
6133 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58,
6134 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01,
6135 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
6136 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
6137 0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a,
6138 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00,
6139 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
6140 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
6141 0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16,
6142 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17,
6143 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
6144 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
6145 0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d,
6146 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04,
6147 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
6148 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
6149 0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16,
6150 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64,
6151 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
6152 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
6153 0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe,
6154 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe,
6155 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
6156 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
6157 0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe,
6158 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7,
6159 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
6160 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
6161 0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9,
6162 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe,
6163 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
6164 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
6165 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01,
6166 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2,
6167 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
6168 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
6169 0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18,
6170 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe,
6171 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
6172 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
6173 0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe,
6174 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10,
6175 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
6176 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
6177 0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe,
6178 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4,
6179 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
6180 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
6181 0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01,
6182 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e,
6183 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
6184 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
6185 0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f,
6186 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
6187 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
6188 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
6189 0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f,
6190 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89,
6191 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
6192 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
6193 0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c,
6194 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e,
6195 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
6196 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
6197 0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09,
6198 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18,
6199 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
6200 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
6201 0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe,
6202 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01,
6203 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
6204 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
6205 0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c,
6206 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d,
6207 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
6208 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
6209 0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01,
6210 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe,
6211 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
6212 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
6213 0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9,
6214 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83,
6215 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
6216 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
6217 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b,
6218 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04,
6219 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
6220 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
6221 0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6,
6222 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c,
6223 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
6224 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
6225 0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83,
6226 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a,
6227 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
6228 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
6229 0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13,
6230 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1,
6231 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
6232 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
6233 0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48,
6234 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f,
6235 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
6236 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
6237 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d,
6238 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30,
6239 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
6240 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
6241 0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31,
6242 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba,
6243 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
6244 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
6245 0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89,
6246 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90,
6247 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
6248 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
6249 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe,
6250 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1,
6251 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
6252 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
6253 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa,
6254 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d,
6255 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
6256 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
6257 0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e,
6258 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99,
6259 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
6260 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
6261 0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80,
6262 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98,
6263 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
6264 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
6265 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b,
6266 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84,
6267 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
6268 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
6269 0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06,
6270 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f,
6271 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6272 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6273 0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6274 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6275 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6276 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6277 0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b,
6278 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e,
6279 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
6282 static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
6283 static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
6285 static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
6287 PortAddr iop_base;
6288 int i;
6289 ushort lram_addr;
6291 iop_base = asc_dvc->iop_base;
6292 AscPutRiscVarFreeQHead(iop_base, 1);
6293 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6294 AscPutVarFreeQHead(iop_base, 1);
6295 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6296 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
6297 (uchar)((int)asc_dvc->max_total_qng + 1));
6298 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
6299 (uchar)((int)asc_dvc->max_total_qng + 2));
6300 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
6301 asc_dvc->max_total_qng);
6302 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
6303 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6304 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
6305 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
6306 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
6307 AscPutQDoneInProgress(iop_base, 0);
6308 lram_addr = ASC_QADR_BEG;
6309 for (i = 0; i < 32; i++, lram_addr += 2) {
6310 AscWriteLramWord(iop_base, lram_addr, 0);
6314 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
6316 int i;
6317 ushort warn_code;
6318 PortAddr iop_base;
6319 ASC_PADDR phy_addr;
6320 ASC_DCNT phy_size;
6321 struct asc_board *board = asc_dvc_to_board(asc_dvc);
6323 iop_base = asc_dvc->iop_base;
6324 warn_code = 0;
6325 for (i = 0; i <= ASC_MAX_TID; i++) {
6326 AscPutMCodeInitSDTRAtID(iop_base, i,
6327 asc_dvc->cfg->sdtr_period_offset[i]);
6330 AscInitQLinkVar(asc_dvc);
6331 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
6332 asc_dvc->cfg->disc_enable);
6333 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
6334 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
6336 /* Ensure overrun buffer is aligned on an 8 byte boundary. */
6337 BUG_ON((unsigned long)asc_dvc->overrun_buf & 7);
6338 asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf,
6339 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
6340 phy_addr = cpu_to_le32(asc_dvc->overrun_dma);
6341 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
6342 (uchar *)&phy_addr, 1);
6343 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE);
6344 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
6345 (uchar *)&phy_size, 1);
6347 asc_dvc->cfg->mcode_date =
6348 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
6349 asc_dvc->cfg->mcode_version =
6350 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
6352 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
6353 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
6354 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
6355 return warn_code;
6357 if (AscStartChip(iop_base) != 1) {
6358 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
6359 return warn_code;
6362 return warn_code;
6365 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
6367 ushort warn_code;
6368 PortAddr iop_base;
6370 iop_base = asc_dvc->iop_base;
6371 warn_code = 0;
6372 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
6373 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
6374 AscResetChipAndScsiBus(asc_dvc);
6375 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
6377 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
6378 if (asc_dvc->err_code != 0)
6379 return UW_ERR;
6380 if (!AscFindSignature(asc_dvc->iop_base)) {
6381 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
6382 return warn_code;
6384 AscDisableInterrupt(iop_base);
6385 warn_code |= AscInitLram(asc_dvc);
6386 if (asc_dvc->err_code != 0)
6387 return UW_ERR;
6388 ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)_asc_mcode_chksum);
6389 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
6390 _asc_mcode_size) != _asc_mcode_chksum) {
6391 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
6392 return warn_code;
6394 warn_code |= AscInitMicroCodeVar(asc_dvc);
6395 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
6396 AscEnableInterrupt(iop_base);
6397 return warn_code;
6401 * Load the Microcode
6403 * Write the microcode image to RISC memory starting at address 0.
6405 * The microcode is stored compressed in the following format:
6407 * 254 word (508 byte) table indexed by byte code followed
6408 * by the following byte codes:
6410 * 1-Byte Code:
6411 * 00: Emit word 0 in table.
6412 * 01: Emit word 1 in table.
6414 * FD: Emit word 253 in table.
6416 * Multi-Byte Code:
6417 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
6418 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
6420 * Returns 0 or an error if the checksum doesn't match
6422 static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
6423 int memsize, int chksum)
6425 int i, j, end, len = 0;
6426 ADV_DCNT sum;
6428 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6430 for (i = 253 * 2; i < size; i++) {
6431 if (buf[i] == 0xff) {
6432 unsigned short word = (buf[i + 3] << 8) | buf[i + 2];
6433 for (j = 0; j < buf[i + 1]; j++) {
6434 AdvWriteWordAutoIncLram(iop_base, word);
6435 len += 2;
6437 i += 3;
6438 } else if (buf[i] == 0xfe) {
6439 unsigned short word = (buf[i + 2] << 8) | buf[i + 1];
6440 AdvWriteWordAutoIncLram(iop_base, word);
6441 i += 2;
6442 len += 2;
6443 } else {
6444 unsigned int off = buf[i] * 2;
6445 unsigned short word = (buf[off + 1] << 8) | buf[off];
6446 AdvWriteWordAutoIncLram(iop_base, word);
6447 len += 2;
6451 end = len;
6453 while (len < memsize) {
6454 AdvWriteWordAutoIncLram(iop_base, 0);
6455 len += 2;
6458 /* Verify the microcode checksum. */
6459 sum = 0;
6460 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6462 for (len = 0; len < end; len += 2) {
6463 sum += AdvReadWordAutoIncLram(iop_base);
6466 if (sum != chksum)
6467 return ASC_IERR_MCODE_CHKSUM;
6469 return 0;
6472 static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
6474 ADV_CARR_T *carrp;
6475 ADV_SDCNT buf_size;
6476 ADV_PADDR carr_paddr;
6478 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
6479 asc_dvc->carr_freelist = NULL;
6480 if (carrp == asc_dvc->carrier_buf) {
6481 buf_size = ADV_CARRIER_BUFSIZE;
6482 } else {
6483 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
6486 do {
6487 /* Get physical address of the carrier 'carrp'. */
6488 carr_paddr = cpu_to_le32(virt_to_bus(carrp));
6490 buf_size -= sizeof(ADV_CARR_T);
6492 carrp->carr_pa = carr_paddr;
6493 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
6496 * Insert the carrier at the beginning of the freelist.
6498 carrp->next_vpa =
6499 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
6500 asc_dvc->carr_freelist = carrp;
6502 carrp++;
6503 } while (buf_size > 0);
6507 * Send an idle command to the chip and wait for completion.
6509 * Command completion is polled for once per microsecond.
6511 * The function can be called from anywhere including an interrupt handler.
6512 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
6513 * functions to prevent reentrancy.
6515 * Return Values:
6516 * ADV_TRUE - command completed successfully
6517 * ADV_FALSE - command failed
6518 * ADV_ERROR - command timed out
6520 static int
6521 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
6522 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
6524 int result;
6525 ADV_DCNT i, j;
6526 AdvPortAddr iop_base;
6528 iop_base = asc_dvc->iop_base;
6531 * Clear the idle command status which is set by the microcode
6532 * to a non-zero value to indicate when the command is completed.
6533 * The non-zero result is one of the IDLE_CMD_STATUS_* values
6535 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
6538 * Write the idle command value after the idle command parameter
6539 * has been written to avoid a race condition. If the order is not
6540 * followed, the microcode may process the idle command before the
6541 * parameters have been written to LRAM.
6543 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
6544 cpu_to_le32(idle_cmd_parameter));
6545 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
6548 * Tickle the RISC to tell it to process the idle command.
6550 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
6551 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
6553 * Clear the tickle value. In the ASC-3550 the RISC flag
6554 * command 'clr_tickle_b' does not work unless the host
6555 * value is cleared.
6557 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
6560 /* Wait for up to 100 millisecond for the idle command to timeout. */
6561 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
6562 /* Poll once each microsecond for command completion. */
6563 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
6564 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
6565 result);
6566 if (result != 0)
6567 return result;
6568 udelay(1);
6572 BUG(); /* The idle command should never timeout. */
6573 return ADV_ERROR;
6577 * Reset SCSI Bus and purge all outstanding requests.
6579 * Return Value:
6580 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
6581 * ADV_FALSE(0) - Microcode command failed.
6582 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
6583 * may be hung which requires driver recovery.
6585 static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
6587 int status;
6590 * Send the SCSI Bus Reset idle start idle command which asserts
6591 * the SCSI Bus Reset signal.
6593 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
6594 if (status != ADV_TRUE) {
6595 return status;
6599 * Delay for the specified SCSI Bus Reset hold time.
6601 * The hold time delay is done on the host because the RISC has no
6602 * microsecond accurate timer.
6604 udelay(ASC_SCSI_RESET_HOLD_TIME_US);
6607 * Send the SCSI Bus Reset end idle command which de-asserts
6608 * the SCSI Bus Reset signal and purges any pending requests.
6610 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
6611 if (status != ADV_TRUE) {
6612 return status;
6615 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
6617 return status;
6621 * Initialize the ASC-3550.
6623 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
6625 * For a non-fatal error return a warning code. If there are no warnings
6626 * then 0 is returned.
6628 * Needed after initialization for error recovery.
6630 static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
6632 AdvPortAddr iop_base;
6633 ushort warn_code;
6634 int begin_addr;
6635 int end_addr;
6636 ushort code_sum;
6637 int word;
6638 int i;
6639 ushort scsi_cfg1;
6640 uchar tid;
6641 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
6642 ushort wdtr_able = 0, sdtr_able, tagqng_able;
6643 uchar max_cmd[ADV_MAX_TID + 1];
6645 /* If there is already an error, don't continue. */
6646 if (asc_dvc->err_code != 0)
6647 return ADV_ERROR;
6650 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
6652 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
6653 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
6654 return ADV_ERROR;
6657 warn_code = 0;
6658 iop_base = asc_dvc->iop_base;
6661 * Save the RISC memory BIOS region before writing the microcode.
6662 * The BIOS may already be loaded and using its RISC LRAM region
6663 * so its region must be saved and restored.
6665 * Note: This code makes the assumption, which is currently true,
6666 * that a chip reset does not clear RISC LRAM.
6668 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6669 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6670 bios_mem[i]);
6674 * Save current per TID negotiated values.
6676 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
6677 ushort bios_version, major, minor;
6679 bios_version =
6680 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
6681 major = (bios_version >> 12) & 0xF;
6682 minor = (bios_version >> 8) & 0xF;
6683 if (major < 3 || (major == 3 && minor == 1)) {
6684 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
6685 AdvReadWordLram(iop_base, 0x120, wdtr_able);
6686 } else {
6687 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
6690 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
6691 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6692 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
6693 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
6694 max_cmd[tid]);
6697 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf,
6698 _adv_asc3550_size, ADV_3550_MEMSIZE,
6699 _adv_asc3550_chksum);
6700 if (asc_dvc->err_code)
6701 return ADV_ERROR;
6704 * Restore the RISC memory BIOS region.
6706 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6707 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6708 bios_mem[i]);
6712 * Calculate and write the microcode code checksum to the microcode
6713 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
6715 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
6716 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
6717 code_sum = 0;
6718 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
6719 for (word = begin_addr; word < end_addr; word += 2) {
6720 code_sum += AdvReadWordAutoIncLram(iop_base);
6722 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
6725 * Read and save microcode version and date.
6727 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
6728 asc_dvc->cfg->mcode_date);
6729 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
6730 asc_dvc->cfg->mcode_version);
6733 * Set the chip type to indicate the ASC3550.
6735 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
6738 * If the PCI Configuration Command Register "Parity Error Response
6739 * Control" Bit was clear (0), then set the microcode variable
6740 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
6741 * to ignore DMA parity errors.
6743 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
6744 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
6745 word |= CONTROL_FLAG_IGNORE_PERR;
6746 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
6750 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
6751 * threshold of 128 bytes. This register is only accessible to the host.
6753 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
6754 START_CTL_EMFU | READ_CMD_MRM);
6757 * Microcode operating variables for WDTR, SDTR, and command tag
6758 * queuing will be set in slave_configure() based on what a
6759 * device reports it is capable of in Inquiry byte 7.
6761 * If SCSI Bus Resets have been disabled, then directly set
6762 * SDTR and WDTR from the EEPROM configuration. This will allow
6763 * the BIOS and warm boot to work without a SCSI bus hang on
6764 * the Inquiry caused by host and target mismatched DTR values.
6765 * Without the SCSI Bus Reset, before an Inquiry a device can't
6766 * be assumed to be in Asynchronous, Narrow mode.
6768 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
6769 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
6770 asc_dvc->wdtr_able);
6771 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
6772 asc_dvc->sdtr_able);
6776 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
6777 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
6778 * bitmask. These values determine the maximum SDTR speed negotiated
6779 * with a device.
6781 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
6782 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
6783 * without determining here whether the device supports SDTR.
6785 * 4-bit speed SDTR speed name
6786 * =========== ===============
6787 * 0000b (0x0) SDTR disabled
6788 * 0001b (0x1) 5 Mhz
6789 * 0010b (0x2) 10 Mhz
6790 * 0011b (0x3) 20 Mhz (Ultra)
6791 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
6792 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
6793 * 0110b (0x6) Undefined
6795 * 1111b (0xF) Undefined
6797 word = 0;
6798 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
6799 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
6800 /* Set Ultra speed for TID 'tid'. */
6801 word |= (0x3 << (4 * (tid % 4)));
6802 } else {
6803 /* Set Fast speed for TID 'tid'. */
6804 word |= (0x2 << (4 * (tid % 4)));
6806 if (tid == 3) { /* Check if done with sdtr_speed1. */
6807 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
6808 word = 0;
6809 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
6810 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
6811 word = 0;
6812 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
6813 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
6814 word = 0;
6815 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
6816 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
6817 /* End of loop. */
6822 * Set microcode operating variable for the disconnect per TID bitmask.
6824 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
6825 asc_dvc->cfg->disc_enable);
6828 * Set SCSI_CFG0 Microcode Default Value.
6830 * The microcode will set the SCSI_CFG0 register using this value
6831 * after it is started below.
6833 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
6834 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
6835 asc_dvc->chip_scsi_id);
6838 * Determine SCSI_CFG1 Microcode Default Value.
6840 * The microcode will set the SCSI_CFG1 register using this value
6841 * after it is started below.
6844 /* Read current SCSI_CFG1 Register value. */
6845 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
6848 * If all three connectors are in use, return an error.
6850 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
6851 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
6852 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
6853 return ADV_ERROR;
6857 * If the internal narrow cable is reversed all of the SCSI_CTRL
6858 * register signals will be set. Check for and return an error if
6859 * this condition is found.
6861 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
6862 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
6863 return ADV_ERROR;
6867 * If this is a differential board and a single-ended device
6868 * is attached to one of the connectors, return an error.
6870 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
6871 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
6872 return ADV_ERROR;
6876 * If automatic termination control is enabled, then set the
6877 * termination value based on a table listed in a_condor.h.
6879 * If manual termination was specified with an EEPROM setting
6880 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
6881 * is ready to be 'ored' into SCSI_CFG1.
6883 if (asc_dvc->cfg->termination == 0) {
6885 * The software always controls termination by setting TERM_CTL_SEL.
6886 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
6888 asc_dvc->cfg->termination |= TERM_CTL_SEL;
6890 switch (scsi_cfg1 & CABLE_DETECT) {
6891 /* TERM_CTL_H: on, TERM_CTL_L: on */
6892 case 0x3:
6893 case 0x7:
6894 case 0xB:
6895 case 0xD:
6896 case 0xE:
6897 case 0xF:
6898 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
6899 break;
6901 /* TERM_CTL_H: on, TERM_CTL_L: off */
6902 case 0x1:
6903 case 0x5:
6904 case 0x9:
6905 case 0xA:
6906 case 0xC:
6907 asc_dvc->cfg->termination |= TERM_CTL_H;
6908 break;
6910 /* TERM_CTL_H: off, TERM_CTL_L: off */
6911 case 0x2:
6912 case 0x6:
6913 break;
6918 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
6920 scsi_cfg1 &= ~TERM_CTL;
6923 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
6924 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
6925 * referenced, because the hardware internally inverts
6926 * the Termination High and Low bits if TERM_POL is set.
6928 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
6931 * Set SCSI_CFG1 Microcode Default Value
6933 * Set filter value and possibly modified termination control
6934 * bits in the Microcode SCSI_CFG1 Register Value.
6936 * The microcode will set the SCSI_CFG1 register using this value
6937 * after it is started below.
6939 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
6940 FLTR_DISABLE | scsi_cfg1);
6943 * Set MEM_CFG Microcode Default Value
6945 * The microcode will set the MEM_CFG register using this value
6946 * after it is started below.
6948 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
6949 * are defined.
6951 * ASC-3550 has 8KB internal memory.
6953 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
6954 BIOS_EN | RAM_SZ_8KB);
6957 * Set SEL_MASK Microcode Default Value
6959 * The microcode will set the SEL_MASK register using this value
6960 * after it is started below.
6962 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
6963 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
6965 AdvBuildCarrierFreelist(asc_dvc);
6968 * Set-up the Host->RISC Initiator Command Queue (ICQ).
6971 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
6972 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
6973 return ADV_ERROR;
6975 asc_dvc->carr_freelist = (ADV_CARR_T *)
6976 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
6979 * The first command issued will be placed in the stopper carrier.
6981 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
6984 * Set RISC ICQ physical address start value.
6986 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
6989 * Set-up the RISC->Host Initiator Response Queue (IRQ).
6991 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
6992 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
6993 return ADV_ERROR;
6995 asc_dvc->carr_freelist = (ADV_CARR_T *)
6996 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
6999 * The first command completed by the RISC will be placed in
7000 * the stopper.
7002 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7003 * completed the RISC will set the ASC_RQ_STOPPER bit.
7005 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7008 * Set RISC IRQ physical address start value.
7010 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7011 asc_dvc->carr_pending_cnt = 0;
7013 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7014 (ADV_INTR_ENABLE_HOST_INTR |
7015 ADV_INTR_ENABLE_GLOBAL_INTR));
7017 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7018 AdvWriteWordRegister(iop_base, IOPW_PC, word);
7020 /* finally, finally, gentlemen, start your engine */
7021 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7024 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7025 * Resets should be performed. The RISC has to be running
7026 * to issue a SCSI Bus Reset.
7028 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7030 * If the BIOS Signature is present in memory, restore the
7031 * BIOS Handshake Configuration Table and do not perform
7032 * a SCSI Bus Reset.
7034 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7035 0x55AA) {
7037 * Restore per TID negotiated values.
7039 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7040 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7041 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7042 tagqng_able);
7043 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7044 AdvWriteByteLram(iop_base,
7045 ASC_MC_NUMBER_OF_MAX_CMD + tid,
7046 max_cmd[tid]);
7048 } else {
7049 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7050 warn_code = ASC_WARN_BUSRESET_ERROR;
7055 return warn_code;
7059 * Initialize the ASC-38C0800.
7061 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
7063 * For a non-fatal error return a warning code. If there are no warnings
7064 * then 0 is returned.
7066 * Needed after initialization for error recovery.
7068 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
7070 AdvPortAddr iop_base;
7071 ushort warn_code;
7072 int begin_addr;
7073 int end_addr;
7074 ushort code_sum;
7075 int word;
7076 int i;
7077 ushort scsi_cfg1;
7078 uchar byte;
7079 uchar tid;
7080 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
7081 ushort wdtr_able, sdtr_able, tagqng_able;
7082 uchar max_cmd[ADV_MAX_TID + 1];
7084 /* If there is already an error, don't continue. */
7085 if (asc_dvc->err_code != 0)
7086 return ADV_ERROR;
7089 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
7091 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
7092 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7093 return ADV_ERROR;
7096 warn_code = 0;
7097 iop_base = asc_dvc->iop_base;
7100 * Save the RISC memory BIOS region before writing the microcode.
7101 * The BIOS may already be loaded and using its RISC LRAM region
7102 * so its region must be saved and restored.
7104 * Note: This code makes the assumption, which is currently true,
7105 * that a chip reset does not clear RISC LRAM.
7107 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7108 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7109 bios_mem[i]);
7113 * Save current per TID negotiated values.
7115 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7116 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7117 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7118 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7119 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
7120 max_cmd[tid]);
7124 * RAM BIST (RAM Built-In Self Test)
7126 * Address : I/O base + offset 0x38h register (byte).
7127 * Function: Bit 7-6(RW) : RAM mode
7128 * Normal Mode : 0x00
7129 * Pre-test Mode : 0x40
7130 * RAM Test Mode : 0x80
7131 * Bit 5 : unused
7132 * Bit 4(RO) : Done bit
7133 * Bit 3-0(RO) : Status
7134 * Host Error : 0x08
7135 * Int_RAM Error : 0x04
7136 * RISC Error : 0x02
7137 * SCSI Error : 0x01
7138 * No Error : 0x00
7140 * Note: RAM BIST code should be put right here, before loading the
7141 * microcode and after saving the RISC memory BIOS region.
7145 * LRAM Pre-test
7147 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
7148 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
7149 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
7150 * to NORMAL_MODE, return an error too.
7152 for (i = 0; i < 2; i++) {
7153 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
7154 mdelay(10); /* Wait for 10ms before reading back. */
7155 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7156 if ((byte & RAM_TEST_DONE) == 0
7157 || (byte & 0x0F) != PRE_TEST_VALUE) {
7158 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7159 return ADV_ERROR;
7162 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7163 mdelay(10); /* Wait for 10ms before reading back. */
7164 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
7165 != NORMAL_VALUE) {
7166 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7167 return ADV_ERROR;
7172 * LRAM Test - It takes about 1.5 ms to run through the test.
7174 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
7175 * If Done bit not set or Status not 0, save register byte, set the
7176 * err_code, and return an error.
7178 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7179 mdelay(10); /* Wait for 10ms before checking status. */
7181 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7182 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
7183 /* Get here if Done bit not set or Status not 0. */
7184 asc_dvc->bist_err_code = byte; /* for BIOS display message */
7185 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
7186 return ADV_ERROR;
7189 /* We need to reset back to normal mode after LRAM test passes. */
7190 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7192 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf,
7193 _adv_asc38C0800_size, ADV_38C0800_MEMSIZE,
7194 _adv_asc38C0800_chksum);
7195 if (asc_dvc->err_code)
7196 return ADV_ERROR;
7199 * Restore the RISC memory BIOS region.
7201 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7202 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7203 bios_mem[i]);
7207 * Calculate and write the microcode code checksum to the microcode
7208 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7210 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
7211 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
7212 code_sum = 0;
7213 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
7214 for (word = begin_addr; word < end_addr; word += 2) {
7215 code_sum += AdvReadWordAutoIncLram(iop_base);
7217 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7220 * Read microcode version and date.
7222 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
7223 asc_dvc->cfg->mcode_date);
7224 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
7225 asc_dvc->cfg->mcode_version);
7228 * Set the chip type to indicate the ASC38C0800.
7230 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
7233 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
7234 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
7235 * cable detection and then we are able to read C_DET[3:0].
7237 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7238 * Microcode Default Value' section below.
7240 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7241 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7242 scsi_cfg1 | DIS_TERM_DRV);
7245 * If the PCI Configuration Command Register "Parity Error Response
7246 * Control" Bit was clear (0), then set the microcode variable
7247 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
7248 * to ignore DMA parity errors.
7250 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
7251 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7252 word |= CONTROL_FLAG_IGNORE_PERR;
7253 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7257 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
7258 * bits for the default FIFO threshold.
7260 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
7262 * For DMA Errata #4 set the BC_THRESH_ENB bit.
7264 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7265 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
7266 READ_CMD_MRM);
7269 * Microcode operating variables for WDTR, SDTR, and command tag
7270 * queuing will be set in slave_configure() based on what a
7271 * device reports it is capable of in Inquiry byte 7.
7273 * If SCSI Bus Resets have been disabled, then directly set
7274 * SDTR and WDTR from the EEPROM configuration. This will allow
7275 * the BIOS and warm boot to work without a SCSI bus hang on
7276 * the Inquiry caused by host and target mismatched DTR values.
7277 * Without the SCSI Bus Reset, before an Inquiry a device can't
7278 * be assumed to be in Asynchronous, Narrow mode.
7280 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
7281 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
7282 asc_dvc->wdtr_able);
7283 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
7284 asc_dvc->sdtr_able);
7288 * Set microcode operating variables for DISC and SDTR_SPEED1,
7289 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
7290 * configuration values.
7292 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
7293 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7294 * without determining here whether the device supports SDTR.
7296 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
7297 asc_dvc->cfg->disc_enable);
7298 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
7299 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
7300 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
7301 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
7304 * Set SCSI_CFG0 Microcode Default Value.
7306 * The microcode will set the SCSI_CFG0 register using this value
7307 * after it is started below.
7309 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
7310 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
7311 asc_dvc->chip_scsi_id);
7314 * Determine SCSI_CFG1 Microcode Default Value.
7316 * The microcode will set the SCSI_CFG1 register using this value
7317 * after it is started below.
7320 /* Read current SCSI_CFG1 Register value. */
7321 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7324 * If the internal narrow cable is reversed all of the SCSI_CTRL
7325 * register signals will be set. Check for and return an error if
7326 * this condition is found.
7328 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7329 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7330 return ADV_ERROR;
7334 * All kind of combinations of devices attached to one of four
7335 * connectors are acceptable except HVD device attached. For example,
7336 * LVD device can be attached to SE connector while SE device attached
7337 * to LVD connector. If LVD device attached to SE connector, it only
7338 * runs up to Ultra speed.
7340 * If an HVD device is attached to one of LVD connectors, return an
7341 * error. However, there is no way to detect HVD device attached to
7342 * SE connectors.
7344 if (scsi_cfg1 & HVD) {
7345 asc_dvc->err_code = ASC_IERR_HVD_DEVICE;
7346 return ADV_ERROR;
7350 * If either SE or LVD automatic termination control is enabled, then
7351 * set the termination value based on a table listed in a_condor.h.
7353 * If manual termination was specified with an EEPROM setting then
7354 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready
7355 * to be 'ored' into SCSI_CFG1.
7357 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
7358 /* SE automatic termination control is enabled. */
7359 switch (scsi_cfg1 & C_DET_SE) {
7360 /* TERM_SE_HI: on, TERM_SE_LO: on */
7361 case 0x1:
7362 case 0x2:
7363 case 0x3:
7364 asc_dvc->cfg->termination |= TERM_SE;
7365 break;
7367 /* TERM_SE_HI: on, TERM_SE_LO: off */
7368 case 0x0:
7369 asc_dvc->cfg->termination |= TERM_SE_HI;
7370 break;
7374 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
7375 /* LVD automatic termination control is enabled. */
7376 switch (scsi_cfg1 & C_DET_LVD) {
7377 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
7378 case 0x4:
7379 case 0x8:
7380 case 0xC:
7381 asc_dvc->cfg->termination |= TERM_LVD;
7382 break;
7384 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
7385 case 0x0:
7386 break;
7391 * Clear any set TERM_SE and TERM_LVD bits.
7393 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
7396 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
7398 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
7401 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE
7402 * bits and set possibly modified termination control bits in the
7403 * Microcode SCSI_CFG1 Register Value.
7405 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
7408 * Set SCSI_CFG1 Microcode Default Value
7410 * Set possibly modified termination control and reset DIS_TERM_DRV
7411 * bits in the Microcode SCSI_CFG1 Register Value.
7413 * The microcode will set the SCSI_CFG1 register using this value
7414 * after it is started below.
7416 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
7419 * Set MEM_CFG Microcode Default Value
7421 * The microcode will set the MEM_CFG register using this value
7422 * after it is started below.
7424 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7425 * are defined.
7427 * ASC-38C0800 has 16KB internal memory.
7429 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7430 BIOS_EN | RAM_SZ_16KB);
7433 * Set SEL_MASK Microcode Default Value
7435 * The microcode will set the SEL_MASK register using this value
7436 * after it is started below.
7438 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7439 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7441 AdvBuildCarrierFreelist(asc_dvc);
7444 * Set-up the Host->RISC Initiator Command Queue (ICQ).
7447 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7448 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7449 return ADV_ERROR;
7451 asc_dvc->carr_freelist = (ADV_CARR_T *)
7452 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7455 * The first command issued will be placed in the stopper carrier.
7457 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7460 * Set RISC ICQ physical address start value.
7461 * carr_pa is LE, must be native before write
7463 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7466 * Set-up the RISC->Host Initiator Response Queue (IRQ).
7468 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7469 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7470 return ADV_ERROR;
7472 asc_dvc->carr_freelist = (ADV_CARR_T *)
7473 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7476 * The first command completed by the RISC will be placed in
7477 * the stopper.
7479 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7480 * completed the RISC will set the ASC_RQ_STOPPER bit.
7482 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7485 * Set RISC IRQ physical address start value.
7487 * carr_pa is LE, must be native before write *
7489 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7490 asc_dvc->carr_pending_cnt = 0;
7492 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7493 (ADV_INTR_ENABLE_HOST_INTR |
7494 ADV_INTR_ENABLE_GLOBAL_INTR));
7496 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7497 AdvWriteWordRegister(iop_base, IOPW_PC, word);
7499 /* finally, finally, gentlemen, start your engine */
7500 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7503 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7504 * Resets should be performed. The RISC has to be running
7505 * to issue a SCSI Bus Reset.
7507 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7509 * If the BIOS Signature is present in memory, restore the
7510 * BIOS Handshake Configuration Table and do not perform
7511 * a SCSI Bus Reset.
7513 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7514 0x55AA) {
7516 * Restore per TID negotiated values.
7518 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7519 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7520 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7521 tagqng_able);
7522 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7523 AdvWriteByteLram(iop_base,
7524 ASC_MC_NUMBER_OF_MAX_CMD + tid,
7525 max_cmd[tid]);
7527 } else {
7528 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7529 warn_code = ASC_WARN_BUSRESET_ERROR;
7534 return warn_code;
7538 * Initialize the ASC-38C1600.
7540 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
7542 * For a non-fatal error return a warning code. If there are no warnings
7543 * then 0 is returned.
7545 * Needed after initialization for error recovery.
7547 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
7549 AdvPortAddr iop_base;
7550 ushort warn_code;
7551 int begin_addr;
7552 int end_addr;
7553 ushort code_sum;
7554 long word;
7555 int i;
7556 ushort scsi_cfg1;
7557 uchar byte;
7558 uchar tid;
7559 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
7560 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
7561 uchar max_cmd[ASC_MAX_TID + 1];
7563 /* If there is already an error, don't continue. */
7564 if (asc_dvc->err_code != 0) {
7565 return ADV_ERROR;
7569 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
7571 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
7572 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7573 return ADV_ERROR;
7576 warn_code = 0;
7577 iop_base = asc_dvc->iop_base;
7580 * Save the RISC memory BIOS region before writing the microcode.
7581 * The BIOS may already be loaded and using its RISC LRAM region
7582 * so its region must be saved and restored.
7584 * Note: This code makes the assumption, which is currently true,
7585 * that a chip reset does not clear RISC LRAM.
7587 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7588 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7589 bios_mem[i]);
7593 * Save current per TID negotiated values.
7595 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7596 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7597 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
7598 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7599 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
7600 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
7601 max_cmd[tid]);
7605 * RAM BIST (Built-In Self Test)
7607 * Address : I/O base + offset 0x38h register (byte).
7608 * Function: Bit 7-6(RW) : RAM mode
7609 * Normal Mode : 0x00
7610 * Pre-test Mode : 0x40
7611 * RAM Test Mode : 0x80
7612 * Bit 5 : unused
7613 * Bit 4(RO) : Done bit
7614 * Bit 3-0(RO) : Status
7615 * Host Error : 0x08
7616 * Int_RAM Error : 0x04
7617 * RISC Error : 0x02
7618 * SCSI Error : 0x01
7619 * No Error : 0x00
7621 * Note: RAM BIST code should be put right here, before loading the
7622 * microcode and after saving the RISC memory BIOS region.
7626 * LRAM Pre-test
7628 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
7629 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
7630 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
7631 * to NORMAL_MODE, return an error too.
7633 for (i = 0; i < 2; i++) {
7634 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
7635 mdelay(10); /* Wait for 10ms before reading back. */
7636 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7637 if ((byte & RAM_TEST_DONE) == 0
7638 || (byte & 0x0F) != PRE_TEST_VALUE) {
7639 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7640 return ADV_ERROR;
7643 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7644 mdelay(10); /* Wait for 10ms before reading back. */
7645 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
7646 != NORMAL_VALUE) {
7647 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7648 return ADV_ERROR;
7653 * LRAM Test - It takes about 1.5 ms to run through the test.
7655 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
7656 * If Done bit not set or Status not 0, save register byte, set the
7657 * err_code, and return an error.
7659 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7660 mdelay(10); /* Wait for 10ms before checking status. */
7662 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7663 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
7664 /* Get here if Done bit not set or Status not 0. */
7665 asc_dvc->bist_err_code = byte; /* for BIOS display message */
7666 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
7667 return ADV_ERROR;
7670 /* We need to reset back to normal mode after LRAM test passes. */
7671 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7673 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf,
7674 _adv_asc38C1600_size, ADV_38C1600_MEMSIZE,
7675 _adv_asc38C1600_chksum);
7676 if (asc_dvc->err_code)
7677 return ADV_ERROR;
7680 * Restore the RISC memory BIOS region.
7682 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7683 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7684 bios_mem[i]);
7688 * Calculate and write the microcode code checksum to the microcode
7689 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7691 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
7692 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
7693 code_sum = 0;
7694 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
7695 for (word = begin_addr; word < end_addr; word += 2) {
7696 code_sum += AdvReadWordAutoIncLram(iop_base);
7698 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7701 * Read microcode version and date.
7703 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
7704 asc_dvc->cfg->mcode_date);
7705 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
7706 asc_dvc->cfg->mcode_version);
7709 * Set the chip type to indicate the ASC38C1600.
7711 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
7714 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
7715 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
7716 * cable detection and then we are able to read C_DET[3:0].
7718 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7719 * Microcode Default Value' section below.
7721 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7722 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7723 scsi_cfg1 | DIS_TERM_DRV);
7726 * If the PCI Configuration Command Register "Parity Error Response
7727 * Control" Bit was clear (0), then set the microcode variable
7728 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
7729 * to ignore DMA parity errors.
7731 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
7732 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7733 word |= CONTROL_FLAG_IGNORE_PERR;
7734 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7738 * If the BIOS control flag AIPP (Asynchronous Information
7739 * Phase Protection) disable bit is not set, then set the firmware
7740 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
7741 * AIPP checking and encoding.
7743 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
7744 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7745 word |= CONTROL_FLAG_ENABLE_AIPP;
7746 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7750 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
7751 * and START_CTL_TH [3:2].
7753 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7754 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
7757 * Microcode operating variables for WDTR, SDTR, and command tag
7758 * queuing will be set in slave_configure() based on what a
7759 * device reports it is capable of in Inquiry byte 7.
7761 * If SCSI Bus Resets have been disabled, then directly set
7762 * SDTR and WDTR from the EEPROM configuration. This will allow
7763 * the BIOS and warm boot to work without a SCSI bus hang on
7764 * the Inquiry caused by host and target mismatched DTR values.
7765 * Without the SCSI Bus Reset, before an Inquiry a device can't
7766 * be assumed to be in Asynchronous, Narrow mode.
7768 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
7769 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
7770 asc_dvc->wdtr_able);
7771 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
7772 asc_dvc->sdtr_able);
7776 * Set microcode operating variables for DISC and SDTR_SPEED1,
7777 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
7778 * configuration values.
7780 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
7781 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7782 * without determining here whether the device supports SDTR.
7784 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
7785 asc_dvc->cfg->disc_enable);
7786 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
7787 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
7788 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
7789 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
7792 * Set SCSI_CFG0 Microcode Default Value.
7794 * The microcode will set the SCSI_CFG0 register using this value
7795 * after it is started below.
7797 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
7798 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
7799 asc_dvc->chip_scsi_id);
7802 * Calculate SCSI_CFG1 Microcode Default Value.
7804 * The microcode will set the SCSI_CFG1 register using this value
7805 * after it is started below.
7807 * Each ASC-38C1600 function has only two cable detect bits.
7808 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
7810 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7813 * If the cable is reversed all of the SCSI_CTRL register signals
7814 * will be set. Check for and return an error if this condition is
7815 * found.
7817 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7818 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7819 return ADV_ERROR;
7823 * Each ASC-38C1600 function has two connectors. Only an HVD device
7824 * can not be connected to either connector. An LVD device or SE device
7825 * may be connected to either connecor. If an SE device is connected,
7826 * then at most Ultra speed (20 Mhz) can be used on both connectors.
7828 * If an HVD device is attached, return an error.
7830 if (scsi_cfg1 & HVD) {
7831 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
7832 return ADV_ERROR;
7836 * Each function in the ASC-38C1600 uses only the SE cable detect and
7837 * termination because there are two connectors for each function. Each
7838 * function may use either LVD or SE mode. Corresponding the SE automatic
7839 * termination control EEPROM bits are used for each function. Each
7840 * function has its own EEPROM. If SE automatic control is enabled for
7841 * the function, then set the termination value based on a table listed
7842 * in a_condor.h.
7844 * If manual termination is specified in the EEPROM for the function,
7845 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
7846 * ready to be 'ored' into SCSI_CFG1.
7848 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
7849 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
7850 /* SE automatic termination control is enabled. */
7851 switch (scsi_cfg1 & C_DET_SE) {
7852 /* TERM_SE_HI: on, TERM_SE_LO: on */
7853 case 0x1:
7854 case 0x2:
7855 case 0x3:
7856 asc_dvc->cfg->termination |= TERM_SE;
7857 break;
7859 case 0x0:
7860 if (PCI_FUNC(pdev->devfn) == 0) {
7861 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
7862 } else {
7863 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
7864 asc_dvc->cfg->termination |= TERM_SE_HI;
7866 break;
7871 * Clear any set TERM_SE bits.
7873 scsi_cfg1 &= ~TERM_SE;
7876 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
7878 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
7881 * Clear Big Endian and Terminator Polarity bits and set possibly
7882 * modified termination control bits in the Microcode SCSI_CFG1
7883 * Register Value.
7885 * Big Endian bit is not used even on big endian machines.
7887 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
7890 * Set SCSI_CFG1 Microcode Default Value
7892 * Set possibly modified termination control bits in the Microcode
7893 * SCSI_CFG1 Register Value.
7895 * The microcode will set the SCSI_CFG1 register using this value
7896 * after it is started below.
7898 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
7901 * Set MEM_CFG Microcode Default Value
7903 * The microcode will set the MEM_CFG register using this value
7904 * after it is started below.
7906 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7907 * are defined.
7909 * ASC-38C1600 has 32KB internal memory.
7911 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
7912 * out a special 16K Adv Library and Microcode version. After the issue
7913 * resolved, we should turn back to the 32K support. Both a_condor.h and
7914 * mcode.sas files also need to be updated.
7916 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7917 * BIOS_EN | RAM_SZ_32KB);
7919 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7920 BIOS_EN | RAM_SZ_16KB);
7923 * Set SEL_MASK Microcode Default Value
7925 * The microcode will set the SEL_MASK register using this value
7926 * after it is started below.
7928 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7929 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7931 AdvBuildCarrierFreelist(asc_dvc);
7934 * Set-up the Host->RISC Initiator Command Queue (ICQ).
7936 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7937 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7938 return ADV_ERROR;
7940 asc_dvc->carr_freelist = (ADV_CARR_T *)
7941 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7944 * The first command issued will be placed in the stopper carrier.
7946 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7949 * Set RISC ICQ physical address start value. Initialize the
7950 * COMMA register to the same value otherwise the RISC will
7951 * prematurely detect a command is available.
7953 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7954 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
7955 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
7958 * Set-up the RISC->Host Initiator Response Queue (IRQ).
7960 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7961 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7962 return ADV_ERROR;
7964 asc_dvc->carr_freelist = (ADV_CARR_T *)
7965 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7968 * The first command completed by the RISC will be placed in
7969 * the stopper.
7971 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7972 * completed the RISC will set the ASC_RQ_STOPPER bit.
7974 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7977 * Set RISC IRQ physical address start value.
7979 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7980 asc_dvc->carr_pending_cnt = 0;
7982 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7983 (ADV_INTR_ENABLE_HOST_INTR |
7984 ADV_INTR_ENABLE_GLOBAL_INTR));
7985 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7986 AdvWriteWordRegister(iop_base, IOPW_PC, word);
7988 /* finally, finally, gentlemen, start your engine */
7989 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7992 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7993 * Resets should be performed. The RISC has to be running
7994 * to issue a SCSI Bus Reset.
7996 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7998 * If the BIOS Signature is present in memory, restore the
7999 * per TID microcode operating variables.
8001 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
8002 0x55AA) {
8004 * Restore per TID negotiated values.
8006 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8007 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8008 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8009 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
8010 tagqng_able);
8011 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
8012 AdvWriteByteLram(iop_base,
8013 ASC_MC_NUMBER_OF_MAX_CMD + tid,
8014 max_cmd[tid]);
8016 } else {
8017 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
8018 warn_code = ASC_WARN_BUSRESET_ERROR;
8023 return warn_code;
8027 * Reset chip and SCSI Bus.
8029 * Return Value:
8030 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
8031 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
8033 static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
8035 int status;
8036 ushort wdtr_able, sdtr_able, tagqng_able;
8037 ushort ppr_able = 0;
8038 uchar tid, max_cmd[ADV_MAX_TID + 1];
8039 AdvPortAddr iop_base;
8040 ushort bios_sig;
8042 iop_base = asc_dvc->iop_base;
8045 * Save current per TID negotiated values.
8047 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8048 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8049 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8050 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8052 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8053 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
8054 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
8055 max_cmd[tid]);
8059 * Force the AdvInitAsc3550/38C0800Driver() function to
8060 * perform a SCSI Bus Reset by clearing the BIOS signature word.
8061 * The initialization functions assumes a SCSI Bus Reset is not
8062 * needed if the BIOS signature word is present.
8064 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8065 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
8068 * Stop chip and reset it.
8070 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
8071 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
8072 mdelay(100);
8073 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
8074 ADV_CTRL_REG_CMD_WR_IO_REG);
8077 * Reset Adv Library error code, if any, and try
8078 * re-initializing the chip.
8080 asc_dvc->err_code = 0;
8081 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8082 status = AdvInitAsc38C1600Driver(asc_dvc);
8083 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8084 status = AdvInitAsc38C0800Driver(asc_dvc);
8085 } else {
8086 status = AdvInitAsc3550Driver(asc_dvc);
8089 /* Translate initialization return value to status value. */
8090 if (status == 0) {
8091 status = ADV_TRUE;
8092 } else {
8093 status = ADV_FALSE;
8097 * Restore the BIOS signature word.
8099 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8102 * Restore per TID negotiated values.
8104 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8105 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8106 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8107 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8109 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8110 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
8111 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
8112 max_cmd[tid]);
8115 return status;
8119 * adv_async_callback() - Adv Library asynchronous event callback function.
8121 static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
8123 switch (code) {
8124 case ADV_ASYNC_SCSI_BUS_RESET_DET:
8126 * The firmware detected a SCSI Bus reset.
8128 ASC_DBG(0, "ADV_ASYNC_SCSI_BUS_RESET_DET\n");
8129 break;
8131 case ADV_ASYNC_RDMA_FAILURE:
8133 * Handle RDMA failure by resetting the SCSI Bus and
8134 * possibly the chip if it is unresponsive. Log the error
8135 * with a unique code.
8137 ASC_DBG(0, "ADV_ASYNC_RDMA_FAILURE\n");
8138 AdvResetChipAndSB(adv_dvc_varp);
8139 break;
8141 case ADV_HOST_SCSI_BUS_RESET:
8143 * Host generated SCSI bus reset occurred.
8145 ASC_DBG(0, "ADV_HOST_SCSI_BUS_RESET\n");
8146 break;
8148 default:
8149 ASC_DBG(0, "unknown code 0x%x\n", code);
8150 break;
8155 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
8157 * Callback function for the Wide SCSI Adv Library.
8159 static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
8161 struct asc_board *boardp;
8162 adv_req_t *reqp;
8163 adv_sgblk_t *sgblkp;
8164 struct scsi_cmnd *scp;
8165 struct Scsi_Host *shost;
8166 ADV_DCNT resid_cnt;
8168 ASC_DBG(1, "adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
8169 (ulong)adv_dvc_varp, (ulong)scsiqp);
8170 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
8173 * Get the adv_req_t structure for the command that has been
8174 * completed. The adv_req_t structure actually contains the
8175 * completed ADV_SCSI_REQ_Q structure.
8177 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
8178 ASC_DBG(1, "reqp 0x%lx\n", (ulong)reqp);
8179 if (reqp == NULL) {
8180 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
8181 return;
8185 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
8186 * command that has been completed.
8188 * Note: The adv_req_t request structure and adv_sgblk_t structure,
8189 * if any, are dropped, because a board structure pointer can not be
8190 * determined.
8192 scp = reqp->cmndp;
8193 ASC_DBG(1, "scp 0x%p\n", scp);
8194 if (scp == NULL) {
8195 ASC_PRINT
8196 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
8197 return;
8199 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
8201 shost = scp->device->host;
8202 ASC_STATS(shost, callback);
8203 ASC_DBG(1, "shost 0x%p\n", shost);
8205 boardp = shost_priv(shost);
8206 BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var);
8209 * 'done_status' contains the command's ending status.
8211 switch (scsiqp->done_status) {
8212 case QD_NO_ERROR:
8213 ASC_DBG(2, "QD_NO_ERROR\n");
8214 scp->result = 0;
8217 * Check for an underrun condition.
8219 * If there was no error and an underrun condition, then
8220 * then return the number of underrun bytes.
8222 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
8223 if (scsi_bufflen(scp) != 0 && resid_cnt != 0 &&
8224 resid_cnt <= scsi_bufflen(scp)) {
8225 ASC_DBG(1, "underrun condition %lu bytes\n",
8226 (ulong)resid_cnt);
8227 scsi_set_resid(scp, resid_cnt);
8229 break;
8231 case QD_WITH_ERROR:
8232 ASC_DBG(2, "QD_WITH_ERROR\n");
8233 switch (scsiqp->host_status) {
8234 case QHSTA_NO_ERROR:
8235 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
8236 ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
8237 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
8238 SCSI_SENSE_BUFFERSIZE);
8240 * Note: The 'status_byte()' macro used by
8241 * target drivers defined in scsi.h shifts the
8242 * status byte returned by host drivers right
8243 * by 1 bit. This is why target drivers also
8244 * use right shifted status byte definitions.
8245 * For instance target drivers use
8246 * CHECK_CONDITION, defined to 0x1, instead of
8247 * the SCSI defined check condition value of
8248 * 0x2. Host drivers are supposed to return
8249 * the status byte as it is defined by SCSI.
8251 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
8252 STATUS_BYTE(scsiqp->scsi_status);
8253 } else {
8254 scp->result = STATUS_BYTE(scsiqp->scsi_status);
8256 break;
8258 default:
8259 /* Some other QHSTA error occurred. */
8260 ASC_DBG(1, "host_status 0x%x\n", scsiqp->host_status);
8261 scp->result = HOST_BYTE(DID_BAD_TARGET);
8262 break;
8264 break;
8266 case QD_ABORTED_BY_HOST:
8267 ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
8268 scp->result =
8269 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
8270 break;
8272 default:
8273 ASC_DBG(1, "done_status 0x%x\n", scsiqp->done_status);
8274 scp->result =
8275 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
8276 break;
8280 * If the 'init_tidmask' bit isn't already set for the target and the
8281 * current request finished normally, then set the bit for the target
8282 * to indicate that a device is present.
8284 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
8285 scsiqp->done_status == QD_NO_ERROR &&
8286 scsiqp->host_status == QHSTA_NO_ERROR) {
8287 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
8290 asc_scsi_done(scp);
8293 * Free all 'adv_sgblk_t' structures allocated for the request.
8295 while ((sgblkp = reqp->sgblkp) != NULL) {
8296 /* Remove 'sgblkp' from the request list. */
8297 reqp->sgblkp = sgblkp->next_sgblkp;
8299 /* Add 'sgblkp' to the board free list. */
8300 sgblkp->next_sgblkp = boardp->adv_sgblkp;
8301 boardp->adv_sgblkp = sgblkp;
8305 * Free the adv_req_t structure used with the command by adding
8306 * it back to the board free list.
8308 reqp->next_reqp = boardp->adv_reqp;
8309 boardp->adv_reqp = reqp;
8311 ASC_DBG(1, "done\n");
8315 * Adv Library Interrupt Service Routine
8317 * This function is called by a driver's interrupt service routine.
8318 * The function disables and re-enables interrupts.
8320 * When a microcode idle command is completed, the ADV_DVC_VAR
8321 * 'idle_cmd_done' field is set to ADV_TRUE.
8323 * Note: AdvISR() can be called when interrupts are disabled or even
8324 * when there is no hardware interrupt condition present. It will
8325 * always check for completed idle commands and microcode requests.
8326 * This is an important feature that shouldn't be changed because it
8327 * allows commands to be completed from polling mode loops.
8329 * Return:
8330 * ADV_TRUE(1) - interrupt was pending
8331 * ADV_FALSE(0) - no interrupt was pending
8333 static int AdvISR(ADV_DVC_VAR *asc_dvc)
8335 AdvPortAddr iop_base;
8336 uchar int_stat;
8337 ushort target_bit;
8338 ADV_CARR_T *free_carrp;
8339 ADV_VADDR irq_next_vpa;
8340 ADV_SCSI_REQ_Q *scsiq;
8342 iop_base = asc_dvc->iop_base;
8344 /* Reading the register clears the interrupt. */
8345 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
8347 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
8348 ADV_INTR_STATUS_INTRC)) == 0) {
8349 return ADV_FALSE;
8353 * Notify the driver of an asynchronous microcode condition by
8354 * calling the adv_async_callback function. The function
8355 * is passed the microcode ASC_MC_INTRB_CODE byte value.
8357 if (int_stat & ADV_INTR_STATUS_INTRB) {
8358 uchar intrb_code;
8360 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
8362 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
8363 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8364 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
8365 asc_dvc->carr_pending_cnt != 0) {
8366 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
8367 ADV_TICKLE_A);
8368 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
8369 AdvWriteByteRegister(iop_base,
8370 IOPB_TICKLE,
8371 ADV_TICKLE_NOP);
8376 adv_async_callback(asc_dvc, intrb_code);
8380 * Check if the IRQ stopper carrier contains a completed request.
8382 while (((irq_next_vpa =
8383 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
8385 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
8386 * The RISC will have set 'areq_vpa' to a virtual address.
8388 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
8389 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
8390 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
8391 * in AdvExeScsiQueue().
8393 scsiq = (ADV_SCSI_REQ_Q *)
8394 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
8397 * Request finished with good status and the queue was not
8398 * DMAed to host memory by the firmware. Set all status fields
8399 * to indicate good status.
8401 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
8402 scsiq->done_status = QD_NO_ERROR;
8403 scsiq->host_status = scsiq->scsi_status = 0;
8404 scsiq->data_cnt = 0L;
8408 * Advance the stopper pointer to the next carrier
8409 * ignoring the lower four bits. Free the previous
8410 * stopper carrier.
8412 free_carrp = asc_dvc->irq_sp;
8413 asc_dvc->irq_sp = (ADV_CARR_T *)
8414 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
8416 free_carrp->next_vpa =
8417 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
8418 asc_dvc->carr_freelist = free_carrp;
8419 asc_dvc->carr_pending_cnt--;
8421 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
8424 * Clear request microcode control flag.
8426 scsiq->cntl = 0;
8429 * Notify the driver of the completed request by passing
8430 * the ADV_SCSI_REQ_Q pointer to its callback function.
8432 scsiq->a_flag |= ADV_SCSIQ_DONE;
8433 adv_isr_callback(asc_dvc, scsiq);
8435 * Note: After the driver callback function is called, 'scsiq'
8436 * can no longer be referenced.
8438 * Fall through and continue processing other completed
8439 * requests...
8442 return ADV_TRUE;
8445 static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
8447 if (asc_dvc->err_code == 0) {
8448 asc_dvc->err_code = err_code;
8449 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
8450 err_code);
8452 return err_code;
8455 static void AscAckInterrupt(PortAddr iop_base)
8457 uchar host_flag;
8458 uchar risc_flag;
8459 ushort loop;
8461 loop = 0;
8462 do {
8463 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
8464 if (loop++ > 0x7FFF) {
8465 break;
8467 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
8468 host_flag =
8469 AscReadLramByte(iop_base,
8470 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
8471 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8472 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
8473 AscSetChipStatus(iop_base, CIW_INT_ACK);
8474 loop = 0;
8475 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
8476 AscSetChipStatus(iop_base, CIW_INT_ACK);
8477 if (loop++ > 3) {
8478 break;
8481 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8484 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
8486 const uchar *period_table;
8487 int max_index;
8488 int min_index;
8489 int i;
8491 period_table = asc_dvc->sdtr_period_tbl;
8492 max_index = (int)asc_dvc->max_sdtr_index;
8493 min_index = (int)asc_dvc->min_sdtr_index;
8494 if ((syn_time <= period_table[max_index])) {
8495 for (i = min_index; i < (max_index - 1); i++) {
8496 if (syn_time <= period_table[i]) {
8497 return (uchar)i;
8500 return (uchar)max_index;
8501 } else {
8502 return (uchar)(max_index + 1);
8506 static uchar
8507 AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
8509 EXT_MSG sdtr_buf;
8510 uchar sdtr_period_index;
8511 PortAddr iop_base;
8513 iop_base = asc_dvc->iop_base;
8514 sdtr_buf.msg_type = EXTENDED_MESSAGE;
8515 sdtr_buf.msg_len = MS_SDTR_LEN;
8516 sdtr_buf.msg_req = EXTENDED_SDTR;
8517 sdtr_buf.xfer_period = sdtr_period;
8518 sdtr_offset &= ASC_SYN_MAX_OFFSET;
8519 sdtr_buf.req_ack_offset = sdtr_offset;
8520 sdtr_period_index = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8521 if (sdtr_period_index <= asc_dvc->max_sdtr_index) {
8522 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
8523 (uchar *)&sdtr_buf,
8524 sizeof(EXT_MSG) >> 1);
8525 return ((sdtr_period_index << 4) | sdtr_offset);
8526 } else {
8527 sdtr_buf.req_ack_offset = 0;
8528 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
8529 (uchar *)&sdtr_buf,
8530 sizeof(EXT_MSG) >> 1);
8531 return 0;
8535 static uchar
8536 AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
8538 uchar byte;
8539 uchar sdtr_period_ix;
8541 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8542 if (sdtr_period_ix > asc_dvc->max_sdtr_index)
8543 return 0xFF;
8544 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
8545 return byte;
8548 static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
8550 ASC_SCSI_BIT_ID_TYPE org_id;
8551 int i;
8552 int sta = TRUE;
8554 AscSetBank(iop_base, 1);
8555 org_id = AscReadChipDvcID(iop_base);
8556 for (i = 0; i <= ASC_MAX_TID; i++) {
8557 if (org_id == (0x01 << i))
8558 break;
8560 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
8561 AscWriteChipDvcID(iop_base, id);
8562 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
8563 AscSetBank(iop_base, 0);
8564 AscSetChipSyn(iop_base, sdtr_data);
8565 if (AscGetChipSyn(iop_base) != sdtr_data) {
8566 sta = FALSE;
8568 } else {
8569 sta = FALSE;
8571 AscSetBank(iop_base, 1);
8572 AscWriteChipDvcID(iop_base, org_id);
8573 AscSetBank(iop_base, 0);
8574 return (sta);
8577 static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
8579 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
8580 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
8583 static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8585 EXT_MSG ext_msg;
8586 EXT_MSG out_msg;
8587 ushort halt_q_addr;
8588 int sdtr_accept;
8589 ushort int_halt_code;
8590 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8591 ASC_SCSI_BIT_ID_TYPE target_id;
8592 PortAddr iop_base;
8593 uchar tag_code;
8594 uchar q_status;
8595 uchar halt_qp;
8596 uchar sdtr_data;
8597 uchar target_ix;
8598 uchar q_cntl, tid_no;
8599 uchar cur_dvc_qng;
8600 uchar asyn_sdtr;
8601 uchar scsi_status;
8602 struct asc_board *boardp;
8604 BUG_ON(!asc_dvc->drv_ptr);
8605 boardp = asc_dvc->drv_ptr;
8607 iop_base = asc_dvc->iop_base;
8608 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8610 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8611 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8612 target_ix = AscReadLramByte(iop_base,
8613 (ushort)(halt_q_addr +
8614 (ushort)ASC_SCSIQ_B_TARGET_IX));
8615 q_cntl = AscReadLramByte(iop_base,
8616 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8617 tid_no = ASC_TIX_TO_TID(target_ix);
8618 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8619 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8620 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8621 } else {
8622 asyn_sdtr = 0;
8624 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8625 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8626 AscSetChipSDTR(iop_base, 0, tid_no);
8627 boardp->sdtr_data[tid_no] = 0;
8629 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8630 return (0);
8631 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8632 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8633 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8634 boardp->sdtr_data[tid_no] = asyn_sdtr;
8636 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8637 return (0);
8638 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8639 AscMemWordCopyPtrFromLram(iop_base,
8640 ASCV_MSGIN_BEG,
8641 (uchar *)&ext_msg,
8642 sizeof(EXT_MSG) >> 1);
8644 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8645 ext_msg.msg_req == EXTENDED_SDTR &&
8646 ext_msg.msg_len == MS_SDTR_LEN) {
8647 sdtr_accept = TRUE;
8648 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8650 sdtr_accept = FALSE;
8651 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8653 if ((ext_msg.xfer_period <
8654 asc_dvc->sdtr_period_tbl[asc_dvc->min_sdtr_index])
8655 || (ext_msg.xfer_period >
8656 asc_dvc->sdtr_period_tbl[asc_dvc->
8657 max_sdtr_index])) {
8658 sdtr_accept = FALSE;
8659 ext_msg.xfer_period =
8660 asc_dvc->sdtr_period_tbl[asc_dvc->
8661 min_sdtr_index];
8663 if (sdtr_accept) {
8664 sdtr_data =
8665 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8666 ext_msg.req_ack_offset);
8667 if ((sdtr_data == 0xFF)) {
8669 q_cntl |= QC_MSG_OUT;
8670 asc_dvc->init_sdtr &= ~target_id;
8671 asc_dvc->sdtr_done &= ~target_id;
8672 AscSetChipSDTR(iop_base, asyn_sdtr,
8673 tid_no);
8674 boardp->sdtr_data[tid_no] = asyn_sdtr;
8677 if (ext_msg.req_ack_offset == 0) {
8679 q_cntl &= ~QC_MSG_OUT;
8680 asc_dvc->init_sdtr &= ~target_id;
8681 asc_dvc->sdtr_done &= ~target_id;
8682 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8683 } else {
8684 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8685 q_cntl &= ~QC_MSG_OUT;
8686 asc_dvc->sdtr_done |= target_id;
8687 asc_dvc->init_sdtr |= target_id;
8688 asc_dvc->pci_fix_asyn_xfer &=
8689 ~target_id;
8690 sdtr_data =
8691 AscCalSDTRData(asc_dvc,
8692 ext_msg.xfer_period,
8693 ext_msg.
8694 req_ack_offset);
8695 AscSetChipSDTR(iop_base, sdtr_data,
8696 tid_no);
8697 boardp->sdtr_data[tid_no] = sdtr_data;
8698 } else {
8699 q_cntl |= QC_MSG_OUT;
8700 AscMsgOutSDTR(asc_dvc,
8701 ext_msg.xfer_period,
8702 ext_msg.req_ack_offset);
8703 asc_dvc->pci_fix_asyn_xfer &=
8704 ~target_id;
8705 sdtr_data =
8706 AscCalSDTRData(asc_dvc,
8707 ext_msg.xfer_period,
8708 ext_msg.
8709 req_ack_offset);
8710 AscSetChipSDTR(iop_base, sdtr_data,
8711 tid_no);
8712 boardp->sdtr_data[tid_no] = sdtr_data;
8713 asc_dvc->sdtr_done |= target_id;
8714 asc_dvc->init_sdtr |= target_id;
8718 AscWriteLramByte(iop_base,
8719 (ushort)(halt_q_addr +
8720 (ushort)ASC_SCSIQ_B_CNTL),
8721 q_cntl);
8722 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8723 return (0);
8724 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8725 ext_msg.msg_req == EXTENDED_WDTR &&
8726 ext_msg.msg_len == MS_WDTR_LEN) {
8728 ext_msg.wdtr_width = 0;
8729 AscMemWordCopyPtrToLram(iop_base,
8730 ASCV_MSGOUT_BEG,
8731 (uchar *)&ext_msg,
8732 sizeof(EXT_MSG) >> 1);
8733 q_cntl |= QC_MSG_OUT;
8734 AscWriteLramByte(iop_base,
8735 (ushort)(halt_q_addr +
8736 (ushort)ASC_SCSIQ_B_CNTL),
8737 q_cntl);
8738 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8739 return (0);
8740 } else {
8742 ext_msg.msg_type = MESSAGE_REJECT;
8743 AscMemWordCopyPtrToLram(iop_base,
8744 ASCV_MSGOUT_BEG,
8745 (uchar *)&ext_msg,
8746 sizeof(EXT_MSG) >> 1);
8747 q_cntl |= QC_MSG_OUT;
8748 AscWriteLramByte(iop_base,
8749 (ushort)(halt_q_addr +
8750 (ushort)ASC_SCSIQ_B_CNTL),
8751 q_cntl);
8752 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8753 return (0);
8755 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8757 q_cntl |= QC_REQ_SENSE;
8759 if ((asc_dvc->init_sdtr & target_id) != 0) {
8761 asc_dvc->sdtr_done &= ~target_id;
8763 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8764 q_cntl |= QC_MSG_OUT;
8765 AscMsgOutSDTR(asc_dvc,
8766 asc_dvc->
8767 sdtr_period_tbl[(sdtr_data >> 4) &
8768 (uchar)(asc_dvc->
8769 max_sdtr_index -
8770 1)],
8771 (uchar)(sdtr_data & (uchar)
8772 ASC_SYN_MAX_OFFSET));
8775 AscWriteLramByte(iop_base,
8776 (ushort)(halt_q_addr +
8777 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8779 tag_code = AscReadLramByte(iop_base,
8780 (ushort)(halt_q_addr + (ushort)
8781 ASC_SCSIQ_B_TAG_CODE));
8782 tag_code &= 0xDC;
8783 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8784 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8787 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8788 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8791 AscWriteLramByte(iop_base,
8792 (ushort)(halt_q_addr +
8793 (ushort)ASC_SCSIQ_B_TAG_CODE),
8794 tag_code);
8796 q_status = AscReadLramByte(iop_base,
8797 (ushort)(halt_q_addr + (ushort)
8798 ASC_SCSIQ_B_STATUS));
8799 q_status |= (QS_READY | QS_BUSY);
8800 AscWriteLramByte(iop_base,
8801 (ushort)(halt_q_addr +
8802 (ushort)ASC_SCSIQ_B_STATUS),
8803 q_status);
8805 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8806 scsi_busy &= ~target_id;
8807 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8809 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8810 return (0);
8811 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8813 AscMemWordCopyPtrFromLram(iop_base,
8814 ASCV_MSGOUT_BEG,
8815 (uchar *)&out_msg,
8816 sizeof(EXT_MSG) >> 1);
8818 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
8819 (out_msg.msg_len == MS_SDTR_LEN) &&
8820 (out_msg.msg_req == EXTENDED_SDTR)) {
8822 asc_dvc->init_sdtr &= ~target_id;
8823 asc_dvc->sdtr_done &= ~target_id;
8824 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8825 boardp->sdtr_data[tid_no] = asyn_sdtr;
8827 q_cntl &= ~QC_MSG_OUT;
8828 AscWriteLramByte(iop_base,
8829 (ushort)(halt_q_addr +
8830 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8831 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8832 return (0);
8833 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8835 scsi_status = AscReadLramByte(iop_base,
8836 (ushort)((ushort)halt_q_addr +
8837 (ushort)
8838 ASC_SCSIQ_SCSI_STATUS));
8839 cur_dvc_qng =
8840 AscReadLramByte(iop_base,
8841 (ushort)((ushort)ASC_QADR_BEG +
8842 (ushort)target_ix));
8843 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8845 scsi_busy = AscReadLramByte(iop_base,
8846 (ushort)ASCV_SCSIBUSY_B);
8847 scsi_busy |= target_id;
8848 AscWriteLramByte(iop_base,
8849 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8850 asc_dvc->queue_full_or_busy |= target_id;
8852 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8853 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8854 cur_dvc_qng -= 1;
8855 asc_dvc->max_dvc_qng[tid_no] =
8856 cur_dvc_qng;
8858 AscWriteLramByte(iop_base,
8859 (ushort)((ushort)
8860 ASCV_MAX_DVC_QNG_BEG
8861 + (ushort)
8862 tid_no),
8863 cur_dvc_qng);
8866 * Set the device queue depth to the
8867 * number of active requests when the
8868 * QUEUE FULL condition was encountered.
8870 boardp->queue_full |= target_id;
8871 boardp->queue_full_cnt[tid_no] =
8872 cur_dvc_qng;
8876 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8877 return (0);
8879 #if CC_VERY_LONG_SG_LIST
8880 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8881 uchar q_no;
8882 ushort q_addr;
8883 uchar sg_wk_q_no;
8884 uchar first_sg_wk_q_no;
8885 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
8886 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
8887 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
8888 ushort sg_list_dwords;
8889 ushort sg_entry_cnt;
8890 uchar next_qp;
8891 int i;
8893 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8894 if (q_no == ASC_QLINK_END)
8895 return 0;
8897 q_addr = ASC_QNO_TO_QADDR(q_no);
8900 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8901 * structure pointer using a macro provided by the driver.
8902 * The ASC_SCSI_REQ pointer provides a pointer to the
8903 * host ASC_SG_HEAD structure.
8905 /* Read request's SRB pointer. */
8906 scsiq = (ASC_SCSI_Q *)
8907 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8908 (ushort)
8909 (q_addr +
8910 ASC_SCSIQ_D_SRBPTR))));
8913 * Get request's first and working SG queue.
8915 sg_wk_q_no = AscReadLramByte(iop_base,
8916 (ushort)(q_addr +
8917 ASC_SCSIQ_B_SG_WK_QP));
8919 first_sg_wk_q_no = AscReadLramByte(iop_base,
8920 (ushort)(q_addr +
8921 ASC_SCSIQ_B_FIRST_SG_WK_QP));
8924 * Reset request's working SG queue back to the
8925 * first SG queue.
8927 AscWriteLramByte(iop_base,
8928 (ushort)(q_addr +
8929 (ushort)ASC_SCSIQ_B_SG_WK_QP),
8930 first_sg_wk_q_no);
8932 sg_head = scsiq->sg_head;
8935 * Set sg_entry_cnt to the number of SG elements
8936 * that will be completed on this interrupt.
8938 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8939 * SG elements. The data_cnt and data_addr fields which
8940 * add 1 to the SG element capacity are not used when
8941 * restarting SG handling after a halt.
8943 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
8944 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8947 * Keep track of remaining number of SG elements that
8948 * will need to be handled on the next interrupt.
8950 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
8951 } else {
8952 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
8953 scsiq->remain_sg_entry_cnt = 0;
8957 * Copy SG elements into the list of allocated SG queues.
8959 * Last index completed is saved in scsiq->next_sg_index.
8961 next_qp = first_sg_wk_q_no;
8962 q_addr = ASC_QNO_TO_QADDR(next_qp);
8963 scsi_sg_q.sg_head_qp = q_no;
8964 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8965 for (i = 0; i < sg_head->queue_cnt; i++) {
8966 scsi_sg_q.seq_no = i + 1;
8967 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8968 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8969 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8971 * After very first SG queue RISC FW uses next
8972 * SG queue first element then checks sg_list_cnt
8973 * against zero and then decrements, so set
8974 * sg_list_cnt 1 less than number of SG elements
8975 * in each SG queue.
8977 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
8978 scsi_sg_q.sg_cur_list_cnt =
8979 ASC_SG_LIST_PER_Q - 1;
8980 } else {
8982 * This is the last SG queue in the list of
8983 * allocated SG queues. If there are more
8984 * SG elements than will fit in the allocated
8985 * queues, then set the QCSG_SG_XFER_MORE flag.
8987 if (scsiq->remain_sg_entry_cnt != 0) {
8988 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8989 } else {
8990 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8992 /* equals sg_entry_cnt * 2 */
8993 sg_list_dwords = sg_entry_cnt << 1;
8994 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
8995 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
8996 sg_entry_cnt = 0;
8999 scsi_sg_q.q_no = next_qp;
9000 AscMemWordCopyPtrToLram(iop_base,
9001 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9002 (uchar *)&scsi_sg_q,
9003 sizeof(ASC_SG_LIST_Q) >> 1);
9005 AscMemDWordCopyPtrToLram(iop_base,
9006 q_addr + ASC_SGQ_LIST_BEG,
9007 (uchar *)&sg_head->
9008 sg_list[scsiq->next_sg_index],
9009 sg_list_dwords);
9011 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
9014 * If the just completed SG queue contained the
9015 * last SG element, then no more SG queues need
9016 * to be written.
9018 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
9019 break;
9022 next_qp = AscReadLramByte(iop_base,
9023 (ushort)(q_addr +
9024 ASC_SCSIQ_B_FWD));
9025 q_addr = ASC_QNO_TO_QADDR(next_qp);
9029 * Clear the halt condition so the RISC will be restarted
9030 * after the return.
9032 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9033 return (0);
9035 #endif /* CC_VERY_LONG_SG_LIST */
9036 return (0);
9040 * void
9041 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9043 * Calling/Exit State:
9044 * none
9046 * Description:
9047 * Input an ASC_QDONE_INFO structure from the chip
9049 static void
9050 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9052 int i;
9053 ushort word;
9055 AscSetChipLramAddr(iop_base, s_addr);
9056 for (i = 0; i < 2 * words; i += 2) {
9057 if (i == 10) {
9058 continue;
9060 word = inpw(iop_base + IOP_RAM_DATA);
9061 inbuf[i] = word & 0xff;
9062 inbuf[i + 1] = (word >> 8) & 0xff;
9064 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
9067 static uchar
9068 _AscCopyLramScsiDoneQ(PortAddr iop_base,
9069 ushort q_addr,
9070 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
9072 ushort _val;
9073 uchar sg_queue_cnt;
9075 DvcGetQinfo(iop_base,
9076 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
9077 (uchar *)scsiq,
9078 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
9080 _val = AscReadLramWord(iop_base,
9081 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
9082 scsiq->q_status = (uchar)_val;
9083 scsiq->q_no = (uchar)(_val >> 8);
9084 _val = AscReadLramWord(iop_base,
9085 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
9086 scsiq->cntl = (uchar)_val;
9087 sg_queue_cnt = (uchar)(_val >> 8);
9088 _val = AscReadLramWord(iop_base,
9089 (ushort)(q_addr +
9090 (ushort)ASC_SCSIQ_B_SENSE_LEN));
9091 scsiq->sense_len = (uchar)_val;
9092 scsiq->extra_bytes = (uchar)(_val >> 8);
9095 * Read high word of remain bytes from alternate location.
9097 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
9098 (ushort)(q_addr +
9099 (ushort)
9100 ASC_SCSIQ_W_ALT_DC1)))
9101 << 16);
9103 * Read low word of remain bytes from original location.
9105 scsiq->remain_bytes += AscReadLramWord(iop_base,
9106 (ushort)(q_addr + (ushort)
9107 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
9109 scsiq->remain_bytes &= max_dma_count;
9110 return sg_queue_cnt;
9114 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
9116 * Interrupt callback function for the Narrow SCSI Asc Library.
9118 static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
9120 struct asc_board *boardp;
9121 struct scsi_cmnd *scp;
9122 struct Scsi_Host *shost;
9124 ASC_DBG(1, "asc_dvc_varp 0x%p, qdonep 0x%p\n", asc_dvc_varp, qdonep);
9125 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
9127 scp = advansys_srb_to_ptr(asc_dvc_varp, qdonep->d2.srb_ptr);
9128 if (!scp)
9129 return;
9131 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
9133 shost = scp->device->host;
9134 ASC_STATS(shost, callback);
9135 ASC_DBG(1, "shost 0x%p\n", shost);
9137 boardp = shost_priv(shost);
9138 BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var);
9140 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
9141 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
9143 * 'qdonep' contains the command's ending status.
9145 switch (qdonep->d3.done_stat) {
9146 case QD_NO_ERROR:
9147 ASC_DBG(2, "QD_NO_ERROR\n");
9148 scp->result = 0;
9151 * Check for an underrun condition.
9153 * If there was no error and an underrun condition, then
9154 * return the number of underrun bytes.
9156 if (scsi_bufflen(scp) != 0 && qdonep->remain_bytes != 0 &&
9157 qdonep->remain_bytes <= scsi_bufflen(scp)) {
9158 ASC_DBG(1, "underrun condition %u bytes\n",
9159 (unsigned)qdonep->remain_bytes);
9160 scsi_set_resid(scp, qdonep->remain_bytes);
9162 break;
9164 case QD_WITH_ERROR:
9165 ASC_DBG(2, "QD_WITH_ERROR\n");
9166 switch (qdonep->d3.host_stat) {
9167 case QHSTA_NO_ERROR:
9168 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
9169 ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
9170 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
9171 SCSI_SENSE_BUFFERSIZE);
9173 * Note: The 'status_byte()' macro used by
9174 * target drivers defined in scsi.h shifts the
9175 * status byte returned by host drivers right
9176 * by 1 bit. This is why target drivers also
9177 * use right shifted status byte definitions.
9178 * For instance target drivers use
9179 * CHECK_CONDITION, defined to 0x1, instead of
9180 * the SCSI defined check condition value of
9181 * 0x2. Host drivers are supposed to return
9182 * the status byte as it is defined by SCSI.
9184 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
9185 STATUS_BYTE(qdonep->d3.scsi_stat);
9186 } else {
9187 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
9189 break;
9191 default:
9192 /* QHSTA error occurred */
9193 ASC_DBG(1, "host_stat 0x%x\n", qdonep->d3.host_stat);
9194 scp->result = HOST_BYTE(DID_BAD_TARGET);
9195 break;
9197 break;
9199 case QD_ABORTED_BY_HOST:
9200 ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
9201 scp->result =
9202 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
9203 scsi_msg) |
9204 STATUS_BYTE(qdonep->d3.scsi_stat);
9205 break;
9207 default:
9208 ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat);
9209 scp->result =
9210 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
9211 scsi_msg) |
9212 STATUS_BYTE(qdonep->d3.scsi_stat);
9213 break;
9217 * If the 'init_tidmask' bit isn't already set for the target and the
9218 * current request finished normally, then set the bit for the target
9219 * to indicate that a device is present.
9221 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
9222 qdonep->d3.done_stat == QD_NO_ERROR &&
9223 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
9224 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
9227 asc_scsi_done(scp);
9230 static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
9232 uchar next_qp;
9233 uchar n_q_used;
9234 uchar sg_list_qp;
9235 uchar sg_queue_cnt;
9236 uchar q_cnt;
9237 uchar done_q_tail;
9238 uchar tid_no;
9239 ASC_SCSI_BIT_ID_TYPE scsi_busy;
9240 ASC_SCSI_BIT_ID_TYPE target_id;
9241 PortAddr iop_base;
9242 ushort q_addr;
9243 ushort sg_q_addr;
9244 uchar cur_target_qng;
9245 ASC_QDONE_INFO scsiq_buf;
9246 ASC_QDONE_INFO *scsiq;
9247 int false_overrun;
9249 iop_base = asc_dvc->iop_base;
9250 n_q_used = 1;
9251 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
9252 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
9253 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
9254 next_qp = AscReadLramByte(iop_base,
9255 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
9256 if (next_qp != ASC_QLINK_END) {
9257 AscPutVarDoneQTail(iop_base, next_qp);
9258 q_addr = ASC_QNO_TO_QADDR(next_qp);
9259 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
9260 asc_dvc->max_dma_count);
9261 AscWriteLramByte(iop_base,
9262 (ushort)(q_addr +
9263 (ushort)ASC_SCSIQ_B_STATUS),
9264 (uchar)(scsiq->
9265 q_status & (uchar)~(QS_READY |
9266 QS_ABORTED)));
9267 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
9268 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
9269 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
9270 sg_q_addr = q_addr;
9271 sg_list_qp = next_qp;
9272 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
9273 sg_list_qp = AscReadLramByte(iop_base,
9274 (ushort)(sg_q_addr
9275 + (ushort)
9276 ASC_SCSIQ_B_FWD));
9277 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
9278 if (sg_list_qp == ASC_QLINK_END) {
9279 AscSetLibErrorCode(asc_dvc,
9280 ASCQ_ERR_SG_Q_LINKS);
9281 scsiq->d3.done_stat = QD_WITH_ERROR;
9282 scsiq->d3.host_stat =
9283 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
9284 goto FATAL_ERR_QDONE;
9286 AscWriteLramByte(iop_base,
9287 (ushort)(sg_q_addr + (ushort)
9288 ASC_SCSIQ_B_STATUS),
9289 QS_FREE);
9291 n_q_used = sg_queue_cnt + 1;
9292 AscPutVarDoneQTail(iop_base, sg_list_qp);
9294 if (asc_dvc->queue_full_or_busy & target_id) {
9295 cur_target_qng = AscReadLramByte(iop_base,
9296 (ushort)((ushort)
9297 ASC_QADR_BEG
9298 + (ushort)
9299 scsiq->d2.
9300 target_ix));
9301 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
9302 scsi_busy = AscReadLramByte(iop_base, (ushort)
9303 ASCV_SCSIBUSY_B);
9304 scsi_busy &= ~target_id;
9305 AscWriteLramByte(iop_base,
9306 (ushort)ASCV_SCSIBUSY_B,
9307 scsi_busy);
9308 asc_dvc->queue_full_or_busy &= ~target_id;
9311 if (asc_dvc->cur_total_qng >= n_q_used) {
9312 asc_dvc->cur_total_qng -= n_q_used;
9313 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
9314 asc_dvc->cur_dvc_qng[tid_no]--;
9316 } else {
9317 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
9318 scsiq->d3.done_stat = QD_WITH_ERROR;
9319 goto FATAL_ERR_QDONE;
9321 if ((scsiq->d2.srb_ptr == 0UL) ||
9322 ((scsiq->q_status & QS_ABORTED) != 0)) {
9323 return (0x11);
9324 } else if (scsiq->q_status == QS_DONE) {
9325 false_overrun = FALSE;
9326 if (scsiq->extra_bytes != 0) {
9327 scsiq->remain_bytes +=
9328 (ADV_DCNT)scsiq->extra_bytes;
9330 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
9331 if (scsiq->d3.host_stat ==
9332 QHSTA_M_DATA_OVER_RUN) {
9333 if ((scsiq->
9334 cntl & (QC_DATA_IN | QC_DATA_OUT))
9335 == 0) {
9336 scsiq->d3.done_stat =
9337 QD_NO_ERROR;
9338 scsiq->d3.host_stat =
9339 QHSTA_NO_ERROR;
9340 } else if (false_overrun) {
9341 scsiq->d3.done_stat =
9342 QD_NO_ERROR;
9343 scsiq->d3.host_stat =
9344 QHSTA_NO_ERROR;
9346 } else if (scsiq->d3.host_stat ==
9347 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
9348 AscStopChip(iop_base);
9349 AscSetChipControl(iop_base,
9350 (uchar)(CC_SCSI_RESET
9351 | CC_HALT));
9352 udelay(60);
9353 AscSetChipControl(iop_base, CC_HALT);
9354 AscSetChipStatus(iop_base,
9355 CIW_CLR_SCSI_RESET_INT);
9356 AscSetChipStatus(iop_base, 0);
9357 AscSetChipControl(iop_base, 0);
9360 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9361 asc_isr_callback(asc_dvc, scsiq);
9362 } else {
9363 if ((AscReadLramByte(iop_base,
9364 (ushort)(q_addr + (ushort)
9365 ASC_SCSIQ_CDB_BEG))
9366 == START_STOP)) {
9367 asc_dvc->unit_not_ready &= ~target_id;
9368 if (scsiq->d3.done_stat != QD_NO_ERROR) {
9369 asc_dvc->start_motor &=
9370 ~target_id;
9374 return (1);
9375 } else {
9376 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
9377 FATAL_ERR_QDONE:
9378 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9379 asc_isr_callback(asc_dvc, scsiq);
9381 return (0x80);
9384 return (0);
9387 static int AscISR(ASC_DVC_VAR *asc_dvc)
9389 ASC_CS_TYPE chipstat;
9390 PortAddr iop_base;
9391 ushort saved_ram_addr;
9392 uchar ctrl_reg;
9393 uchar saved_ctrl_reg;
9394 int int_pending;
9395 int status;
9396 uchar host_flag;
9398 iop_base = asc_dvc->iop_base;
9399 int_pending = FALSE;
9401 if (AscIsIntPending(iop_base) == 0)
9402 return int_pending;
9404 if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
9405 return ERR;
9407 if (asc_dvc->in_critical_cnt != 0) {
9408 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
9409 return ERR;
9411 if (asc_dvc->is_in_int) {
9412 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
9413 return ERR;
9415 asc_dvc->is_in_int = TRUE;
9416 ctrl_reg = AscGetChipControl(iop_base);
9417 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
9418 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
9419 chipstat = AscGetChipStatus(iop_base);
9420 if (chipstat & CSW_SCSI_RESET_LATCH) {
9421 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
9422 int i = 10;
9423 int_pending = TRUE;
9424 asc_dvc->sdtr_done = 0;
9425 saved_ctrl_reg &= (uchar)(~CC_HALT);
9426 while ((AscGetChipStatus(iop_base) &
9427 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
9428 mdelay(100);
9430 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
9431 AscSetChipControl(iop_base, CC_HALT);
9432 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
9433 AscSetChipStatus(iop_base, 0);
9434 chipstat = AscGetChipStatus(iop_base);
9437 saved_ram_addr = AscGetChipLramAddr(iop_base);
9438 host_flag = AscReadLramByte(iop_base,
9439 ASCV_HOST_FLAG_B) &
9440 (uchar)(~ASC_HOST_FLAG_IN_ISR);
9441 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
9442 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
9443 if ((chipstat & CSW_INT_PENDING) || (int_pending)) {
9444 AscAckInterrupt(iop_base);
9445 int_pending = TRUE;
9446 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
9447 if (AscIsrChipHalted(asc_dvc) == ERR) {
9448 goto ISR_REPORT_QDONE_FATAL_ERROR;
9449 } else {
9450 saved_ctrl_reg &= (uchar)(~CC_HALT);
9452 } else {
9453 ISR_REPORT_QDONE_FATAL_ERROR:
9454 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
9455 while (((status =
9456 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
9458 } else {
9459 do {
9460 if ((status =
9461 AscIsrQDone(asc_dvc)) == 1) {
9462 break;
9464 } while (status == 0x11);
9466 if ((status & 0x80) != 0)
9467 int_pending = ERR;
9470 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9471 AscSetChipLramAddr(iop_base, saved_ram_addr);
9472 AscSetChipControl(iop_base, saved_ctrl_reg);
9473 asc_dvc->is_in_int = FALSE;
9474 return int_pending;
9478 * advansys_reset()
9480 * Reset the bus associated with the command 'scp'.
9482 * This function runs its own thread. Interrupts must be blocked but
9483 * sleeping is allowed and no locking other than for host structures is
9484 * required. Returns SUCCESS or FAILED.
9486 static int advansys_reset(struct scsi_cmnd *scp)
9488 struct Scsi_Host *shost = scp->device->host;
9489 struct asc_board *boardp = shost_priv(shost);
9490 unsigned long flags;
9491 int status;
9492 int ret = SUCCESS;
9494 ASC_DBG(1, "0x%p\n", scp);
9496 ASC_STATS(shost, reset);
9498 scmd_printk(KERN_INFO, scp, "SCSI bus reset started...\n");
9500 if (ASC_NARROW_BOARD(boardp)) {
9501 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
9503 /* Reset the chip and SCSI bus. */
9504 ASC_DBG(1, "before AscInitAsc1000Driver()\n");
9505 status = AscInitAsc1000Driver(asc_dvc);
9507 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
9508 if (asc_dvc->err_code) {
9509 scmd_printk(KERN_INFO, scp, "SCSI bus reset error: "
9510 "0x%x\n", asc_dvc->err_code);
9511 ret = FAILED;
9512 } else if (status) {
9513 scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: "
9514 "0x%x\n", status);
9515 } else {
9516 scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9517 "successful\n");
9520 ASC_DBG(1, "after AscInitAsc1000Driver()\n");
9521 spin_lock_irqsave(shost->host_lock, flags);
9522 } else {
9524 * If the suggest reset bus flags are set, then reset the bus.
9525 * Otherwise only reset the device.
9527 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
9530 * Reset the target's SCSI bus.
9532 ASC_DBG(1, "before AdvResetChipAndSB()\n");
9533 switch (AdvResetChipAndSB(adv_dvc)) {
9534 case ASC_TRUE:
9535 scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9536 "successful\n");
9537 break;
9538 case ASC_FALSE:
9539 default:
9540 scmd_printk(KERN_INFO, scp, "SCSI bus reset error\n");
9541 ret = FAILED;
9542 break;
9544 spin_lock_irqsave(shost->host_lock, flags);
9545 AdvISR(adv_dvc);
9548 /* Save the time of the most recently completed reset. */
9549 boardp->last_reset = jiffies;
9550 spin_unlock_irqrestore(shost->host_lock, flags);
9552 ASC_DBG(1, "ret %d\n", ret);
9554 return ret;
9558 * advansys_biosparam()
9560 * Translate disk drive geometry if the "BIOS greater than 1 GB"
9561 * support is enabled for a drive.
9563 * ip (information pointer) is an int array with the following definition:
9564 * ip[0]: heads
9565 * ip[1]: sectors
9566 * ip[2]: cylinders
9568 static int
9569 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
9570 sector_t capacity, int ip[])
9572 struct asc_board *boardp = shost_priv(sdev->host);
9574 ASC_DBG(1, "begin\n");
9575 ASC_STATS(sdev->host, biosparam);
9576 if (ASC_NARROW_BOARD(boardp)) {
9577 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
9578 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
9579 ip[0] = 255;
9580 ip[1] = 63;
9581 } else {
9582 ip[0] = 64;
9583 ip[1] = 32;
9585 } else {
9586 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
9587 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
9588 ip[0] = 255;
9589 ip[1] = 63;
9590 } else {
9591 ip[0] = 64;
9592 ip[1] = 32;
9595 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
9596 ASC_DBG(1, "end\n");
9597 return 0;
9601 * First-level interrupt handler.
9603 * 'dev_id' is a pointer to the interrupting adapter's Scsi_Host.
9605 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
9607 struct Scsi_Host *shost = dev_id;
9608 struct asc_board *boardp = shost_priv(shost);
9609 irqreturn_t result = IRQ_NONE;
9611 ASC_DBG(2, "boardp 0x%p\n", boardp);
9612 spin_lock(shost->host_lock);
9613 if (ASC_NARROW_BOARD(boardp)) {
9614 if (AscIsIntPending(shost->io_port)) {
9615 result = IRQ_HANDLED;
9616 ASC_STATS(shost, interrupt);
9617 ASC_DBG(1, "before AscISR()\n");
9618 AscISR(&boardp->dvc_var.asc_dvc_var);
9620 } else {
9621 ASC_DBG(1, "before AdvISR()\n");
9622 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
9623 result = IRQ_HANDLED;
9624 ASC_STATS(shost, interrupt);
9627 spin_unlock(shost->host_lock);
9629 ASC_DBG(1, "end\n");
9630 return result;
9633 static int AscHostReqRiscHalt(PortAddr iop_base)
9635 int count = 0;
9636 int sta = 0;
9637 uchar saved_stop_code;
9639 if (AscIsChipHalted(iop_base))
9640 return (1);
9641 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
9642 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9643 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
9644 do {
9645 if (AscIsChipHalted(iop_base)) {
9646 sta = 1;
9647 break;
9649 mdelay(100);
9650 } while (count++ < 20);
9651 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
9652 return (sta);
9655 static int
9656 AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9658 int sta = FALSE;
9660 if (AscHostReqRiscHalt(iop_base)) {
9661 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9662 AscStartChip(iop_base);
9664 return sta;
9667 static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
9669 char type = sdev->type;
9670 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
9672 if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN))
9673 return;
9674 if (asc_dvc->init_sdtr & tid_bits)
9675 return;
9677 if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0))
9678 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
9680 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
9681 if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) ||
9682 (type == TYPE_ROM) || (type == TYPE_TAPE))
9683 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
9685 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
9686 AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id,
9687 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
9690 static void
9691 advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
9693 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
9694 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
9696 if (sdev->lun == 0) {
9697 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
9698 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
9699 asc_dvc->init_sdtr |= tid_bit;
9700 } else {
9701 asc_dvc->init_sdtr &= ~tid_bit;
9704 if (orig_init_sdtr != asc_dvc->init_sdtr)
9705 AscAsyncFix(asc_dvc, sdev);
9708 if (sdev->tagged_supported) {
9709 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
9710 if (sdev->lun == 0) {
9711 asc_dvc->cfg->can_tagged_qng |= tid_bit;
9712 asc_dvc->use_tagged_qng |= tid_bit;
9714 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
9715 asc_dvc->max_dvc_qng[sdev->id]);
9717 } else {
9718 if (sdev->lun == 0) {
9719 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
9720 asc_dvc->use_tagged_qng &= ~tid_bit;
9722 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
9725 if ((sdev->lun == 0) &&
9726 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
9727 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
9728 asc_dvc->cfg->disc_enable);
9729 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
9730 asc_dvc->use_tagged_qng);
9731 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
9732 asc_dvc->cfg->can_tagged_qng);
9734 asc_dvc->max_dvc_qng[sdev->id] =
9735 asc_dvc->cfg->max_tag_qng[sdev->id];
9736 AscWriteLramByte(asc_dvc->iop_base,
9737 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
9738 asc_dvc->max_dvc_qng[sdev->id]);
9743 * Wide Transfers
9745 * If the EEPROM enabled WDTR for the device and the device supports wide
9746 * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
9747 * write the new value to the microcode.
9749 static void
9750 advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
9752 unsigned short cfg_word;
9753 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
9754 if ((cfg_word & tidmask) != 0)
9755 return;
9757 cfg_word |= tidmask;
9758 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
9761 * Clear the microcode SDTR and WDTR negotiation done indicators for
9762 * the target to cause it to negotiate with the new setting set above.
9763 * WDTR when accepted causes the target to enter asynchronous mode, so
9764 * SDTR must be negotiated.
9766 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9767 cfg_word &= ~tidmask;
9768 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9769 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
9770 cfg_word &= ~tidmask;
9771 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
9775 * Synchronous Transfers
9777 * If the EEPROM enabled SDTR for the device and the device
9778 * supports synchronous transfers, then turn on the device's
9779 * 'sdtr_able' bit. Write the new value to the microcode.
9781 static void
9782 advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
9784 unsigned short cfg_word;
9785 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
9786 if ((cfg_word & tidmask) != 0)
9787 return;
9789 cfg_word |= tidmask;
9790 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
9793 * Clear the microcode "SDTR negotiation" done indicator for the
9794 * target to cause it to negotiate with the new setting set above.
9796 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9797 cfg_word &= ~tidmask;
9798 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9802 * PPR (Parallel Protocol Request) Capable
9804 * If the device supports DT mode, then it must be PPR capable.
9805 * The PPR message will be used in place of the SDTR and WDTR
9806 * messages to negotiate synchronous speed and offset, transfer
9807 * width, and protocol options.
9809 static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
9810 AdvPortAddr iop_base, unsigned short tidmask)
9812 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
9813 adv_dvc->ppr_able |= tidmask;
9814 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
9817 static void
9818 advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
9820 AdvPortAddr iop_base = adv_dvc->iop_base;
9821 unsigned short tidmask = 1 << sdev->id;
9823 if (sdev->lun == 0) {
9825 * Handle WDTR, SDTR, and Tag Queuing. If the feature
9826 * is enabled in the EEPROM and the device supports the
9827 * feature, then enable it in the microcode.
9830 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
9831 advansys_wide_enable_wdtr(iop_base, tidmask);
9832 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
9833 advansys_wide_enable_sdtr(iop_base, tidmask);
9834 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
9835 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
9838 * Tag Queuing is disabled for the BIOS which runs in polled
9839 * mode and would see no benefit from Tag Queuing. Also by
9840 * disabling Tag Queuing in the BIOS devices with Tag Queuing
9841 * bugs will at least work with the BIOS.
9843 if ((adv_dvc->tagqng_able & tidmask) &&
9844 sdev->tagged_supported) {
9845 unsigned short cfg_word;
9846 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
9847 cfg_word |= tidmask;
9848 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
9849 cfg_word);
9850 AdvWriteByteLram(iop_base,
9851 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
9852 adv_dvc->max_dvc_qng);
9856 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
9857 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
9858 adv_dvc->max_dvc_qng);
9859 } else {
9860 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
9865 * Set the number of commands to queue per device for the
9866 * specified host adapter.
9868 static int advansys_slave_configure(struct scsi_device *sdev)
9870 struct asc_board *boardp = shost_priv(sdev->host);
9872 if (ASC_NARROW_BOARD(boardp))
9873 advansys_narrow_slave_configure(sdev,
9874 &boardp->dvc_var.asc_dvc_var);
9875 else
9876 advansys_wide_slave_configure(sdev,
9877 &boardp->dvc_var.adv_dvc_var);
9879 return 0;
9882 static __le32 advansys_get_sense_buffer_dma(struct scsi_cmnd *scp)
9884 struct asc_board *board = shost_priv(scp->device->host);
9885 scp->SCp.dma_handle = dma_map_single(board->dev, scp->sense_buffer,
9886 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
9887 dma_cache_sync(board->dev, scp->sense_buffer,
9888 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
9889 return cpu_to_le32(scp->SCp.dma_handle);
9892 static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
9893 struct asc_scsi_q *asc_scsi_q)
9895 struct asc_dvc_var *asc_dvc = &boardp->dvc_var.asc_dvc_var;
9896 int use_sg;
9898 memset(asc_scsi_q, 0, sizeof(*asc_scsi_q));
9901 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
9903 asc_scsi_q->q2.srb_ptr = advansys_ptr_to_srb(asc_dvc, scp);
9904 if (asc_scsi_q->q2.srb_ptr == BAD_SRB) {
9905 scp->result = HOST_BYTE(DID_SOFT_ERROR);
9906 return ASC_ERROR;
9910 * Build the ASC_SCSI_Q request.
9912 asc_scsi_q->cdbptr = &scp->cmnd[0];
9913 asc_scsi_q->q2.cdb_len = scp->cmd_len;
9914 asc_scsi_q->q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
9915 asc_scsi_q->q1.target_lun = scp->device->lun;
9916 asc_scsi_q->q2.target_ix =
9917 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
9918 asc_scsi_q->q1.sense_addr = advansys_get_sense_buffer_dma(scp);
9919 asc_scsi_q->q1.sense_len = SCSI_SENSE_BUFFERSIZE;
9922 * If there are any outstanding requests for the current target,
9923 * then every 255th request send an ORDERED request. This heuristic
9924 * tries to retain the benefit of request sorting while preventing
9925 * request starvation. 255 is the max number of tags or pending commands
9926 * a device may have outstanding.
9928 * The request count is incremented below for every successfully
9929 * started request.
9932 if ((asc_dvc->cur_dvc_qng[scp->device->id] > 0) &&
9933 (boardp->reqcnt[scp->device->id] % 255) == 0) {
9934 asc_scsi_q->q2.tag_code = MSG_ORDERED_TAG;
9935 } else {
9936 asc_scsi_q->q2.tag_code = MSG_SIMPLE_TAG;
9939 /* Build ASC_SCSI_Q */
9940 use_sg = scsi_dma_map(scp);
9941 if (use_sg != 0) {
9942 int sgcnt;
9943 struct scatterlist *slp;
9944 struct asc_sg_head *asc_sg_head;
9946 if (use_sg > scp->device->host->sg_tablesize) {
9947 scmd_printk(KERN_ERR, scp, "use_sg %d > "
9948 "sg_tablesize %d\n", use_sg,
9949 scp->device->host->sg_tablesize);
9950 scsi_dma_unmap(scp);
9951 scp->result = HOST_BYTE(DID_ERROR);
9952 return ASC_ERROR;
9955 asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) +
9956 use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC);
9957 if (!asc_sg_head) {
9958 scsi_dma_unmap(scp);
9959 scp->result = HOST_BYTE(DID_SOFT_ERROR);
9960 return ASC_ERROR;
9963 asc_scsi_q->q1.cntl |= QC_SG_HEAD;
9964 asc_scsi_q->sg_head = asc_sg_head;
9965 asc_scsi_q->q1.data_cnt = 0;
9966 asc_scsi_q->q1.data_addr = 0;
9967 /* This is a byte value, otherwise it would need to be swapped. */
9968 asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg;
9969 ASC_STATS_ADD(scp->device->host, xfer_elem,
9970 asc_sg_head->entry_cnt);
9973 * Convert scatter-gather list into ASC_SG_HEAD list.
9975 scsi_for_each_sg(scp, slp, use_sg, sgcnt) {
9976 asc_sg_head->sg_list[sgcnt].addr =
9977 cpu_to_le32(sg_dma_address(slp));
9978 asc_sg_head->sg_list[sgcnt].bytes =
9979 cpu_to_le32(sg_dma_len(slp));
9980 ASC_STATS_ADD(scp->device->host, xfer_sect,
9981 DIV_ROUND_UP(sg_dma_len(slp), 512));
9985 ASC_STATS(scp->device->host, xfer_cnt);
9987 ASC_DBG_PRT_ASC_SCSI_Q(2, asc_scsi_q);
9988 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
9990 return ASC_NOERROR;
9994 * Build scatter-gather list for Adv Library (Wide Board).
9996 * Additional ADV_SG_BLOCK structures will need to be allocated
9997 * if the total number of scatter-gather elements exceeds
9998 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
9999 * assumed to be physically contiguous.
10001 * Return:
10002 * ADV_SUCCESS(1) - SG List successfully created
10003 * ADV_ERROR(-1) - SG List creation failed
10005 static int
10006 adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
10007 int use_sg)
10009 adv_sgblk_t *sgblkp;
10010 ADV_SCSI_REQ_Q *scsiqp;
10011 struct scatterlist *slp;
10012 int sg_elem_cnt;
10013 ADV_SG_BLOCK *sg_block, *prev_sg_block;
10014 ADV_PADDR sg_block_paddr;
10015 int i;
10017 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
10018 slp = scsi_sglist(scp);
10019 sg_elem_cnt = use_sg;
10020 prev_sg_block = NULL;
10021 reqp->sgblkp = NULL;
10023 for (;;) {
10025 * Allocate a 'adv_sgblk_t' structure from the board free
10026 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
10027 * (15) scatter-gather elements.
10029 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
10030 ASC_DBG(1, "no free adv_sgblk_t\n");
10031 ASC_STATS(scp->device->host, adv_build_nosg);
10034 * Allocation failed. Free 'adv_sgblk_t' structures
10035 * already allocated for the request.
10037 while ((sgblkp = reqp->sgblkp) != NULL) {
10038 /* Remove 'sgblkp' from the request list. */
10039 reqp->sgblkp = sgblkp->next_sgblkp;
10041 /* Add 'sgblkp' to the board free list. */
10042 sgblkp->next_sgblkp = boardp->adv_sgblkp;
10043 boardp->adv_sgblkp = sgblkp;
10045 return ASC_BUSY;
10048 /* Complete 'adv_sgblk_t' board allocation. */
10049 boardp->adv_sgblkp = sgblkp->next_sgblkp;
10050 sgblkp->next_sgblkp = NULL;
10053 * Get 8 byte aligned virtual and physical addresses
10054 * for the allocated ADV_SG_BLOCK structure.
10056 sg_block = (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
10057 sg_block_paddr = virt_to_bus(sg_block);
10060 * Check if this is the first 'adv_sgblk_t' for the
10061 * request.
10063 if (reqp->sgblkp == NULL) {
10064 /* Request's first scatter-gather block. */
10065 reqp->sgblkp = sgblkp;
10068 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
10069 * address pointers.
10071 scsiqp->sg_list_ptr = sg_block;
10072 scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
10073 } else {
10074 /* Request's second or later scatter-gather block. */
10075 sgblkp->next_sgblkp = reqp->sgblkp;
10076 reqp->sgblkp = sgblkp;
10079 * Point the previous ADV_SG_BLOCK structure to
10080 * the newly allocated ADV_SG_BLOCK structure.
10082 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
10085 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
10086 sg_block->sg_list[i].sg_addr =
10087 cpu_to_le32(sg_dma_address(slp));
10088 sg_block->sg_list[i].sg_count =
10089 cpu_to_le32(sg_dma_len(slp));
10090 ASC_STATS_ADD(scp->device->host, xfer_sect,
10091 DIV_ROUND_UP(sg_dma_len(slp), 512));
10093 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
10094 sg_block->sg_cnt = i + 1;
10095 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
10096 return ADV_SUCCESS;
10098 slp++;
10100 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
10101 prev_sg_block = sg_block;
10106 * Build a request structure for the Adv Library (Wide Board).
10108 * If an adv_req_t can not be allocated to issue the request,
10109 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
10111 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
10112 * microcode for DMA addresses or math operations are byte swapped
10113 * to little-endian order.
10115 static int
10116 adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
10117 ADV_SCSI_REQ_Q **adv_scsiqpp)
10119 adv_req_t *reqp;
10120 ADV_SCSI_REQ_Q *scsiqp;
10121 int i;
10122 int ret;
10123 int use_sg;
10126 * Allocate an adv_req_t structure from the board to execute
10127 * the command.
10129 if (boardp->adv_reqp == NULL) {
10130 ASC_DBG(1, "no free adv_req_t\n");
10131 ASC_STATS(scp->device->host, adv_build_noreq);
10132 return ASC_BUSY;
10133 } else {
10134 reqp = boardp->adv_reqp;
10135 boardp->adv_reqp = reqp->next_reqp;
10136 reqp->next_reqp = NULL;
10140 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
10142 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
10145 * Initialize the structure.
10147 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
10150 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
10152 scsiqp->srb_ptr = ADV_VADDR_TO_U32(reqp);
10155 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
10157 reqp->cmndp = scp;
10160 * Build the ADV_SCSI_REQ_Q request.
10163 /* Set CDB length and copy it to the request structure. */
10164 scsiqp->cdb_len = scp->cmd_len;
10165 /* Copy first 12 CDB bytes to cdb[]. */
10166 for (i = 0; i < scp->cmd_len && i < 12; i++) {
10167 scsiqp->cdb[i] = scp->cmnd[i];
10169 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
10170 for (; i < scp->cmd_len; i++) {
10171 scsiqp->cdb16[i - 12] = scp->cmnd[i];
10174 scsiqp->target_id = scp->device->id;
10175 scsiqp->target_lun = scp->device->lun;
10177 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
10178 scsiqp->sense_len = SCSI_SENSE_BUFFERSIZE;
10180 /* Build ADV_SCSI_REQ_Q */
10182 use_sg = scsi_dma_map(scp);
10183 if (use_sg == 0) {
10184 /* Zero-length transfer */
10185 reqp->sgblkp = NULL;
10186 scsiqp->data_cnt = 0;
10187 scsiqp->vdata_addr = NULL;
10189 scsiqp->data_addr = 0;
10190 scsiqp->sg_list_ptr = NULL;
10191 scsiqp->sg_real_addr = 0;
10192 } else {
10193 if (use_sg > ADV_MAX_SG_LIST) {
10194 scmd_printk(KERN_ERR, scp, "use_sg %d > "
10195 "ADV_MAX_SG_LIST %d\n", use_sg,
10196 scp->device->host->sg_tablesize);
10197 scsi_dma_unmap(scp);
10198 scp->result = HOST_BYTE(DID_ERROR);
10201 * Free the 'adv_req_t' structure by adding it back
10202 * to the board free list.
10204 reqp->next_reqp = boardp->adv_reqp;
10205 boardp->adv_reqp = reqp;
10207 return ASC_ERROR;
10210 scsiqp->data_cnt = cpu_to_le32(scsi_bufflen(scp));
10212 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
10213 if (ret != ADV_SUCCESS) {
10215 * Free the adv_req_t structure by adding it back to
10216 * the board free list.
10218 reqp->next_reqp = boardp->adv_reqp;
10219 boardp->adv_reqp = reqp;
10221 return ret;
10224 ASC_STATS_ADD(scp->device->host, xfer_elem, use_sg);
10227 ASC_STATS(scp->device->host, xfer_cnt);
10229 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
10230 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
10232 *adv_scsiqpp = scsiqp;
10234 return ASC_NOERROR;
10237 static int AscSgListToQueue(int sg_list)
10239 int n_sg_list_qs;
10241 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
10242 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
10243 n_sg_list_qs++;
10244 return n_sg_list_qs + 1;
10247 static uint
10248 AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
10250 uint cur_used_qs;
10251 uint cur_free_qs;
10252 ASC_SCSI_BIT_ID_TYPE target_id;
10253 uchar tid_no;
10255 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
10256 tid_no = ASC_TIX_TO_TID(target_ix);
10257 if ((asc_dvc->unit_not_ready & target_id) ||
10258 (asc_dvc->queue_full_or_busy & target_id)) {
10259 return 0;
10261 if (n_qs == 1) {
10262 cur_used_qs = (uint) asc_dvc->cur_total_qng +
10263 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
10264 } else {
10265 cur_used_qs = (uint) asc_dvc->cur_total_qng +
10266 (uint) ASC_MIN_FREE_Q;
10268 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
10269 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
10270 if (asc_dvc->cur_dvc_qng[tid_no] >=
10271 asc_dvc->max_dvc_qng[tid_no]) {
10272 return 0;
10274 return cur_free_qs;
10276 if (n_qs > 1) {
10277 if ((n_qs > asc_dvc->last_q_shortage)
10278 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
10279 asc_dvc->last_q_shortage = n_qs;
10282 return 0;
10285 static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
10287 ushort q_addr;
10288 uchar next_qp;
10289 uchar q_status;
10291 q_addr = ASC_QNO_TO_QADDR(free_q_head);
10292 q_status = (uchar)AscReadLramByte(iop_base,
10293 (ushort)(q_addr +
10294 ASC_SCSIQ_B_STATUS));
10295 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10296 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END))
10297 return next_qp;
10298 return ASC_QLINK_END;
10301 static uchar
10302 AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
10304 uchar i;
10306 for (i = 0; i < n_free_q; i++) {
10307 free_q_head = AscAllocFreeQueue(iop_base, free_q_head);
10308 if (free_q_head == ASC_QLINK_END)
10309 break;
10311 return free_q_head;
10315 * void
10316 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10318 * Calling/Exit State:
10319 * none
10321 * Description:
10322 * Output an ASC_SCSI_Q structure to the chip
10324 static void
10325 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10327 int i;
10329 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
10330 AscSetChipLramAddr(iop_base, s_addr);
10331 for (i = 0; i < 2 * words; i += 2) {
10332 if (i == 4 || i == 20) {
10333 continue;
10335 outpw(iop_base + IOP_RAM_DATA,
10336 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
10340 static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10342 ushort q_addr;
10343 uchar tid_no;
10344 uchar sdtr_data;
10345 uchar syn_period_ix;
10346 uchar syn_offset;
10347 PortAddr iop_base;
10349 iop_base = asc_dvc->iop_base;
10350 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
10351 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
10352 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
10353 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10354 syn_period_ix =
10355 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
10356 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
10357 AscMsgOutSDTR(asc_dvc,
10358 asc_dvc->sdtr_period_tbl[syn_period_ix],
10359 syn_offset);
10360 scsiq->q1.cntl |= QC_MSG_OUT;
10362 q_addr = ASC_QNO_TO_QADDR(q_no);
10363 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
10364 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10366 scsiq->q1.status = QS_FREE;
10367 AscMemWordCopyPtrToLram(iop_base,
10368 q_addr + ASC_SCSIQ_CDB_BEG,
10369 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
10371 DvcPutScsiQ(iop_base,
10372 q_addr + ASC_SCSIQ_CPY_BEG,
10373 (uchar *)&scsiq->q1.cntl,
10374 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
10375 AscWriteLramWord(iop_base,
10376 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
10377 (ushort)(((ushort)scsiq->q1.
10378 q_no << 8) | (ushort)QS_READY));
10379 return 1;
10382 static int
10383 AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10385 int sta;
10386 int i;
10387 ASC_SG_HEAD *sg_head;
10388 ASC_SG_LIST_Q scsi_sg_q;
10389 ASC_DCNT saved_data_addr;
10390 ASC_DCNT saved_data_cnt;
10391 PortAddr iop_base;
10392 ushort sg_list_dwords;
10393 ushort sg_index;
10394 ushort sg_entry_cnt;
10395 ushort q_addr;
10396 uchar next_qp;
10398 iop_base = asc_dvc->iop_base;
10399 sg_head = scsiq->sg_head;
10400 saved_data_addr = scsiq->q1.data_addr;
10401 saved_data_cnt = scsiq->q1.data_cnt;
10402 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
10403 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
10404 #if CC_VERY_LONG_SG_LIST
10406 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
10407 * then not all SG elements will fit in the allocated queues.
10408 * The rest of the SG elements will be copied when the RISC
10409 * completes the SG elements that fit and halts.
10411 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10413 * Set sg_entry_cnt to be the number of SG elements that
10414 * will fit in the allocated SG queues. It is minus 1, because
10415 * the first SG element is handled above. ASC_MAX_SG_LIST is
10416 * already inflated by 1 to account for this. For example it
10417 * may be 50 which is 1 + 7 queues * 7 SG elements.
10419 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10422 * Keep track of remaining number of SG elements that will
10423 * need to be handled from a_isr.c.
10425 scsiq->remain_sg_entry_cnt =
10426 sg_head->entry_cnt - ASC_MAX_SG_LIST;
10427 } else {
10428 #endif /* CC_VERY_LONG_SG_LIST */
10430 * Set sg_entry_cnt to be the number of SG elements that
10431 * will fit in the allocated SG queues. It is minus 1, because
10432 * the first SG element is handled above.
10434 sg_entry_cnt = sg_head->entry_cnt - 1;
10435 #if CC_VERY_LONG_SG_LIST
10437 #endif /* CC_VERY_LONG_SG_LIST */
10438 if (sg_entry_cnt != 0) {
10439 scsiq->q1.cntl |= QC_SG_HEAD;
10440 q_addr = ASC_QNO_TO_QADDR(q_no);
10441 sg_index = 1;
10442 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
10443 scsi_sg_q.sg_head_qp = q_no;
10444 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10445 for (i = 0; i < sg_head->queue_cnt; i++) {
10446 scsi_sg_q.seq_no = i + 1;
10447 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
10448 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
10449 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10450 if (i == 0) {
10451 scsi_sg_q.sg_list_cnt =
10452 ASC_SG_LIST_PER_Q;
10453 scsi_sg_q.sg_cur_list_cnt =
10454 ASC_SG_LIST_PER_Q;
10455 } else {
10456 scsi_sg_q.sg_list_cnt =
10457 ASC_SG_LIST_PER_Q - 1;
10458 scsi_sg_q.sg_cur_list_cnt =
10459 ASC_SG_LIST_PER_Q - 1;
10461 } else {
10462 #if CC_VERY_LONG_SG_LIST
10464 * This is the last SG queue in the list of
10465 * allocated SG queues. If there are more
10466 * SG elements than will fit in the allocated
10467 * queues, then set the QCSG_SG_XFER_MORE flag.
10469 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10470 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10471 } else {
10472 #endif /* CC_VERY_LONG_SG_LIST */
10473 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10474 #if CC_VERY_LONG_SG_LIST
10476 #endif /* CC_VERY_LONG_SG_LIST */
10477 sg_list_dwords = sg_entry_cnt << 1;
10478 if (i == 0) {
10479 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
10480 scsi_sg_q.sg_cur_list_cnt =
10481 sg_entry_cnt;
10482 } else {
10483 scsi_sg_q.sg_list_cnt =
10484 sg_entry_cnt - 1;
10485 scsi_sg_q.sg_cur_list_cnt =
10486 sg_entry_cnt - 1;
10488 sg_entry_cnt = 0;
10490 next_qp = AscReadLramByte(iop_base,
10491 (ushort)(q_addr +
10492 ASC_SCSIQ_B_FWD));
10493 scsi_sg_q.q_no = next_qp;
10494 q_addr = ASC_QNO_TO_QADDR(next_qp);
10495 AscMemWordCopyPtrToLram(iop_base,
10496 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10497 (uchar *)&scsi_sg_q,
10498 sizeof(ASC_SG_LIST_Q) >> 1);
10499 AscMemDWordCopyPtrToLram(iop_base,
10500 q_addr + ASC_SGQ_LIST_BEG,
10501 (uchar *)&sg_head->
10502 sg_list[sg_index],
10503 sg_list_dwords);
10504 sg_index += ASC_SG_LIST_PER_Q;
10505 scsiq->next_sg_index = sg_index;
10507 } else {
10508 scsiq->q1.cntl &= ~QC_SG_HEAD;
10510 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
10511 scsiq->q1.data_addr = saved_data_addr;
10512 scsiq->q1.data_cnt = saved_data_cnt;
10513 return (sta);
10516 static int
10517 AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
10519 PortAddr iop_base;
10520 uchar free_q_head;
10521 uchar uninitialized_var(next_qp);
10522 uchar tid_no;
10523 uchar target_ix;
10524 int sta;
10526 iop_base = asc_dvc->iop_base;
10527 target_ix = scsiq->q2.target_ix;
10528 tid_no = ASC_TIX_TO_TID(target_ix);
10529 sta = 0;
10530 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
10531 if (n_q_required > 1) {
10532 next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head,
10533 (uchar)n_q_required);
10534 if (next_qp != ASC_QLINK_END) {
10535 asc_dvc->last_q_shortage = 0;
10536 scsiq->sg_head->queue_cnt = n_q_required - 1;
10537 scsiq->q1.q_no = free_q_head;
10538 sta = AscPutReadySgListQueue(asc_dvc, scsiq,
10539 free_q_head);
10541 } else if (n_q_required == 1) {
10542 next_qp = AscAllocFreeQueue(iop_base, free_q_head);
10543 if (next_qp != ASC_QLINK_END) {
10544 scsiq->q1.q_no = free_q_head;
10545 sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head);
10548 if (sta == 1) {
10549 AscPutVarFreeQHead(iop_base, next_qp);
10550 asc_dvc->cur_total_qng += n_q_required;
10551 asc_dvc->cur_dvc_qng[tid_no]++;
10553 return sta;
10556 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
10557 static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
10558 INQUIRY,
10559 REQUEST_SENSE,
10560 READ_CAPACITY,
10561 READ_TOC,
10562 MODE_SELECT,
10563 MODE_SENSE,
10564 MODE_SELECT_10,
10565 MODE_SENSE_10,
10566 0xFF,
10567 0xFF,
10568 0xFF,
10569 0xFF,
10570 0xFF,
10571 0xFF,
10572 0xFF,
10573 0xFF
10576 static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
10578 PortAddr iop_base;
10579 int sta;
10580 int n_q_required;
10581 int disable_syn_offset_one_fix;
10582 int i;
10583 ASC_PADDR addr;
10584 ushort sg_entry_cnt = 0;
10585 ushort sg_entry_cnt_minus_one = 0;
10586 uchar target_ix;
10587 uchar tid_no;
10588 uchar sdtr_data;
10589 uchar extra_bytes;
10590 uchar scsi_cmd;
10591 uchar disable_cmd;
10592 ASC_SG_HEAD *sg_head;
10593 ASC_DCNT data_cnt;
10595 iop_base = asc_dvc->iop_base;
10596 sg_head = scsiq->sg_head;
10597 if (asc_dvc->err_code != 0)
10598 return (ERR);
10599 scsiq->q1.q_no = 0;
10600 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
10601 scsiq->q1.extra_bytes = 0;
10603 sta = 0;
10604 target_ix = scsiq->q2.target_ix;
10605 tid_no = ASC_TIX_TO_TID(target_ix);
10606 n_q_required = 1;
10607 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
10608 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
10609 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
10610 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10611 AscMsgOutSDTR(asc_dvc,
10612 asc_dvc->
10613 sdtr_period_tbl[(sdtr_data >> 4) &
10614 (uchar)(asc_dvc->
10615 max_sdtr_index -
10616 1)],
10617 (uchar)(sdtr_data & (uchar)
10618 ASC_SYN_MAX_OFFSET));
10619 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
10622 if (asc_dvc->in_critical_cnt != 0) {
10623 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
10624 return (ERR);
10626 asc_dvc->in_critical_cnt++;
10627 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10628 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
10629 asc_dvc->in_critical_cnt--;
10630 return (ERR);
10632 #if !CC_VERY_LONG_SG_LIST
10633 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
10634 asc_dvc->in_critical_cnt--;
10635 return (ERR);
10637 #endif /* !CC_VERY_LONG_SG_LIST */
10638 if (sg_entry_cnt == 1) {
10639 scsiq->q1.data_addr =
10640 (ADV_PADDR)sg_head->sg_list[0].addr;
10641 scsiq->q1.data_cnt =
10642 (ADV_DCNT)sg_head->sg_list[0].bytes;
10643 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
10645 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
10647 scsi_cmd = scsiq->cdbptr[0];
10648 disable_syn_offset_one_fix = FALSE;
10649 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
10650 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
10651 if (scsiq->q1.cntl & QC_SG_HEAD) {
10652 data_cnt = 0;
10653 for (i = 0; i < sg_entry_cnt; i++) {
10654 data_cnt +=
10655 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
10656 bytes);
10658 } else {
10659 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10661 if (data_cnt != 0UL) {
10662 if (data_cnt < 512UL) {
10663 disable_syn_offset_one_fix = TRUE;
10664 } else {
10665 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
10666 i++) {
10667 disable_cmd =
10668 _syn_offset_one_disable_cmd[i];
10669 if (disable_cmd == 0xFF) {
10670 break;
10672 if (scsi_cmd == disable_cmd) {
10673 disable_syn_offset_one_fix =
10674 TRUE;
10675 break;
10681 if (disable_syn_offset_one_fix) {
10682 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10683 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
10684 ASC_TAG_FLAG_DISABLE_DISCONNECT);
10685 } else {
10686 scsiq->q2.tag_code &= 0x27;
10688 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10689 if (asc_dvc->bug_fix_cntl) {
10690 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10691 if ((scsi_cmd == READ_6) ||
10692 (scsi_cmd == READ_10)) {
10693 addr =
10694 (ADV_PADDR)le32_to_cpu(sg_head->
10695 sg_list
10696 [sg_entry_cnt_minus_one].
10697 addr) +
10698 (ADV_DCNT)le32_to_cpu(sg_head->
10699 sg_list
10700 [sg_entry_cnt_minus_one].
10701 bytes);
10702 extra_bytes =
10703 (uchar)((ushort)addr & 0x0003);
10704 if ((extra_bytes != 0)
10706 ((scsiq->q2.
10707 tag_code &
10708 ASC_TAG_FLAG_EXTRA_BYTES)
10709 == 0)) {
10710 scsiq->q2.tag_code |=
10711 ASC_TAG_FLAG_EXTRA_BYTES;
10712 scsiq->q1.extra_bytes =
10713 extra_bytes;
10714 data_cnt =
10715 le32_to_cpu(sg_head->
10716 sg_list
10717 [sg_entry_cnt_minus_one].
10718 bytes);
10719 data_cnt -=
10720 (ASC_DCNT) extra_bytes;
10721 sg_head->
10722 sg_list
10723 [sg_entry_cnt_minus_one].
10724 bytes =
10725 cpu_to_le32(data_cnt);
10730 sg_head->entry_to_copy = sg_head->entry_cnt;
10731 #if CC_VERY_LONG_SG_LIST
10733 * Set the sg_entry_cnt to the maximum possible. The rest of
10734 * the SG elements will be copied when the RISC completes the
10735 * SG elements that fit and halts.
10737 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
10738 sg_entry_cnt = ASC_MAX_SG_LIST;
10740 #endif /* CC_VERY_LONG_SG_LIST */
10741 n_q_required = AscSgListToQueue(sg_entry_cnt);
10742 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
10743 (uint) n_q_required)
10744 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10745 if ((sta =
10746 AscSendScsiQueue(asc_dvc, scsiq,
10747 n_q_required)) == 1) {
10748 asc_dvc->in_critical_cnt--;
10749 return (sta);
10752 } else {
10753 if (asc_dvc->bug_fix_cntl) {
10754 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10755 if ((scsi_cmd == READ_6) ||
10756 (scsi_cmd == READ_10)) {
10757 addr =
10758 le32_to_cpu(scsiq->q1.data_addr) +
10759 le32_to_cpu(scsiq->q1.data_cnt);
10760 extra_bytes =
10761 (uchar)((ushort)addr & 0x0003);
10762 if ((extra_bytes != 0)
10764 ((scsiq->q2.
10765 tag_code &
10766 ASC_TAG_FLAG_EXTRA_BYTES)
10767 == 0)) {
10768 data_cnt =
10769 le32_to_cpu(scsiq->q1.
10770 data_cnt);
10771 if (((ushort)data_cnt & 0x01FF)
10772 == 0) {
10773 scsiq->q2.tag_code |=
10774 ASC_TAG_FLAG_EXTRA_BYTES;
10775 data_cnt -= (ASC_DCNT)
10776 extra_bytes;
10777 scsiq->q1.data_cnt =
10778 cpu_to_le32
10779 (data_cnt);
10780 scsiq->q1.extra_bytes =
10781 extra_bytes;
10787 n_q_required = 1;
10788 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
10789 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10790 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
10791 n_q_required)) == 1) {
10792 asc_dvc->in_critical_cnt--;
10793 return (sta);
10797 asc_dvc->in_critical_cnt--;
10798 return (sta);
10802 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
10804 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
10805 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
10806 * RISC to notify it a new command is ready to be executed.
10808 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
10809 * set to SCSI_MAX_RETRY.
10811 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
10812 * for DMA addresses or math operations are byte swapped to little-endian
10813 * order.
10815 * Return:
10816 * ADV_SUCCESS(1) - The request was successfully queued.
10817 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
10818 * request completes.
10819 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
10820 * host IC error.
10822 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
10824 AdvPortAddr iop_base;
10825 ADV_PADDR req_paddr;
10826 ADV_CARR_T *new_carrp;
10829 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
10831 if (scsiq->target_id > ADV_MAX_TID) {
10832 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
10833 scsiq->done_status = QD_WITH_ERROR;
10834 return ADV_ERROR;
10837 iop_base = asc_dvc->iop_base;
10840 * Allocate a carrier ensuring at least one carrier always
10841 * remains on the freelist and initialize fields.
10843 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
10844 return ADV_BUSY;
10846 asc_dvc->carr_freelist = (ADV_CARR_T *)
10847 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
10848 asc_dvc->carr_pending_cnt++;
10851 * Set the carrier to be a stopper by setting 'next_vpa'
10852 * to the stopper value. The current stopper will be changed
10853 * below to point to the new stopper.
10855 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
10858 * Clear the ADV_SCSI_REQ_Q done flag.
10860 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
10862 req_paddr = virt_to_bus(scsiq);
10863 BUG_ON(req_paddr & 31);
10864 /* Wait for assertion before making little-endian */
10865 req_paddr = cpu_to_le32(req_paddr);
10867 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
10868 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
10869 scsiq->scsiq_rptr = req_paddr;
10871 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
10873 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
10874 * order during initialization.
10876 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
10879 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
10880 * the microcode. The newly allocated stopper will become the new
10881 * stopper.
10883 asc_dvc->icq_sp->areq_vpa = req_paddr;
10886 * Set the 'next_vpa' pointer for the old stopper to be the
10887 * physical address of the new stopper. The RISC can only
10888 * follow physical addresses.
10890 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
10893 * Set the host adapter stopper pointer to point to the new carrier.
10895 asc_dvc->icq_sp = new_carrp;
10897 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
10898 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
10900 * Tickle the RISC to tell it to read its Command Queue Head pointer.
10902 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
10903 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
10905 * Clear the tickle value. In the ASC-3550 the RISC flag
10906 * command 'clr_tickle_a' does not work unless the host
10907 * value is cleared.
10909 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
10910 ADV_TICKLE_NOP);
10912 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
10914 * Notify the RISC a carrier is ready by writing the physical
10915 * address of the new carrier stopper to the COMMA register.
10917 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
10918 le32_to_cpu(new_carrp->carr_pa));
10921 return ADV_SUCCESS;
10925 * Execute a single 'Scsi_Cmnd'.
10927 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
10929 int ret, err_code;
10930 struct asc_board *boardp = shost_priv(scp->device->host);
10932 ASC_DBG(1, "scp 0x%p\n", scp);
10934 if (ASC_NARROW_BOARD(boardp)) {
10935 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
10936 struct asc_scsi_q asc_scsi_q;
10938 /* asc_build_req() can not return ASC_BUSY. */
10939 ret = asc_build_req(boardp, scp, &asc_scsi_q);
10940 if (ret == ASC_ERROR) {
10941 ASC_STATS(scp->device->host, build_error);
10942 return ASC_ERROR;
10945 ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q);
10946 kfree(asc_scsi_q.sg_head);
10947 err_code = asc_dvc->err_code;
10948 } else {
10949 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
10950 ADV_SCSI_REQ_Q *uninitialized_var(adv_scsiqp);
10952 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
10953 case ASC_NOERROR:
10954 ASC_DBG(3, "adv_build_req ASC_NOERROR\n");
10955 break;
10956 case ASC_BUSY:
10957 ASC_DBG(1, "adv_build_req ASC_BUSY\n");
10959 * The asc_stats fields 'adv_build_noreq' and
10960 * 'adv_build_nosg' count wide board busy conditions.
10961 * They are updated in adv_build_req and
10962 * adv_get_sglist, respectively.
10964 return ASC_BUSY;
10965 case ASC_ERROR:
10966 default:
10967 ASC_DBG(1, "adv_build_req ASC_ERROR\n");
10968 ASC_STATS(scp->device->host, build_error);
10969 return ASC_ERROR;
10972 ret = AdvExeScsiQueue(adv_dvc, adv_scsiqp);
10973 err_code = adv_dvc->err_code;
10976 switch (ret) {
10977 case ASC_NOERROR:
10978 ASC_STATS(scp->device->host, exe_noerror);
10980 * Increment monotonically increasing per device
10981 * successful request counter. Wrapping doesn't matter.
10983 boardp->reqcnt[scp->device->id]++;
10984 ASC_DBG(1, "ExeScsiQueue() ASC_NOERROR\n");
10985 break;
10986 case ASC_BUSY:
10987 ASC_STATS(scp->device->host, exe_busy);
10988 break;
10989 case ASC_ERROR:
10990 scmd_printk(KERN_ERR, scp, "ExeScsiQueue() ASC_ERROR, "
10991 "err_code 0x%x\n", err_code);
10992 ASC_STATS(scp->device->host, exe_error);
10993 scp->result = HOST_BYTE(DID_ERROR);
10994 break;
10995 default:
10996 scmd_printk(KERN_ERR, scp, "ExeScsiQueue() unknown, "
10997 "err_code 0x%x\n", err_code);
10998 ASC_STATS(scp->device->host, exe_unknown);
10999 scp->result = HOST_BYTE(DID_ERROR);
11000 break;
11003 ASC_DBG(1, "end\n");
11004 return ret;
11008 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
11010 * This function always returns 0. Command return status is saved
11011 * in the 'scp' result field.
11013 static int
11014 advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
11016 struct Scsi_Host *shost = scp->device->host;
11017 int asc_res, result = 0;
11019 ASC_STATS(shost, queuecommand);
11020 scp->scsi_done = done;
11022 asc_res = asc_execute_scsi_cmnd(scp);
11024 switch (asc_res) {
11025 case ASC_NOERROR:
11026 break;
11027 case ASC_BUSY:
11028 result = SCSI_MLQUEUE_HOST_BUSY;
11029 break;
11030 case ASC_ERROR:
11031 default:
11032 asc_scsi_done(scp);
11033 break;
11036 return result;
11039 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
11041 PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11042 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
11043 return inpw(eisa_cfg_iop);
11047 * Return the BIOS address of the adapter at the specified
11048 * I/O port and with the specified bus type.
11050 static unsigned short __devinit
11051 AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
11053 unsigned short cfg_lsw;
11054 unsigned short bios_addr;
11057 * The PCI BIOS is re-located by the motherboard BIOS. Because
11058 * of this the driver can not determine where a PCI BIOS is
11059 * loaded and executes.
11061 if (bus_type & ASC_IS_PCI)
11062 return 0;
11064 if ((bus_type & ASC_IS_EISA) != 0) {
11065 cfg_lsw = AscGetEisaChipCfg(iop_base);
11066 cfg_lsw &= 0x000F;
11067 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
11068 return bios_addr;
11071 cfg_lsw = AscGetChipCfgLsw(iop_base);
11074 * ISA PnP uses the top bit as the 32K BIOS flag
11076 if (bus_type == ASC_IS_ISAPNP)
11077 cfg_lsw &= 0x7FFF;
11078 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
11079 return bios_addr;
11082 static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
11084 ushort cfg_lsw;
11086 if (AscGetChipScsiID(iop_base) == new_host_id) {
11087 return (new_host_id);
11089 cfg_lsw = AscGetChipCfgLsw(iop_base);
11090 cfg_lsw &= 0xF8FF;
11091 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
11092 AscSetChipCfgLsw(iop_base, cfg_lsw);
11093 return (AscGetChipScsiID(iop_base));
11096 static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
11098 unsigned char sc;
11100 AscSetBank(iop_base, 1);
11101 sc = inp(iop_base + IOP_REG_SC);
11102 AscSetBank(iop_base, 0);
11103 return sc;
11106 static unsigned char __devinit
11107 AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
11109 if (bus_type & ASC_IS_EISA) {
11110 PortAddr eisa_iop;
11111 unsigned char revision;
11112 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11113 (PortAddr) ASC_EISA_REV_IOP_MASK;
11114 revision = inp(eisa_iop);
11115 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
11117 return AscGetChipVerNo(iop_base);
11120 #ifdef CONFIG_ISA
11121 static void __devinit AscEnableIsaDma(uchar dma_channel)
11123 if (dma_channel < 4) {
11124 outp(0x000B, (ushort)(0xC0 | dma_channel));
11125 outp(0x000A, dma_channel);
11126 } else if (dma_channel < 8) {
11127 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
11128 outp(0x00D4, (ushort)(dma_channel - 4));
11131 #endif /* CONFIG_ISA */
11133 static int AscStopQueueExe(PortAddr iop_base)
11135 int count = 0;
11137 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11138 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11139 ASC_STOP_REQ_RISC_STOP);
11140 do {
11141 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11142 ASC_STOP_ACK_RISC_STOP) {
11143 return (1);
11145 mdelay(100);
11146 } while (count++ < 20);
11148 return (0);
11151 static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
11153 if (bus_type & ASC_IS_ISA)
11154 return ASC_MAX_ISA_DMA_COUNT;
11155 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
11156 return ASC_MAX_VL_DMA_COUNT;
11157 return ASC_MAX_PCI_DMA_COUNT;
11160 #ifdef CONFIG_ISA
11161 static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
11163 ushort channel;
11165 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
11166 if (channel == 0x03)
11167 return (0);
11168 else if (channel == 0x00)
11169 return (7);
11170 return (channel + 4);
11173 static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
11175 ushort cfg_lsw;
11176 uchar value;
11178 if ((dma_channel >= 5) && (dma_channel <= 7)) {
11179 if (dma_channel == 7)
11180 value = 0x00;
11181 else
11182 value = dma_channel - 4;
11183 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
11184 cfg_lsw |= value;
11185 AscSetChipCfgLsw(iop_base, cfg_lsw);
11186 return (AscGetIsaDmaChannel(iop_base));
11188 return 0;
11191 static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
11193 uchar speed_value;
11195 AscSetBank(iop_base, 1);
11196 speed_value = AscReadChipDmaSpeed(iop_base);
11197 speed_value &= 0x07;
11198 AscSetBank(iop_base, 0);
11199 return speed_value;
11202 static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
11204 speed_value &= 0x07;
11205 AscSetBank(iop_base, 1);
11206 AscWriteChipDmaSpeed(iop_base, speed_value);
11207 AscSetBank(iop_base, 0);
11208 return AscGetIsaDmaSpeed(iop_base);
11210 #endif /* CONFIG_ISA */
11212 static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
11214 int i;
11215 PortAddr iop_base;
11216 ushort warn_code;
11217 uchar chip_version;
11219 iop_base = asc_dvc->iop_base;
11220 warn_code = 0;
11221 asc_dvc->err_code = 0;
11222 if ((asc_dvc->bus_type &
11223 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
11224 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
11226 AscSetChipControl(iop_base, CC_HALT);
11227 AscSetChipStatus(iop_base, 0);
11228 asc_dvc->bug_fix_cntl = 0;
11229 asc_dvc->pci_fix_asyn_xfer = 0;
11230 asc_dvc->pci_fix_asyn_xfer_always = 0;
11231 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
11232 asc_dvc->sdtr_done = 0;
11233 asc_dvc->cur_total_qng = 0;
11234 asc_dvc->is_in_int = 0;
11235 asc_dvc->in_critical_cnt = 0;
11236 asc_dvc->last_q_shortage = 0;
11237 asc_dvc->use_tagged_qng = 0;
11238 asc_dvc->no_scam = 0;
11239 asc_dvc->unit_not_ready = 0;
11240 asc_dvc->queue_full_or_busy = 0;
11241 asc_dvc->redo_scam = 0;
11242 asc_dvc->res2 = 0;
11243 asc_dvc->min_sdtr_index = 0;
11244 asc_dvc->cfg->can_tagged_qng = 0;
11245 asc_dvc->cfg->cmd_qng_enabled = 0;
11246 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
11247 asc_dvc->init_sdtr = 0;
11248 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
11249 asc_dvc->scsi_reset_wait = 3;
11250 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
11251 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
11252 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
11253 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
11254 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
11255 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
11256 asc_dvc->cfg->chip_version = chip_version;
11257 asc_dvc->sdtr_period_tbl = asc_syn_xfer_period;
11258 asc_dvc->max_sdtr_index = 7;
11259 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
11260 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
11261 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
11262 asc_dvc->sdtr_period_tbl = asc_syn_ultra_xfer_period;
11263 asc_dvc->max_sdtr_index = 15;
11264 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
11265 AscSetExtraControl(iop_base,
11266 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11267 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
11268 AscSetExtraControl(iop_base,
11269 (SEC_ACTIVE_NEGATE |
11270 SEC_ENABLE_FILTER));
11273 if (asc_dvc->bus_type == ASC_IS_PCI) {
11274 AscSetExtraControl(iop_base,
11275 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11278 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
11279 #ifdef CONFIG_ISA
11280 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
11281 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
11282 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
11283 asc_dvc->bus_type = ASC_IS_ISAPNP;
11285 asc_dvc->cfg->isa_dma_channel =
11286 (uchar)AscGetIsaDmaChannel(iop_base);
11288 #endif /* CONFIG_ISA */
11289 for (i = 0; i <= ASC_MAX_TID; i++) {
11290 asc_dvc->cur_dvc_qng[i] = 0;
11291 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
11292 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
11293 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
11294 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
11296 return warn_code;
11299 static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
11301 int retry;
11303 for (retry = 0; retry < ASC_EEP_MAX_RETRY; retry++) {
11304 unsigned char read_back;
11305 AscSetChipEEPCmd(iop_base, cmd_reg);
11306 mdelay(1);
11307 read_back = AscGetChipEEPCmd(iop_base);
11308 if (read_back == cmd_reg)
11309 return 1;
11311 return 0;
11314 static void __devinit AscWaitEEPRead(void)
11316 mdelay(1);
11319 static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
11321 ushort read_wval;
11322 uchar cmd_reg;
11324 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11325 AscWaitEEPRead();
11326 cmd_reg = addr | ASC_EEP_CMD_READ;
11327 AscWriteEEPCmdReg(iop_base, cmd_reg);
11328 AscWaitEEPRead();
11329 read_wval = AscGetChipEEPData(iop_base);
11330 AscWaitEEPRead();
11331 return read_wval;
11334 static ushort __devinit
11335 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11337 ushort wval;
11338 ushort sum;
11339 ushort *wbuf;
11340 int cfg_beg;
11341 int cfg_end;
11342 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11343 int s_addr;
11345 wbuf = (ushort *)cfg_buf;
11346 sum = 0;
11347 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
11348 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11349 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11350 sum += *wbuf;
11352 if (bus_type & ASC_IS_VL) {
11353 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11354 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11355 } else {
11356 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11357 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11359 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11360 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
11361 if (s_addr <= uchar_end_in_config) {
11363 * Swap all char fields - must unswap bytes already swapped
11364 * by AscReadEEPWord().
11366 *wbuf = le16_to_cpu(wval);
11367 } else {
11368 /* Don't swap word field at the end - cntl field. */
11369 *wbuf = wval;
11371 sum += wval; /* Checksum treats all EEPROM data as words. */
11374 * Read the checksum word which will be compared against 'sum'
11375 * by the caller. Word field already swapped.
11377 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11378 return sum;
11381 static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
11383 PortAddr iop_base;
11384 ushort q_addr;
11385 ushort saved_word;
11386 int sta;
11388 iop_base = asc_dvc->iop_base;
11389 sta = 0;
11390 q_addr = ASC_QNO_TO_QADDR(241);
11391 saved_word = AscReadLramWord(iop_base, q_addr);
11392 AscSetChipLramAddr(iop_base, q_addr);
11393 AscSetChipLramData(iop_base, 0x55AA);
11394 mdelay(10);
11395 AscSetChipLramAddr(iop_base, q_addr);
11396 if (AscGetChipLramData(iop_base) == 0x55AA) {
11397 sta = 1;
11398 AscWriteLramWord(iop_base, q_addr, saved_word);
11400 return (sta);
11403 static void __devinit AscWaitEEPWrite(void)
11405 mdelay(20);
11408 static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
11410 ushort read_back;
11411 int retry;
11413 retry = 0;
11414 while (TRUE) {
11415 AscSetChipEEPData(iop_base, data_reg);
11416 mdelay(1);
11417 read_back = AscGetChipEEPData(iop_base);
11418 if (read_back == data_reg) {
11419 return (1);
11421 if (retry++ > ASC_EEP_MAX_RETRY) {
11422 return (0);
11427 static ushort __devinit
11428 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
11430 ushort read_wval;
11432 read_wval = AscReadEEPWord(iop_base, addr);
11433 if (read_wval != word_val) {
11434 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
11435 AscWaitEEPRead();
11436 AscWriteEEPDataReg(iop_base, word_val);
11437 AscWaitEEPRead();
11438 AscWriteEEPCmdReg(iop_base,
11439 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
11440 AscWaitEEPWrite();
11441 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11442 AscWaitEEPRead();
11443 return (AscReadEEPWord(iop_base, addr));
11445 return (read_wval);
11448 static int __devinit
11449 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11451 int n_error;
11452 ushort *wbuf;
11453 ushort word;
11454 ushort sum;
11455 int s_addr;
11456 int cfg_beg;
11457 int cfg_end;
11458 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11460 wbuf = (ushort *)cfg_buf;
11461 n_error = 0;
11462 sum = 0;
11463 /* Write two config words; AscWriteEEPWord() will swap bytes. */
11464 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11465 sum += *wbuf;
11466 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11467 n_error++;
11470 if (bus_type & ASC_IS_VL) {
11471 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11472 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11473 } else {
11474 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11475 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11477 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11478 if (s_addr <= uchar_end_in_config) {
11480 * This is a char field. Swap char fields before they are
11481 * swapped again by AscWriteEEPWord().
11483 word = cpu_to_le16(*wbuf);
11484 if (word !=
11485 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11486 n_error++;
11488 } else {
11489 /* Don't swap word field at the end - cntl field. */
11490 if (*wbuf !=
11491 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11492 n_error++;
11495 sum += *wbuf; /* Checksum calculated from word values. */
11497 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
11498 *wbuf = sum;
11499 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
11500 n_error++;
11503 /* Read EEPROM back again. */
11504 wbuf = (ushort *)cfg_buf;
11506 * Read two config words; Byte-swapping done by AscReadEEPWord().
11508 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11509 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11510 n_error++;
11513 if (bus_type & ASC_IS_VL) {
11514 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11515 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11516 } else {
11517 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11518 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11520 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11521 if (s_addr <= uchar_end_in_config) {
11523 * Swap all char fields. Must unswap bytes already swapped
11524 * by AscReadEEPWord().
11526 word =
11527 le16_to_cpu(AscReadEEPWord
11528 (iop_base, (uchar)s_addr));
11529 } else {
11530 /* Don't swap word field at the end - cntl field. */
11531 word = AscReadEEPWord(iop_base, (uchar)s_addr);
11533 if (*wbuf != word) {
11534 n_error++;
11537 /* Read checksum; Byte swapping not needed. */
11538 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11539 n_error++;
11541 return n_error;
11544 static int __devinit
11545 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11547 int retry;
11548 int n_error;
11550 retry = 0;
11551 while (TRUE) {
11552 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11553 bus_type)) == 0) {
11554 break;
11556 if (++retry > ASC_EEP_MAX_RETRY) {
11557 break;
11560 return n_error;
11563 static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
11565 ASCEEP_CONFIG eep_config_buf;
11566 ASCEEP_CONFIG *eep_config;
11567 PortAddr iop_base;
11568 ushort chksum;
11569 ushort warn_code;
11570 ushort cfg_msw, cfg_lsw;
11571 int i;
11572 int write_eep = 0;
11574 iop_base = asc_dvc->iop_base;
11575 warn_code = 0;
11576 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
11577 AscStopQueueExe(iop_base);
11578 if ((AscStopChip(iop_base) == FALSE) ||
11579 (AscGetChipScsiCtrl(iop_base) != 0)) {
11580 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
11581 AscResetChipAndScsiBus(asc_dvc);
11582 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
11584 if (AscIsChipHalted(iop_base) == FALSE) {
11585 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
11586 return (warn_code);
11588 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
11589 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
11590 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
11591 return (warn_code);
11593 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
11594 cfg_msw = AscGetChipCfgMsw(iop_base);
11595 cfg_lsw = AscGetChipCfgLsw(iop_base);
11596 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
11597 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11598 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
11599 AscSetChipCfgMsw(iop_base, cfg_msw);
11601 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
11602 ASC_DBG(1, "chksum 0x%x\n", chksum);
11603 if (chksum == 0) {
11604 chksum = 0xaa55;
11606 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
11607 warn_code |= ASC_WARN_AUTO_CONFIG;
11608 if (asc_dvc->cfg->chip_version == 3) {
11609 if (eep_config->cfg_lsw != cfg_lsw) {
11610 warn_code |= ASC_WARN_EEPROM_RECOVER;
11611 eep_config->cfg_lsw =
11612 AscGetChipCfgLsw(iop_base);
11614 if (eep_config->cfg_msw != cfg_msw) {
11615 warn_code |= ASC_WARN_EEPROM_RECOVER;
11616 eep_config->cfg_msw =
11617 AscGetChipCfgMsw(iop_base);
11621 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11622 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
11623 ASC_DBG(1, "eep_config->chksum 0x%x\n", eep_config->chksum);
11624 if (chksum != eep_config->chksum) {
11625 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
11626 ASC_CHIP_VER_PCI_ULTRA_3050) {
11627 ASC_DBG(1, "chksum error ignored; EEPROM-less board\n");
11628 eep_config->init_sdtr = 0xFF;
11629 eep_config->disc_enable = 0xFF;
11630 eep_config->start_motor = 0xFF;
11631 eep_config->use_cmd_qng = 0;
11632 eep_config->max_total_qng = 0xF0;
11633 eep_config->max_tag_qng = 0x20;
11634 eep_config->cntl = 0xBFFF;
11635 ASC_EEP_SET_CHIP_ID(eep_config, 7);
11636 eep_config->no_scam = 0;
11637 eep_config->adapter_info[0] = 0;
11638 eep_config->adapter_info[1] = 0;
11639 eep_config->adapter_info[2] = 0;
11640 eep_config->adapter_info[3] = 0;
11641 eep_config->adapter_info[4] = 0;
11642 /* Indicate EEPROM-less board. */
11643 eep_config->adapter_info[5] = 0xBB;
11644 } else {
11645 ASC_PRINT
11646 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
11647 write_eep = 1;
11648 warn_code |= ASC_WARN_EEPROM_CHKSUM;
11651 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
11652 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
11653 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
11654 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
11655 asc_dvc->start_motor = eep_config->start_motor;
11656 asc_dvc->dvc_cntl = eep_config->cntl;
11657 asc_dvc->no_scam = eep_config->no_scam;
11658 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
11659 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
11660 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
11661 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
11662 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
11663 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
11664 if (!AscTestExternalLram(asc_dvc)) {
11665 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
11666 ASC_IS_PCI_ULTRA)) {
11667 eep_config->max_total_qng =
11668 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
11669 eep_config->max_tag_qng =
11670 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
11671 } else {
11672 eep_config->cfg_msw |= 0x0800;
11673 cfg_msw |= 0x0800;
11674 AscSetChipCfgMsw(iop_base, cfg_msw);
11675 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
11676 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
11678 } else {
11680 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
11681 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
11683 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
11684 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
11686 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
11687 eep_config->max_tag_qng = eep_config->max_total_qng;
11689 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
11690 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
11692 asc_dvc->max_total_qng = eep_config->max_total_qng;
11693 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
11694 eep_config->use_cmd_qng) {
11695 eep_config->disc_enable = eep_config->use_cmd_qng;
11696 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
11698 ASC_EEP_SET_CHIP_ID(eep_config,
11699 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
11700 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
11701 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
11702 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
11703 asc_dvc->min_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
11706 for (i = 0; i <= ASC_MAX_TID; i++) {
11707 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
11708 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
11709 asc_dvc->cfg->sdtr_period_offset[i] =
11710 (uchar)(ASC_DEF_SDTR_OFFSET |
11711 (asc_dvc->min_sdtr_index << 4));
11713 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
11714 if (write_eep) {
11715 if ((i = AscSetEEPConfig(iop_base, eep_config,
11716 asc_dvc->bus_type)) != 0) {
11717 ASC_PRINT1
11718 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
11720 } else {
11721 ASC_PRINT
11722 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
11725 return (warn_code);
11728 static int __devinit AscInitGetConfig(struct Scsi_Host *shost)
11730 struct asc_board *board = shost_priv(shost);
11731 ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
11732 unsigned short warn_code = 0;
11734 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
11735 if (asc_dvc->err_code != 0)
11736 return asc_dvc->err_code;
11738 if (AscFindSignature(asc_dvc->iop_base)) {
11739 warn_code |= AscInitAscDvcVar(asc_dvc);
11740 warn_code |= AscInitFromEEP(asc_dvc);
11741 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
11742 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
11743 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
11744 } else {
11745 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11748 switch (warn_code) {
11749 case 0: /* No error */
11750 break;
11751 case ASC_WARN_IO_PORT_ROTATE:
11752 shost_printk(KERN_WARNING, shost, "I/O port address "
11753 "modified\n");
11754 break;
11755 case ASC_WARN_AUTO_CONFIG:
11756 shost_printk(KERN_WARNING, shost, "I/O port increment switch "
11757 "enabled\n");
11758 break;
11759 case ASC_WARN_EEPROM_CHKSUM:
11760 shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n");
11761 break;
11762 case ASC_WARN_IRQ_MODIFIED:
11763 shost_printk(KERN_WARNING, shost, "IRQ modified\n");
11764 break;
11765 case ASC_WARN_CMD_QNG_CONFLICT:
11766 shost_printk(KERN_WARNING, shost, "tag queuing enabled w/o "
11767 "disconnects\n");
11768 break;
11769 default:
11770 shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n",
11771 warn_code);
11772 break;
11775 if (asc_dvc->err_code != 0)
11776 shost_printk(KERN_ERR, shost, "error 0x%x at init_state "
11777 "0x%x\n", asc_dvc->err_code, asc_dvc->init_state);
11779 return asc_dvc->err_code;
11782 static int __devinit AscInitSetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
11784 struct asc_board *board = shost_priv(shost);
11785 ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
11786 PortAddr iop_base = asc_dvc->iop_base;
11787 unsigned short cfg_msw;
11788 unsigned short warn_code = 0;
11790 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
11791 if (asc_dvc->err_code != 0)
11792 return asc_dvc->err_code;
11793 if (!AscFindSignature(asc_dvc->iop_base)) {
11794 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11795 return asc_dvc->err_code;
11798 cfg_msw = AscGetChipCfgMsw(iop_base);
11799 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
11800 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11801 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
11802 AscSetChipCfgMsw(iop_base, cfg_msw);
11804 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
11805 asc_dvc->cfg->cmd_qng_enabled) {
11806 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
11807 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
11809 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
11810 warn_code |= ASC_WARN_AUTO_CONFIG;
11812 #ifdef CONFIG_PCI
11813 if (asc_dvc->bus_type & ASC_IS_PCI) {
11814 cfg_msw &= 0xFFC0;
11815 AscSetChipCfgMsw(iop_base, cfg_msw);
11816 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
11817 } else {
11818 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
11819 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
11820 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
11821 asc_dvc->bug_fix_cntl |=
11822 ASC_BUG_FIX_ASYN_USE_SYN;
11825 } else
11826 #endif /* CONFIG_PCI */
11827 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
11828 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
11829 == ASC_CHIP_VER_ASYN_BUG) {
11830 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
11833 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
11834 asc_dvc->cfg->chip_scsi_id) {
11835 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
11837 #ifdef CONFIG_ISA
11838 if (asc_dvc->bus_type & ASC_IS_ISA) {
11839 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
11840 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
11842 #endif /* CONFIG_ISA */
11844 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
11846 switch (warn_code) {
11847 case 0: /* No error. */
11848 break;
11849 case ASC_WARN_IO_PORT_ROTATE:
11850 shost_printk(KERN_WARNING, shost, "I/O port address "
11851 "modified\n");
11852 break;
11853 case ASC_WARN_AUTO_CONFIG:
11854 shost_printk(KERN_WARNING, shost, "I/O port increment switch "
11855 "enabled\n");
11856 break;
11857 case ASC_WARN_EEPROM_CHKSUM:
11858 shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n");
11859 break;
11860 case ASC_WARN_IRQ_MODIFIED:
11861 shost_printk(KERN_WARNING, shost, "IRQ modified\n");
11862 break;
11863 case ASC_WARN_CMD_QNG_CONFLICT:
11864 shost_printk(KERN_WARNING, shost, "tag queuing w/o "
11865 "disconnects\n");
11866 break;
11867 default:
11868 shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n",
11869 warn_code);
11870 break;
11873 if (asc_dvc->err_code != 0)
11874 shost_printk(KERN_ERR, shost, "error 0x%x at init_state "
11875 "0x%x\n", asc_dvc->err_code, asc_dvc->init_state);
11877 return asc_dvc->err_code;
11881 * EEPROM Configuration.
11883 * All drivers should use this structure to set the default EEPROM
11884 * configuration. The BIOS now uses this structure when it is built.
11885 * Additional structure information can be found in a_condor.h where
11886 * the structure is defined.
11888 * The *_Field_IsChar structs are needed to correct for endianness.
11889 * These values are read from the board 16 bits at a time directly
11890 * into the structs. Because some fields are char, the values will be
11891 * in the wrong order. The *_Field_IsChar tells when to flip the
11892 * bytes. Data read and written to PCI memory is automatically swapped
11893 * on big-endian platforms so char fields read as words are actually being
11894 * unswapped on big-endian platforms.
11896 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
11897 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
11898 0x0000, /* cfg_msw */
11899 0xFFFF, /* disc_enable */
11900 0xFFFF, /* wdtr_able */
11901 0xFFFF, /* sdtr_able */
11902 0xFFFF, /* start_motor */
11903 0xFFFF, /* tagqng_able */
11904 0xFFFF, /* bios_scan */
11905 0, /* scam_tolerant */
11906 7, /* adapter_scsi_id */
11907 0, /* bios_boot_delay */
11908 3, /* scsi_reset_delay */
11909 0, /* bios_id_lun */
11910 0, /* termination */
11911 0, /* reserved1 */
11912 0xFFE7, /* bios_ctrl */
11913 0xFFFF, /* ultra_able */
11914 0, /* reserved2 */
11915 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
11916 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
11917 0, /* dvc_cntl */
11918 0, /* bug_fix */
11919 0, /* serial_number_word1 */
11920 0, /* serial_number_word2 */
11921 0, /* serial_number_word3 */
11922 0, /* check_sum */
11923 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
11924 , /* oem_name[16] */
11925 0, /* dvc_err_code */
11926 0, /* adv_err_code */
11927 0, /* adv_err_addr */
11928 0, /* saved_dvc_err_code */
11929 0, /* saved_adv_err_code */
11930 0, /* saved_adv_err_addr */
11931 0 /* num_of_err */
11934 static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
11935 0, /* cfg_lsw */
11936 0, /* cfg_msw */
11937 0, /* -disc_enable */
11938 0, /* wdtr_able */
11939 0, /* sdtr_able */
11940 0, /* start_motor */
11941 0, /* tagqng_able */
11942 0, /* bios_scan */
11943 0, /* scam_tolerant */
11944 1, /* adapter_scsi_id */
11945 1, /* bios_boot_delay */
11946 1, /* scsi_reset_delay */
11947 1, /* bios_id_lun */
11948 1, /* termination */
11949 1, /* reserved1 */
11950 0, /* bios_ctrl */
11951 0, /* ultra_able */
11952 0, /* reserved2 */
11953 1, /* max_host_qng */
11954 1, /* max_dvc_qng */
11955 0, /* dvc_cntl */
11956 0, /* bug_fix */
11957 0, /* serial_number_word1 */
11958 0, /* serial_number_word2 */
11959 0, /* serial_number_word3 */
11960 0, /* check_sum */
11961 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
11962 , /* oem_name[16] */
11963 0, /* dvc_err_code */
11964 0, /* adv_err_code */
11965 0, /* adv_err_addr */
11966 0, /* saved_dvc_err_code */
11967 0, /* saved_adv_err_code */
11968 0, /* saved_adv_err_addr */
11969 0 /* num_of_err */
11972 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
11973 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
11974 0x0000, /* 01 cfg_msw */
11975 0xFFFF, /* 02 disc_enable */
11976 0xFFFF, /* 03 wdtr_able */
11977 0x4444, /* 04 sdtr_speed1 */
11978 0xFFFF, /* 05 start_motor */
11979 0xFFFF, /* 06 tagqng_able */
11980 0xFFFF, /* 07 bios_scan */
11981 0, /* 08 scam_tolerant */
11982 7, /* 09 adapter_scsi_id */
11983 0, /* bios_boot_delay */
11984 3, /* 10 scsi_reset_delay */
11985 0, /* bios_id_lun */
11986 0, /* 11 termination_se */
11987 0, /* termination_lvd */
11988 0xFFE7, /* 12 bios_ctrl */
11989 0x4444, /* 13 sdtr_speed2 */
11990 0x4444, /* 14 sdtr_speed3 */
11991 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
11992 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
11993 0, /* 16 dvc_cntl */
11994 0x4444, /* 17 sdtr_speed4 */
11995 0, /* 18 serial_number_word1 */
11996 0, /* 19 serial_number_word2 */
11997 0, /* 20 serial_number_word3 */
11998 0, /* 21 check_sum */
11999 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12000 , /* 22-29 oem_name[16] */
12001 0, /* 30 dvc_err_code */
12002 0, /* 31 adv_err_code */
12003 0, /* 32 adv_err_addr */
12004 0, /* 33 saved_dvc_err_code */
12005 0, /* 34 saved_adv_err_code */
12006 0, /* 35 saved_adv_err_addr */
12007 0, /* 36 reserved */
12008 0, /* 37 reserved */
12009 0, /* 38 reserved */
12010 0, /* 39 reserved */
12011 0, /* 40 reserved */
12012 0, /* 41 reserved */
12013 0, /* 42 reserved */
12014 0, /* 43 reserved */
12015 0, /* 44 reserved */
12016 0, /* 45 reserved */
12017 0, /* 46 reserved */
12018 0, /* 47 reserved */
12019 0, /* 48 reserved */
12020 0, /* 49 reserved */
12021 0, /* 50 reserved */
12022 0, /* 51 reserved */
12023 0, /* 52 reserved */
12024 0, /* 53 reserved */
12025 0, /* 54 reserved */
12026 0, /* 55 reserved */
12027 0, /* 56 cisptr_lsw */
12028 0, /* 57 cisprt_msw */
12029 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
12030 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
12031 0, /* 60 reserved */
12032 0, /* 61 reserved */
12033 0, /* 62 reserved */
12034 0 /* 63 reserved */
12037 static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
12038 0, /* 00 cfg_lsw */
12039 0, /* 01 cfg_msw */
12040 0, /* 02 disc_enable */
12041 0, /* 03 wdtr_able */
12042 0, /* 04 sdtr_speed1 */
12043 0, /* 05 start_motor */
12044 0, /* 06 tagqng_able */
12045 0, /* 07 bios_scan */
12046 0, /* 08 scam_tolerant */
12047 1, /* 09 adapter_scsi_id */
12048 1, /* bios_boot_delay */
12049 1, /* 10 scsi_reset_delay */
12050 1, /* bios_id_lun */
12051 1, /* 11 termination_se */
12052 1, /* termination_lvd */
12053 0, /* 12 bios_ctrl */
12054 0, /* 13 sdtr_speed2 */
12055 0, /* 14 sdtr_speed3 */
12056 1, /* 15 max_host_qng */
12057 1, /* max_dvc_qng */
12058 0, /* 16 dvc_cntl */
12059 0, /* 17 sdtr_speed4 */
12060 0, /* 18 serial_number_word1 */
12061 0, /* 19 serial_number_word2 */
12062 0, /* 20 serial_number_word3 */
12063 0, /* 21 check_sum */
12064 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12065 , /* 22-29 oem_name[16] */
12066 0, /* 30 dvc_err_code */
12067 0, /* 31 adv_err_code */
12068 0, /* 32 adv_err_addr */
12069 0, /* 33 saved_dvc_err_code */
12070 0, /* 34 saved_adv_err_code */
12071 0, /* 35 saved_adv_err_addr */
12072 0, /* 36 reserved */
12073 0, /* 37 reserved */
12074 0, /* 38 reserved */
12075 0, /* 39 reserved */
12076 0, /* 40 reserved */
12077 0, /* 41 reserved */
12078 0, /* 42 reserved */
12079 0, /* 43 reserved */
12080 0, /* 44 reserved */
12081 0, /* 45 reserved */
12082 0, /* 46 reserved */
12083 0, /* 47 reserved */
12084 0, /* 48 reserved */
12085 0, /* 49 reserved */
12086 0, /* 50 reserved */
12087 0, /* 51 reserved */
12088 0, /* 52 reserved */
12089 0, /* 53 reserved */
12090 0, /* 54 reserved */
12091 0, /* 55 reserved */
12092 0, /* 56 cisptr_lsw */
12093 0, /* 57 cisprt_msw */
12094 0, /* 58 subsysvid */
12095 0, /* 59 subsysid */
12096 0, /* 60 reserved */
12097 0, /* 61 reserved */
12098 0, /* 62 reserved */
12099 0 /* 63 reserved */
12102 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
12103 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
12104 0x0000, /* 01 cfg_msw */
12105 0xFFFF, /* 02 disc_enable */
12106 0xFFFF, /* 03 wdtr_able */
12107 0x5555, /* 04 sdtr_speed1 */
12108 0xFFFF, /* 05 start_motor */
12109 0xFFFF, /* 06 tagqng_able */
12110 0xFFFF, /* 07 bios_scan */
12111 0, /* 08 scam_tolerant */
12112 7, /* 09 adapter_scsi_id */
12113 0, /* bios_boot_delay */
12114 3, /* 10 scsi_reset_delay */
12115 0, /* bios_id_lun */
12116 0, /* 11 termination_se */
12117 0, /* termination_lvd */
12118 0xFFE7, /* 12 bios_ctrl */
12119 0x5555, /* 13 sdtr_speed2 */
12120 0x5555, /* 14 sdtr_speed3 */
12121 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
12122 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
12123 0, /* 16 dvc_cntl */
12124 0x5555, /* 17 sdtr_speed4 */
12125 0, /* 18 serial_number_word1 */
12126 0, /* 19 serial_number_word2 */
12127 0, /* 20 serial_number_word3 */
12128 0, /* 21 check_sum */
12129 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12130 , /* 22-29 oem_name[16] */
12131 0, /* 30 dvc_err_code */
12132 0, /* 31 adv_err_code */
12133 0, /* 32 adv_err_addr */
12134 0, /* 33 saved_dvc_err_code */
12135 0, /* 34 saved_adv_err_code */
12136 0, /* 35 saved_adv_err_addr */
12137 0, /* 36 reserved */
12138 0, /* 37 reserved */
12139 0, /* 38 reserved */
12140 0, /* 39 reserved */
12141 0, /* 40 reserved */
12142 0, /* 41 reserved */
12143 0, /* 42 reserved */
12144 0, /* 43 reserved */
12145 0, /* 44 reserved */
12146 0, /* 45 reserved */
12147 0, /* 46 reserved */
12148 0, /* 47 reserved */
12149 0, /* 48 reserved */
12150 0, /* 49 reserved */
12151 0, /* 50 reserved */
12152 0, /* 51 reserved */
12153 0, /* 52 reserved */
12154 0, /* 53 reserved */
12155 0, /* 54 reserved */
12156 0, /* 55 reserved */
12157 0, /* 56 cisptr_lsw */
12158 0, /* 57 cisprt_msw */
12159 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
12160 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
12161 0, /* 60 reserved */
12162 0, /* 61 reserved */
12163 0, /* 62 reserved */
12164 0 /* 63 reserved */
12167 static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
12168 0, /* 00 cfg_lsw */
12169 0, /* 01 cfg_msw */
12170 0, /* 02 disc_enable */
12171 0, /* 03 wdtr_able */
12172 0, /* 04 sdtr_speed1 */
12173 0, /* 05 start_motor */
12174 0, /* 06 tagqng_able */
12175 0, /* 07 bios_scan */
12176 0, /* 08 scam_tolerant */
12177 1, /* 09 adapter_scsi_id */
12178 1, /* bios_boot_delay */
12179 1, /* 10 scsi_reset_delay */
12180 1, /* bios_id_lun */
12181 1, /* 11 termination_se */
12182 1, /* termination_lvd */
12183 0, /* 12 bios_ctrl */
12184 0, /* 13 sdtr_speed2 */
12185 0, /* 14 sdtr_speed3 */
12186 1, /* 15 max_host_qng */
12187 1, /* max_dvc_qng */
12188 0, /* 16 dvc_cntl */
12189 0, /* 17 sdtr_speed4 */
12190 0, /* 18 serial_number_word1 */
12191 0, /* 19 serial_number_word2 */
12192 0, /* 20 serial_number_word3 */
12193 0, /* 21 check_sum */
12194 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12195 , /* 22-29 oem_name[16] */
12196 0, /* 30 dvc_err_code */
12197 0, /* 31 adv_err_code */
12198 0, /* 32 adv_err_addr */
12199 0, /* 33 saved_dvc_err_code */
12200 0, /* 34 saved_adv_err_code */
12201 0, /* 35 saved_adv_err_addr */
12202 0, /* 36 reserved */
12203 0, /* 37 reserved */
12204 0, /* 38 reserved */
12205 0, /* 39 reserved */
12206 0, /* 40 reserved */
12207 0, /* 41 reserved */
12208 0, /* 42 reserved */
12209 0, /* 43 reserved */
12210 0, /* 44 reserved */
12211 0, /* 45 reserved */
12212 0, /* 46 reserved */
12213 0, /* 47 reserved */
12214 0, /* 48 reserved */
12215 0, /* 49 reserved */
12216 0, /* 50 reserved */
12217 0, /* 51 reserved */
12218 0, /* 52 reserved */
12219 0, /* 53 reserved */
12220 0, /* 54 reserved */
12221 0, /* 55 reserved */
12222 0, /* 56 cisptr_lsw */
12223 0, /* 57 cisprt_msw */
12224 0, /* 58 subsysvid */
12225 0, /* 59 subsysid */
12226 0, /* 60 reserved */
12227 0, /* 61 reserved */
12228 0, /* 62 reserved */
12229 0 /* 63 reserved */
12232 #ifdef CONFIG_PCI
12234 * Wait for EEPROM command to complete
12236 static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
12238 int eep_delay_ms;
12240 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
12241 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
12242 ASC_EEP_CMD_DONE) {
12243 break;
12245 mdelay(1);
12247 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
12249 BUG();
12253 * Read the EEPROM from specified location
12255 static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
12257 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12258 ASC_EEP_CMD_READ | eep_word_addr);
12259 AdvWaitEEPCmd(iop_base);
12260 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
12264 * Write the EEPROM from 'cfg_buf'.
12266 static void __devinit
12267 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
12269 ushort *wbuf;
12270 ushort addr, chksum;
12271 ushort *charfields;
12273 wbuf = (ushort *)cfg_buf;
12274 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
12275 chksum = 0;
12277 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12278 AdvWaitEEPCmd(iop_base);
12281 * Write EEPROM from word 0 to word 20.
12283 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12284 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12285 ushort word;
12287 if (*charfields++) {
12288 word = cpu_to_le16(*wbuf);
12289 } else {
12290 word = *wbuf;
12292 chksum += *wbuf; /* Checksum is calculated from word values. */
12293 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12294 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12295 ASC_EEP_CMD_WRITE | addr);
12296 AdvWaitEEPCmd(iop_base);
12297 mdelay(ADV_EEP_DELAY_MS);
12301 * Write EEPROM checksum at word 21.
12303 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12304 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12305 AdvWaitEEPCmd(iop_base);
12306 wbuf++;
12307 charfields++;
12310 * Write EEPROM OEM name at words 22 to 29.
12312 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12313 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12314 ushort word;
12316 if (*charfields++) {
12317 word = cpu_to_le16(*wbuf);
12318 } else {
12319 word = *wbuf;
12321 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12322 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12323 ASC_EEP_CMD_WRITE | addr);
12324 AdvWaitEEPCmd(iop_base);
12326 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12327 AdvWaitEEPCmd(iop_base);
12331 * Write the EEPROM from 'cfg_buf'.
12333 static void __devinit
12334 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
12336 ushort *wbuf;
12337 ushort *charfields;
12338 ushort addr, chksum;
12340 wbuf = (ushort *)cfg_buf;
12341 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
12342 chksum = 0;
12344 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12345 AdvWaitEEPCmd(iop_base);
12348 * Write EEPROM from word 0 to word 20.
12350 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12351 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12352 ushort word;
12354 if (*charfields++) {
12355 word = cpu_to_le16(*wbuf);
12356 } else {
12357 word = *wbuf;
12359 chksum += *wbuf; /* Checksum is calculated from word values. */
12360 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12361 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12362 ASC_EEP_CMD_WRITE | addr);
12363 AdvWaitEEPCmd(iop_base);
12364 mdelay(ADV_EEP_DELAY_MS);
12368 * Write EEPROM checksum at word 21.
12370 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12371 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12372 AdvWaitEEPCmd(iop_base);
12373 wbuf++;
12374 charfields++;
12377 * Write EEPROM OEM name at words 22 to 29.
12379 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12380 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12381 ushort word;
12383 if (*charfields++) {
12384 word = cpu_to_le16(*wbuf);
12385 } else {
12386 word = *wbuf;
12388 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12389 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12390 ASC_EEP_CMD_WRITE | addr);
12391 AdvWaitEEPCmd(iop_base);
12393 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12394 AdvWaitEEPCmd(iop_base);
12398 * Write the EEPROM from 'cfg_buf'.
12400 static void __devinit
12401 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
12403 ushort *wbuf;
12404 ushort *charfields;
12405 ushort addr, chksum;
12407 wbuf = (ushort *)cfg_buf;
12408 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
12409 chksum = 0;
12411 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12412 AdvWaitEEPCmd(iop_base);
12415 * Write EEPROM from word 0 to word 20.
12417 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12418 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12419 ushort word;
12421 if (*charfields++) {
12422 word = cpu_to_le16(*wbuf);
12423 } else {
12424 word = *wbuf;
12426 chksum += *wbuf; /* Checksum is calculated from word values. */
12427 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12428 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12429 ASC_EEP_CMD_WRITE | addr);
12430 AdvWaitEEPCmd(iop_base);
12431 mdelay(ADV_EEP_DELAY_MS);
12435 * Write EEPROM checksum at word 21.
12437 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12438 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12439 AdvWaitEEPCmd(iop_base);
12440 wbuf++;
12441 charfields++;
12444 * Write EEPROM OEM name at words 22 to 29.
12446 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12447 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12448 ushort word;
12450 if (*charfields++) {
12451 word = cpu_to_le16(*wbuf);
12452 } else {
12453 word = *wbuf;
12455 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12456 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12457 ASC_EEP_CMD_WRITE | addr);
12458 AdvWaitEEPCmd(iop_base);
12460 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12461 AdvWaitEEPCmd(iop_base);
12465 * Read EEPROM configuration into the specified buffer.
12467 * Return a checksum based on the EEPROM configuration read.
12469 static ushort __devinit
12470 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
12472 ushort wval, chksum;
12473 ushort *wbuf;
12474 int eep_addr;
12475 ushort *charfields;
12477 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
12478 wbuf = (ushort *)cfg_buf;
12479 chksum = 0;
12481 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12482 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12483 wval = AdvReadEEPWord(iop_base, eep_addr);
12484 chksum += wval; /* Checksum is calculated from word values. */
12485 if (*charfields++) {
12486 *wbuf = le16_to_cpu(wval);
12487 } else {
12488 *wbuf = wval;
12491 /* Read checksum word. */
12492 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12493 wbuf++;
12494 charfields++;
12496 /* Read rest of EEPROM not covered by the checksum. */
12497 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12498 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12499 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12500 if (*charfields++) {
12501 *wbuf = le16_to_cpu(*wbuf);
12504 return chksum;
12508 * Read EEPROM configuration into the specified buffer.
12510 * Return a checksum based on the EEPROM configuration read.
12512 static ushort __devinit
12513 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
12515 ushort wval, chksum;
12516 ushort *wbuf;
12517 int eep_addr;
12518 ushort *charfields;
12520 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
12521 wbuf = (ushort *)cfg_buf;
12522 chksum = 0;
12524 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12525 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12526 wval = AdvReadEEPWord(iop_base, eep_addr);
12527 chksum += wval; /* Checksum is calculated from word values. */
12528 if (*charfields++) {
12529 *wbuf = le16_to_cpu(wval);
12530 } else {
12531 *wbuf = wval;
12534 /* Read checksum word. */
12535 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12536 wbuf++;
12537 charfields++;
12539 /* Read rest of EEPROM not covered by the checksum. */
12540 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12541 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12542 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12543 if (*charfields++) {
12544 *wbuf = le16_to_cpu(*wbuf);
12547 return chksum;
12551 * Read EEPROM configuration into the specified buffer.
12553 * Return a checksum based on the EEPROM configuration read.
12555 static ushort __devinit
12556 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
12558 ushort wval, chksum;
12559 ushort *wbuf;
12560 int eep_addr;
12561 ushort *charfields;
12563 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
12564 wbuf = (ushort *)cfg_buf;
12565 chksum = 0;
12567 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12568 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12569 wval = AdvReadEEPWord(iop_base, eep_addr);
12570 chksum += wval; /* Checksum is calculated from word values. */
12571 if (*charfields++) {
12572 *wbuf = le16_to_cpu(wval);
12573 } else {
12574 *wbuf = wval;
12577 /* Read checksum word. */
12578 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12579 wbuf++;
12580 charfields++;
12582 /* Read rest of EEPROM not covered by the checksum. */
12583 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12584 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12585 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12586 if (*charfields++) {
12587 *wbuf = le16_to_cpu(*wbuf);
12590 return chksum;
12594 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12595 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12596 * all of this is done.
12598 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12600 * For a non-fatal error return a warning code. If there are no warnings
12601 * then 0 is returned.
12603 * Note: Chip is stopped on entry.
12605 static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
12607 AdvPortAddr iop_base;
12608 ushort warn_code;
12609 ADVEEP_3550_CONFIG eep_config;
12611 iop_base = asc_dvc->iop_base;
12613 warn_code = 0;
12616 * Read the board's EEPROM configuration.
12618 * Set default values if a bad checksum is found.
12620 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
12621 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12624 * Set EEPROM default values.
12626 memcpy(&eep_config, &Default_3550_EEPROM_Config,
12627 sizeof(ADVEEP_3550_CONFIG));
12630 * Assume the 6 byte board serial number that was read from
12631 * EEPROM is correct even if the EEPROM checksum failed.
12633 eep_config.serial_number_word3 =
12634 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
12636 eep_config.serial_number_word2 =
12637 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
12639 eep_config.serial_number_word1 =
12640 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
12642 AdvSet3550EEPConfig(iop_base, &eep_config);
12645 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
12646 * EEPROM configuration that was read.
12648 * This is the mapping of EEPROM fields to Adv Library fields.
12650 asc_dvc->wdtr_able = eep_config.wdtr_able;
12651 asc_dvc->sdtr_able = eep_config.sdtr_able;
12652 asc_dvc->ultra_able = eep_config.ultra_able;
12653 asc_dvc->tagqng_able = eep_config.tagqng_able;
12654 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
12655 asc_dvc->max_host_qng = eep_config.max_host_qng;
12656 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12657 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
12658 asc_dvc->start_motor = eep_config.start_motor;
12659 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
12660 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
12661 asc_dvc->no_scam = eep_config.scam_tolerant;
12662 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
12663 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
12664 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
12667 * Set the host maximum queuing (max. 253, min. 16) and the per device
12668 * maximum queuing (max. 63, min. 4).
12670 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
12671 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12672 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
12673 /* If the value is zero, assume it is uninitialized. */
12674 if (eep_config.max_host_qng == 0) {
12675 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12676 } else {
12677 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
12681 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
12682 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12683 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
12684 /* If the value is zero, assume it is uninitialized. */
12685 if (eep_config.max_dvc_qng == 0) {
12686 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12687 } else {
12688 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
12693 * If 'max_dvc_qng' is greater than 'max_host_qng', then
12694 * set 'max_dvc_qng' to 'max_host_qng'.
12696 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
12697 eep_config.max_dvc_qng = eep_config.max_host_qng;
12701 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
12702 * values based on possibly adjusted EEPROM values.
12704 asc_dvc->max_host_qng = eep_config.max_host_qng;
12705 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12708 * If the EEPROM 'termination' field is set to automatic (0), then set
12709 * the ADV_DVC_CFG 'termination' field to automatic also.
12711 * If the termination is specified with a non-zero 'termination'
12712 * value check that a legal value is set and set the ADV_DVC_CFG
12713 * 'termination' field appropriately.
12715 if (eep_config.termination == 0) {
12716 asc_dvc->cfg->termination = 0; /* auto termination */
12717 } else {
12718 /* Enable manual control with low off / high off. */
12719 if (eep_config.termination == 1) {
12720 asc_dvc->cfg->termination = TERM_CTL_SEL;
12722 /* Enable manual control with low off / high on. */
12723 } else if (eep_config.termination == 2) {
12724 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
12726 /* Enable manual control with low on / high on. */
12727 } else if (eep_config.termination == 3) {
12728 asc_dvc->cfg->termination =
12729 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
12730 } else {
12732 * The EEPROM 'termination' field contains a bad value. Use
12733 * automatic termination instead.
12735 asc_dvc->cfg->termination = 0;
12736 warn_code |= ASC_WARN_EEPROM_TERMINATION;
12740 return warn_code;
12744 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12745 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12746 * all of this is done.
12748 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12750 * For a non-fatal error return a warning code. If there are no warnings
12751 * then 0 is returned.
12753 * Note: Chip is stopped on entry.
12755 static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
12757 AdvPortAddr iop_base;
12758 ushort warn_code;
12759 ADVEEP_38C0800_CONFIG eep_config;
12760 uchar tid, termination;
12761 ushort sdtr_speed = 0;
12763 iop_base = asc_dvc->iop_base;
12765 warn_code = 0;
12768 * Read the board's EEPROM configuration.
12770 * Set default values if a bad checksum is found.
12772 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
12773 eep_config.check_sum) {
12774 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12777 * Set EEPROM default values.
12779 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
12780 sizeof(ADVEEP_38C0800_CONFIG));
12783 * Assume the 6 byte board serial number that was read from
12784 * EEPROM is correct even if the EEPROM checksum failed.
12786 eep_config.serial_number_word3 =
12787 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
12789 eep_config.serial_number_word2 =
12790 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
12792 eep_config.serial_number_word1 =
12793 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
12795 AdvSet38C0800EEPConfig(iop_base, &eep_config);
12798 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
12799 * EEPROM configuration that was read.
12801 * This is the mapping of EEPROM fields to Adv Library fields.
12803 asc_dvc->wdtr_able = eep_config.wdtr_able;
12804 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
12805 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
12806 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
12807 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
12808 asc_dvc->tagqng_able = eep_config.tagqng_able;
12809 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
12810 asc_dvc->max_host_qng = eep_config.max_host_qng;
12811 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12812 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
12813 asc_dvc->start_motor = eep_config.start_motor;
12814 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
12815 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
12816 asc_dvc->no_scam = eep_config.scam_tolerant;
12817 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
12818 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
12819 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
12822 * For every Target ID if any of its 'sdtr_speed[1234]' bits
12823 * are set, then set an 'sdtr_able' bit for it.
12825 asc_dvc->sdtr_able = 0;
12826 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
12827 if (tid == 0) {
12828 sdtr_speed = asc_dvc->sdtr_speed1;
12829 } else if (tid == 4) {
12830 sdtr_speed = asc_dvc->sdtr_speed2;
12831 } else if (tid == 8) {
12832 sdtr_speed = asc_dvc->sdtr_speed3;
12833 } else if (tid == 12) {
12834 sdtr_speed = asc_dvc->sdtr_speed4;
12836 if (sdtr_speed & ADV_MAX_TID) {
12837 asc_dvc->sdtr_able |= (1 << tid);
12839 sdtr_speed >>= 4;
12843 * Set the host maximum queuing (max. 253, min. 16) and the per device
12844 * maximum queuing (max. 63, min. 4).
12846 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
12847 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12848 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
12849 /* If the value is zero, assume it is uninitialized. */
12850 if (eep_config.max_host_qng == 0) {
12851 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12852 } else {
12853 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
12857 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
12858 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12859 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
12860 /* If the value is zero, assume it is uninitialized. */
12861 if (eep_config.max_dvc_qng == 0) {
12862 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12863 } else {
12864 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
12869 * If 'max_dvc_qng' is greater than 'max_host_qng', then
12870 * set 'max_dvc_qng' to 'max_host_qng'.
12872 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
12873 eep_config.max_dvc_qng = eep_config.max_host_qng;
12877 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
12878 * values based on possibly adjusted EEPROM values.
12880 asc_dvc->max_host_qng = eep_config.max_host_qng;
12881 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12884 * If the EEPROM 'termination' field is set to automatic (0), then set
12885 * the ADV_DVC_CFG 'termination' field to automatic also.
12887 * If the termination is specified with a non-zero 'termination'
12888 * value check that a legal value is set and set the ADV_DVC_CFG
12889 * 'termination' field appropriately.
12891 if (eep_config.termination_se == 0) {
12892 termination = 0; /* auto termination for SE */
12893 } else {
12894 /* Enable manual control with low off / high off. */
12895 if (eep_config.termination_se == 1) {
12896 termination = 0;
12898 /* Enable manual control with low off / high on. */
12899 } else if (eep_config.termination_se == 2) {
12900 termination = TERM_SE_HI;
12902 /* Enable manual control with low on / high on. */
12903 } else if (eep_config.termination_se == 3) {
12904 termination = TERM_SE;
12905 } else {
12907 * The EEPROM 'termination_se' field contains a bad value.
12908 * Use automatic termination instead.
12910 termination = 0;
12911 warn_code |= ASC_WARN_EEPROM_TERMINATION;
12915 if (eep_config.termination_lvd == 0) {
12916 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
12917 } else {
12918 /* Enable manual control with low off / high off. */
12919 if (eep_config.termination_lvd == 1) {
12920 asc_dvc->cfg->termination = termination;
12922 /* Enable manual control with low off / high on. */
12923 } else if (eep_config.termination_lvd == 2) {
12924 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
12926 /* Enable manual control with low on / high on. */
12927 } else if (eep_config.termination_lvd == 3) {
12928 asc_dvc->cfg->termination = termination | TERM_LVD;
12929 } else {
12931 * The EEPROM 'termination_lvd' field contains a bad value.
12932 * Use automatic termination instead.
12934 asc_dvc->cfg->termination = termination;
12935 warn_code |= ASC_WARN_EEPROM_TERMINATION;
12939 return warn_code;
12943 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
12944 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
12945 * all of this is done.
12947 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
12949 * For a non-fatal error return a warning code. If there are no warnings
12950 * then 0 is returned.
12952 * Note: Chip is stopped on entry.
12954 static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
12956 AdvPortAddr iop_base;
12957 ushort warn_code;
12958 ADVEEP_38C1600_CONFIG eep_config;
12959 uchar tid, termination;
12960 ushort sdtr_speed = 0;
12962 iop_base = asc_dvc->iop_base;
12964 warn_code = 0;
12967 * Read the board's EEPROM configuration.
12969 * Set default values if a bad checksum is found.
12971 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
12972 eep_config.check_sum) {
12973 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
12974 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12977 * Set EEPROM default values.
12979 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
12980 sizeof(ADVEEP_38C1600_CONFIG));
12982 if (PCI_FUNC(pdev->devfn) != 0) {
12983 u8 ints;
12985 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60
12986 * and old Mac system booting problem. The Expansion
12987 * ROM must be disabled in Function 1 for these systems
12989 eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
12991 * Clear the INTAB (bit 11) if the GPIO 0 input
12992 * indicates the Function 1 interrupt line is wired
12993 * to INTB.
12995 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
12996 * 1 - Function 1 interrupt line wired to INT A.
12997 * 0 - Function 1 interrupt line wired to INT B.
12999 * Note: Function 0 is always wired to INTA.
13000 * Put all 5 GPIO bits in input mode and then read
13001 * their input values.
13003 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
13004 ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
13005 if ((ints & 0x01) == 0)
13006 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
13010 * Assume the 6 byte board serial number that was read from
13011 * EEPROM is correct even if the EEPROM checksum failed.
13013 eep_config.serial_number_word3 =
13014 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
13015 eep_config.serial_number_word2 =
13016 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
13017 eep_config.serial_number_word1 =
13018 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
13020 AdvSet38C1600EEPConfig(iop_base, &eep_config);
13024 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13025 * EEPROM configuration that was read.
13027 * This is the mapping of EEPROM fields to Adv Library fields.
13029 asc_dvc->wdtr_able = eep_config.wdtr_able;
13030 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13031 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13032 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13033 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13034 asc_dvc->ppr_able = 0;
13035 asc_dvc->tagqng_able = eep_config.tagqng_able;
13036 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13037 asc_dvc->max_host_qng = eep_config.max_host_qng;
13038 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13039 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
13040 asc_dvc->start_motor = eep_config.start_motor;
13041 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13042 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13043 asc_dvc->no_scam = eep_config.scam_tolerant;
13046 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13047 * are set, then set an 'sdtr_able' bit for it.
13049 asc_dvc->sdtr_able = 0;
13050 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
13051 if (tid == 0) {
13052 sdtr_speed = asc_dvc->sdtr_speed1;
13053 } else if (tid == 4) {
13054 sdtr_speed = asc_dvc->sdtr_speed2;
13055 } else if (tid == 8) {
13056 sdtr_speed = asc_dvc->sdtr_speed3;
13057 } else if (tid == 12) {
13058 sdtr_speed = asc_dvc->sdtr_speed4;
13060 if (sdtr_speed & ASC_MAX_TID) {
13061 asc_dvc->sdtr_able |= (1 << tid);
13063 sdtr_speed >>= 4;
13067 * Set the host maximum queuing (max. 253, min. 16) and the per device
13068 * maximum queuing (max. 63, min. 4).
13070 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13071 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13072 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13073 /* If the value is zero, assume it is uninitialized. */
13074 if (eep_config.max_host_qng == 0) {
13075 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13076 } else {
13077 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13081 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13082 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13083 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13084 /* If the value is zero, assume it is uninitialized. */
13085 if (eep_config.max_dvc_qng == 0) {
13086 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13087 } else {
13088 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13093 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13094 * set 'max_dvc_qng' to 'max_host_qng'.
13096 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13097 eep_config.max_dvc_qng = eep_config.max_host_qng;
13101 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
13102 * values based on possibly adjusted EEPROM values.
13104 asc_dvc->max_host_qng = eep_config.max_host_qng;
13105 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13108 * If the EEPROM 'termination' field is set to automatic (0), then set
13109 * the ASC_DVC_CFG 'termination' field to automatic also.
13111 * If the termination is specified with a non-zero 'termination'
13112 * value check that a legal value is set and set the ASC_DVC_CFG
13113 * 'termination' field appropriately.
13115 if (eep_config.termination_se == 0) {
13116 termination = 0; /* auto termination for SE */
13117 } else {
13118 /* Enable manual control with low off / high off. */
13119 if (eep_config.termination_se == 1) {
13120 termination = 0;
13122 /* Enable manual control with low off / high on. */
13123 } else if (eep_config.termination_se == 2) {
13124 termination = TERM_SE_HI;
13126 /* Enable manual control with low on / high on. */
13127 } else if (eep_config.termination_se == 3) {
13128 termination = TERM_SE;
13129 } else {
13131 * The EEPROM 'termination_se' field contains a bad value.
13132 * Use automatic termination instead.
13134 termination = 0;
13135 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13139 if (eep_config.termination_lvd == 0) {
13140 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13141 } else {
13142 /* Enable manual control with low off / high off. */
13143 if (eep_config.termination_lvd == 1) {
13144 asc_dvc->cfg->termination = termination;
13146 /* Enable manual control with low off / high on. */
13147 } else if (eep_config.termination_lvd == 2) {
13148 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13150 /* Enable manual control with low on / high on. */
13151 } else if (eep_config.termination_lvd == 3) {
13152 asc_dvc->cfg->termination = termination | TERM_LVD;
13153 } else {
13155 * The EEPROM 'termination_lvd' field contains a bad value.
13156 * Use automatic termination instead.
13158 asc_dvc->cfg->termination = termination;
13159 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13163 return warn_code;
13167 * Initialize the ADV_DVC_VAR structure.
13169 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13171 * For a non-fatal error return a warning code. If there are no warnings
13172 * then 0 is returned.
13174 static int __devinit
13175 AdvInitGetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
13177 struct asc_board *board = shost_priv(shost);
13178 ADV_DVC_VAR *asc_dvc = &board->dvc_var.adv_dvc_var;
13179 unsigned short warn_code = 0;
13180 AdvPortAddr iop_base = asc_dvc->iop_base;
13181 u16 cmd;
13182 int status;
13184 asc_dvc->err_code = 0;
13187 * Save the state of the PCI Configuration Command Register
13188 * "Parity Error Response Control" Bit. If the bit is clear (0),
13189 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13190 * DMA parity errors.
13192 asc_dvc->cfg->control_flag = 0;
13193 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
13194 if ((cmd & PCI_COMMAND_PARITY) == 0)
13195 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
13197 asc_dvc->cfg->chip_version =
13198 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13200 ASC_DBG(1, "iopb_chip_id_1: 0x%x 0x%x\n",
13201 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13202 (ushort)ADV_CHIP_ID_BYTE);
13204 ASC_DBG(1, "iopw_chip_id_0: 0x%x 0x%x\n",
13205 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13206 (ushort)ADV_CHIP_ID_WORD);
13209 * Reset the chip to start and allow register writes.
13211 if (AdvFindSignature(iop_base) == 0) {
13212 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13213 return ADV_ERROR;
13214 } else {
13216 * The caller must set 'chip_type' to a valid setting.
13218 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13219 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13220 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13221 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13222 return ADV_ERROR;
13226 * Reset Chip.
13228 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13229 ADV_CTRL_REG_CMD_RESET);
13230 mdelay(100);
13231 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13232 ADV_CTRL_REG_CMD_WR_IO_REG);
13234 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13235 status = AdvInitFrom38C1600EEP(asc_dvc);
13236 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13237 status = AdvInitFrom38C0800EEP(asc_dvc);
13238 } else {
13239 status = AdvInitFrom3550EEP(asc_dvc);
13241 warn_code |= status;
13244 if (warn_code != 0)
13245 shost_printk(KERN_WARNING, shost, "warning: 0x%x\n", warn_code);
13247 if (asc_dvc->err_code)
13248 shost_printk(KERN_ERR, shost, "error code 0x%x\n",
13249 asc_dvc->err_code);
13251 return asc_dvc->err_code;
13253 #endif
13255 static struct scsi_host_template advansys_template = {
13256 .proc_name = DRV_NAME,
13257 #ifdef CONFIG_PROC_FS
13258 .proc_info = advansys_proc_info,
13259 #endif
13260 .name = DRV_NAME,
13261 .info = advansys_info,
13262 .queuecommand = advansys_queuecommand,
13263 .eh_bus_reset_handler = advansys_reset,
13264 .bios_param = advansys_biosparam,
13265 .slave_configure = advansys_slave_configure,
13267 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
13268 * must be set. The flag will be cleared in advansys_board_found
13269 * for non-ISA adapters.
13271 .unchecked_isa_dma = 1,
13273 * All adapters controlled by this driver are capable of large
13274 * scatter-gather lists. According to the mid-level SCSI documentation
13275 * this obviates any performance gain provided by setting
13276 * 'use_clustering'. But empirically while CPU utilization is increased
13277 * by enabling clustering, I/O throughput increases as well.
13279 .use_clustering = ENABLE_CLUSTERING,
13282 static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost)
13284 struct asc_board *board = shost_priv(shost);
13285 struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
13286 int req_cnt = 0;
13287 adv_req_t *reqp = NULL;
13288 int sg_cnt = 0;
13289 adv_sgblk_t *sgp;
13290 int warn_code, err_code;
13293 * Allocate buffer carrier structures. The total size
13294 * is about 4 KB, so allocate all at once.
13296 adv_dvc->carrier_buf = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
13297 ASC_DBG(1, "carrier_buf 0x%p\n", adv_dvc->carrier_buf);
13299 if (!adv_dvc->carrier_buf)
13300 goto kmalloc_failed;
13303 * Allocate up to 'max_host_qng' request structures for the Wide
13304 * board. The total size is about 16 KB, so allocate all at once.
13305 * If the allocation fails decrement and try again.
13307 for (req_cnt = adv_dvc->max_host_qng; req_cnt > 0; req_cnt--) {
13308 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
13310 ASC_DBG(1, "reqp 0x%p, req_cnt %d, bytes %lu\n", reqp, req_cnt,
13311 (ulong)sizeof(adv_req_t) * req_cnt);
13313 if (reqp)
13314 break;
13317 if (!reqp)
13318 goto kmalloc_failed;
13320 adv_dvc->orig_reqp = reqp;
13323 * Allocate up to ADV_TOT_SG_BLOCK request structures for
13324 * the Wide board. Each structure is about 136 bytes.
13326 board->adv_sgblkp = NULL;
13327 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
13328 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
13330 if (!sgp)
13331 break;
13333 sgp->next_sgblkp = board->adv_sgblkp;
13334 board->adv_sgblkp = sgp;
13338 ASC_DBG(1, "sg_cnt %d * %lu = %lu bytes\n", sg_cnt, sizeof(adv_sgblk_t),
13339 sizeof(adv_sgblk_t) * sg_cnt);
13341 if (!board->adv_sgblkp)
13342 goto kmalloc_failed;
13345 * Point 'adv_reqp' to the request structures and
13346 * link them together.
13348 req_cnt--;
13349 reqp[req_cnt].next_reqp = NULL;
13350 for (; req_cnt > 0; req_cnt--) {
13351 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
13353 board->adv_reqp = &reqp[0];
13355 if (adv_dvc->chip_type == ADV_CHIP_ASC3550) {
13356 ASC_DBG(2, "AdvInitAsc3550Driver()\n");
13357 warn_code = AdvInitAsc3550Driver(adv_dvc);
13358 } else if (adv_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13359 ASC_DBG(2, "AdvInitAsc38C0800Driver()\n");
13360 warn_code = AdvInitAsc38C0800Driver(adv_dvc);
13361 } else {
13362 ASC_DBG(2, "AdvInitAsc38C1600Driver()\n");
13363 warn_code = AdvInitAsc38C1600Driver(adv_dvc);
13365 err_code = adv_dvc->err_code;
13367 if (warn_code || err_code) {
13368 shost_printk(KERN_WARNING, shost, "error: warn 0x%x, error "
13369 "0x%x\n", warn_code, err_code);
13372 goto exit;
13374 kmalloc_failed:
13375 shost_printk(KERN_ERR, shost, "error: kmalloc() failed\n");
13376 err_code = ADV_ERROR;
13377 exit:
13378 return err_code;
13381 static void advansys_wide_free_mem(struct asc_board *board)
13383 struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
13384 kfree(adv_dvc->carrier_buf);
13385 adv_dvc->carrier_buf = NULL;
13386 kfree(adv_dvc->orig_reqp);
13387 adv_dvc->orig_reqp = board->adv_reqp = NULL;
13388 while (board->adv_sgblkp) {
13389 adv_sgblk_t *sgp = board->adv_sgblkp;
13390 board->adv_sgblkp = sgp->next_sgblkp;
13391 kfree(sgp);
13395 static int __devinit advansys_board_found(struct Scsi_Host *shost,
13396 unsigned int iop, int bus_type)
13398 struct pci_dev *pdev;
13399 struct asc_board *boardp = shost_priv(shost);
13400 ASC_DVC_VAR *asc_dvc_varp = NULL;
13401 ADV_DVC_VAR *adv_dvc_varp = NULL;
13402 int share_irq, warn_code, ret;
13404 pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL;
13406 if (ASC_NARROW_BOARD(boardp)) {
13407 ASC_DBG(1, "narrow board\n");
13408 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
13409 asc_dvc_varp->bus_type = bus_type;
13410 asc_dvc_varp->drv_ptr = boardp;
13411 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
13412 asc_dvc_varp->iop_base = iop;
13413 } else {
13414 #ifdef CONFIG_PCI
13415 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
13416 adv_dvc_varp->drv_ptr = boardp;
13417 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
13418 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
13419 ASC_DBG(1, "wide board ASC-3550\n");
13420 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
13421 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
13422 ASC_DBG(1, "wide board ASC-38C0800\n");
13423 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
13424 } else {
13425 ASC_DBG(1, "wide board ASC-38C1600\n");
13426 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
13429 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
13430 boardp->ioremap_addr = pci_ioremap_bar(pdev, 1);
13431 if (!boardp->ioremap_addr) {
13432 shost_printk(KERN_ERR, shost, "ioremap(%lx, %d) "
13433 "returned NULL\n",
13434 (long)pci_resource_start(pdev, 1),
13435 boardp->asc_n_io_port);
13436 ret = -ENODEV;
13437 goto err_shost;
13439 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr;
13440 ASC_DBG(1, "iop_base: 0x%p\n", adv_dvc_varp->iop_base);
13443 * Even though it isn't used to access wide boards, other
13444 * than for the debug line below, save I/O Port address so
13445 * that it can be reported.
13447 boardp->ioport = iop;
13449 ASC_DBG(1, "iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
13450 (ushort)inp(iop + 1), (ushort)inpw(iop));
13451 #endif /* CONFIG_PCI */
13454 #ifdef CONFIG_PROC_FS
13456 * Allocate buffer for printing information from
13457 * /proc/scsi/advansys/[0...].
13459 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
13460 if (!boardp->prtbuf) {
13461 shost_printk(KERN_ERR, shost, "kmalloc(%d) returned NULL\n",
13462 ASC_PRTBUF_SIZE);
13463 ret = -ENOMEM;
13464 goto err_unmap;
13466 #endif /* CONFIG_PROC_FS */
13468 if (ASC_NARROW_BOARD(boardp)) {
13470 * Set the board bus type and PCI IRQ before
13471 * calling AscInitGetConfig().
13473 switch (asc_dvc_varp->bus_type) {
13474 #ifdef CONFIG_ISA
13475 case ASC_IS_ISA:
13476 shost->unchecked_isa_dma = TRUE;
13477 share_irq = 0;
13478 break;
13479 case ASC_IS_VL:
13480 shost->unchecked_isa_dma = FALSE;
13481 share_irq = 0;
13482 break;
13483 case ASC_IS_EISA:
13484 shost->unchecked_isa_dma = FALSE;
13485 share_irq = IRQF_SHARED;
13486 break;
13487 #endif /* CONFIG_ISA */
13488 #ifdef CONFIG_PCI
13489 case ASC_IS_PCI:
13490 shost->unchecked_isa_dma = FALSE;
13491 share_irq = IRQF_SHARED;
13492 break;
13493 #endif /* CONFIG_PCI */
13494 default:
13495 shost_printk(KERN_ERR, shost, "unknown adapter type: "
13496 "%d\n", asc_dvc_varp->bus_type);
13497 shost->unchecked_isa_dma = TRUE;
13498 share_irq = 0;
13499 break;
13503 * NOTE: AscInitGetConfig() may change the board's
13504 * bus_type value. The bus_type value should no
13505 * longer be used. If the bus_type field must be
13506 * referenced only use the bit-wise AND operator "&".
13508 ASC_DBG(2, "AscInitGetConfig()\n");
13509 ret = AscInitGetConfig(shost) ? -ENODEV : 0;
13510 } else {
13511 #ifdef CONFIG_PCI
13513 * For Wide boards set PCI information before calling
13514 * AdvInitGetConfig().
13516 shost->unchecked_isa_dma = FALSE;
13517 share_irq = IRQF_SHARED;
13518 ASC_DBG(2, "AdvInitGetConfig()\n");
13520 ret = AdvInitGetConfig(pdev, shost) ? -ENODEV : 0;
13521 #endif /* CONFIG_PCI */
13524 if (ret)
13525 goto err_free_proc;
13528 * Save the EEPROM configuration so that it can be displayed
13529 * from /proc/scsi/advansys/[0...].
13531 if (ASC_NARROW_BOARD(boardp)) {
13533 ASCEEP_CONFIG *ep;
13536 * Set the adapter's target id bit in the 'init_tidmask' field.
13538 boardp->init_tidmask |=
13539 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
13542 * Save EEPROM settings for the board.
13544 ep = &boardp->eep_config.asc_eep;
13546 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
13547 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
13548 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
13549 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
13550 ep->start_motor = asc_dvc_varp->start_motor;
13551 ep->cntl = asc_dvc_varp->dvc_cntl;
13552 ep->no_scam = asc_dvc_varp->no_scam;
13553 ep->max_total_qng = asc_dvc_varp->max_total_qng;
13554 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
13555 /* 'max_tag_qng' is set to the same value for every device. */
13556 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
13557 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
13558 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
13559 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
13560 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
13561 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
13562 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
13565 * Modify board configuration.
13567 ASC_DBG(2, "AscInitSetConfig()\n");
13568 ret = AscInitSetConfig(pdev, shost) ? -ENODEV : 0;
13569 if (ret)
13570 goto err_free_proc;
13571 } else {
13572 ADVEEP_3550_CONFIG *ep_3550;
13573 ADVEEP_38C0800_CONFIG *ep_38C0800;
13574 ADVEEP_38C1600_CONFIG *ep_38C1600;
13577 * Save Wide EEP Configuration Information.
13579 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
13580 ep_3550 = &boardp->eep_config.adv_3550_eep;
13582 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
13583 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
13584 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
13585 ep_3550->termination = adv_dvc_varp->cfg->termination;
13586 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
13587 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
13588 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
13589 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
13590 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
13591 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
13592 ep_3550->start_motor = adv_dvc_varp->start_motor;
13593 ep_3550->scsi_reset_delay =
13594 adv_dvc_varp->scsi_reset_wait;
13595 ep_3550->serial_number_word1 =
13596 adv_dvc_varp->cfg->serial1;
13597 ep_3550->serial_number_word2 =
13598 adv_dvc_varp->cfg->serial2;
13599 ep_3550->serial_number_word3 =
13600 adv_dvc_varp->cfg->serial3;
13601 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
13602 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
13604 ep_38C0800->adapter_scsi_id =
13605 adv_dvc_varp->chip_scsi_id;
13606 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
13607 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
13608 ep_38C0800->termination_lvd =
13609 adv_dvc_varp->cfg->termination;
13610 ep_38C0800->disc_enable =
13611 adv_dvc_varp->cfg->disc_enable;
13612 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
13613 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
13614 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
13615 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
13616 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
13617 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
13618 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
13619 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
13620 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
13621 ep_38C0800->scsi_reset_delay =
13622 adv_dvc_varp->scsi_reset_wait;
13623 ep_38C0800->serial_number_word1 =
13624 adv_dvc_varp->cfg->serial1;
13625 ep_38C0800->serial_number_word2 =
13626 adv_dvc_varp->cfg->serial2;
13627 ep_38C0800->serial_number_word3 =
13628 adv_dvc_varp->cfg->serial3;
13629 } else {
13630 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
13632 ep_38C1600->adapter_scsi_id =
13633 adv_dvc_varp->chip_scsi_id;
13634 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
13635 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
13636 ep_38C1600->termination_lvd =
13637 adv_dvc_varp->cfg->termination;
13638 ep_38C1600->disc_enable =
13639 adv_dvc_varp->cfg->disc_enable;
13640 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
13641 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
13642 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
13643 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
13644 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
13645 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
13646 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
13647 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
13648 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
13649 ep_38C1600->scsi_reset_delay =
13650 adv_dvc_varp->scsi_reset_wait;
13651 ep_38C1600->serial_number_word1 =
13652 adv_dvc_varp->cfg->serial1;
13653 ep_38C1600->serial_number_word2 =
13654 adv_dvc_varp->cfg->serial2;
13655 ep_38C1600->serial_number_word3 =
13656 adv_dvc_varp->cfg->serial3;
13660 * Set the adapter's target id bit in the 'init_tidmask' field.
13662 boardp->init_tidmask |=
13663 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
13667 * Channels are numbered beginning with 0. For AdvanSys one host
13668 * structure supports one channel. Multi-channel boards have a
13669 * separate host structure for each channel.
13671 shost->max_channel = 0;
13672 if (ASC_NARROW_BOARD(boardp)) {
13673 shost->max_id = ASC_MAX_TID + 1;
13674 shost->max_lun = ASC_MAX_LUN + 1;
13675 shost->max_cmd_len = ASC_MAX_CDB_LEN;
13677 shost->io_port = asc_dvc_varp->iop_base;
13678 boardp->asc_n_io_port = ASC_IOADR_GAP;
13679 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
13681 /* Set maximum number of queues the adapter can handle. */
13682 shost->can_queue = asc_dvc_varp->max_total_qng;
13683 } else {
13684 shost->max_id = ADV_MAX_TID + 1;
13685 shost->max_lun = ADV_MAX_LUN + 1;
13686 shost->max_cmd_len = ADV_MAX_CDB_LEN;
13689 * Save the I/O Port address and length even though
13690 * I/O ports are not used to access Wide boards.
13691 * Instead the Wide boards are accessed with
13692 * PCI Memory Mapped I/O.
13694 shost->io_port = iop;
13696 shost->this_id = adv_dvc_varp->chip_scsi_id;
13698 /* Set maximum number of queues the adapter can handle. */
13699 shost->can_queue = adv_dvc_varp->max_host_qng;
13703 * Following v1.3.89, 'cmd_per_lun' is no longer needed
13704 * and should be set to zero.
13706 * But because of a bug introduced in v1.3.89 if the driver is
13707 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
13708 * SCSI function 'allocate_device' will panic. To allow the driver
13709 * to work as a module in these kernels set 'cmd_per_lun' to 1.
13711 * Note: This is wrong. cmd_per_lun should be set to the depth
13712 * you want on untagged devices always.
13713 #ifdef MODULE
13715 shost->cmd_per_lun = 1;
13716 /* #else
13717 shost->cmd_per_lun = 0;
13718 #endif */
13721 * Set the maximum number of scatter-gather elements the
13722 * adapter can handle.
13724 if (ASC_NARROW_BOARD(boardp)) {
13726 * Allow two commands with 'sg_tablesize' scatter-gather
13727 * elements to be executed simultaneously. This value is
13728 * the theoretical hardware limit. It may be decreased
13729 * below.
13731 shost->sg_tablesize =
13732 (((asc_dvc_varp->max_total_qng - 2) / 2) *
13733 ASC_SG_LIST_PER_Q) + 1;
13734 } else {
13735 shost->sg_tablesize = ADV_MAX_SG_LIST;
13739 * The value of 'sg_tablesize' can not exceed the SCSI
13740 * mid-level driver definition of SG_ALL. SG_ALL also
13741 * must not be exceeded, because it is used to define the
13742 * size of the scatter-gather table in 'struct asc_sg_head'.
13744 if (shost->sg_tablesize > SG_ALL) {
13745 shost->sg_tablesize = SG_ALL;
13748 ASC_DBG(1, "sg_tablesize: %d\n", shost->sg_tablesize);
13750 /* BIOS start address. */
13751 if (ASC_NARROW_BOARD(boardp)) {
13752 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
13753 asc_dvc_varp->bus_type);
13754 } else {
13756 * Fill-in BIOS board variables. The Wide BIOS saves
13757 * information in LRAM that is used by the driver.
13759 AdvReadWordLram(adv_dvc_varp->iop_base,
13760 BIOS_SIGNATURE, boardp->bios_signature);
13761 AdvReadWordLram(adv_dvc_varp->iop_base,
13762 BIOS_VERSION, boardp->bios_version);
13763 AdvReadWordLram(adv_dvc_varp->iop_base,
13764 BIOS_CODESEG, boardp->bios_codeseg);
13765 AdvReadWordLram(adv_dvc_varp->iop_base,
13766 BIOS_CODELEN, boardp->bios_codelen);
13768 ASC_DBG(1, "bios_signature 0x%x, bios_version 0x%x\n",
13769 boardp->bios_signature, boardp->bios_version);
13771 ASC_DBG(1, "bios_codeseg 0x%x, bios_codelen 0x%x\n",
13772 boardp->bios_codeseg, boardp->bios_codelen);
13775 * If the BIOS saved a valid signature, then fill in
13776 * the BIOS code segment base address.
13778 if (boardp->bios_signature == 0x55AA) {
13780 * Convert x86 realmode code segment to a linear
13781 * address by shifting left 4.
13783 shost->base = ((ulong)boardp->bios_codeseg << 4);
13784 } else {
13785 shost->base = 0;
13790 * Register Board Resources - I/O Port, DMA, IRQ
13793 /* Register DMA Channel for Narrow boards. */
13794 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
13795 #ifdef CONFIG_ISA
13796 if (ASC_NARROW_BOARD(boardp)) {
13797 /* Register DMA channel for ISA bus. */
13798 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
13799 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
13800 ret = request_dma(shost->dma_channel, DRV_NAME);
13801 if (ret) {
13802 shost_printk(KERN_ERR, shost, "request_dma() "
13803 "%d failed %d\n",
13804 shost->dma_channel, ret);
13805 goto err_free_proc;
13807 AscEnableIsaDma(shost->dma_channel);
13810 #endif /* CONFIG_ISA */
13812 /* Register IRQ Number. */
13813 ASC_DBG(2, "request_irq(%d, %p)\n", boardp->irq, shost);
13815 ret = request_irq(boardp->irq, advansys_interrupt, share_irq,
13816 DRV_NAME, shost);
13818 if (ret) {
13819 if (ret == -EBUSY) {
13820 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
13821 "already in use\n", boardp->irq);
13822 } else if (ret == -EINVAL) {
13823 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
13824 "not valid\n", boardp->irq);
13825 } else {
13826 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
13827 "failed with %d\n", boardp->irq, ret);
13829 goto err_free_dma;
13833 * Initialize board RISC chip and enable interrupts.
13835 if (ASC_NARROW_BOARD(boardp)) {
13836 ASC_DBG(2, "AscInitAsc1000Driver()\n");
13838 asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL);
13839 if (!asc_dvc_varp->overrun_buf) {
13840 ret = -ENOMEM;
13841 goto err_free_wide_mem;
13843 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
13845 if (warn_code || asc_dvc_varp->err_code) {
13846 shost_printk(KERN_ERR, shost, "error: init_state 0x%x, "
13847 "warn 0x%x, error 0x%x\n",
13848 asc_dvc_varp->init_state, warn_code,
13849 asc_dvc_varp->err_code);
13850 if (asc_dvc_varp->err_code) {
13851 ret = -ENODEV;
13852 kfree(asc_dvc_varp->overrun_buf);
13855 } else {
13856 if (advansys_wide_init_chip(shost))
13857 ret = -ENODEV;
13860 if (ret)
13861 goto err_free_wide_mem;
13863 ASC_DBG_PRT_SCSI_HOST(2, shost);
13865 ret = scsi_add_host(shost, boardp->dev);
13866 if (ret)
13867 goto err_free_wide_mem;
13869 scsi_scan_host(shost);
13870 return 0;
13872 err_free_wide_mem:
13873 advansys_wide_free_mem(boardp);
13874 free_irq(boardp->irq, shost);
13875 err_free_dma:
13876 #ifdef CONFIG_ISA
13877 if (shost->dma_channel != NO_ISA_DMA)
13878 free_dma(shost->dma_channel);
13879 #endif
13880 err_free_proc:
13881 kfree(boardp->prtbuf);
13882 #ifdef CONFIG_PROC_FS
13883 err_unmap:
13884 #endif
13885 if (boardp->ioremap_addr)
13886 iounmap(boardp->ioremap_addr);
13887 err_shost:
13888 return ret;
13892 * advansys_release()
13894 * Release resources allocated for a single AdvanSys adapter.
13896 static int advansys_release(struct Scsi_Host *shost)
13898 struct asc_board *board = shost_priv(shost);
13899 ASC_DBG(1, "begin\n");
13900 scsi_remove_host(shost);
13901 free_irq(board->irq, shost);
13902 #ifdef CONFIG_ISA
13903 if (shost->dma_channel != NO_ISA_DMA) {
13904 ASC_DBG(1, "free_dma()\n");
13905 free_dma(shost->dma_channel);
13907 #endif
13908 if (ASC_NARROW_BOARD(board)) {
13909 dma_unmap_single(board->dev,
13910 board->dvc_var.asc_dvc_var.overrun_dma,
13911 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
13912 kfree(board->dvc_var.asc_dvc_var.overrun_buf);
13913 } else {
13914 iounmap(board->ioremap_addr);
13915 advansys_wide_free_mem(board);
13917 kfree(board->prtbuf);
13918 scsi_host_put(shost);
13919 ASC_DBG(1, "end\n");
13920 return 0;
13923 #define ASC_IOADR_TABLE_MAX_IX 11
13925 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] = {
13926 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
13927 0x0210, 0x0230, 0x0250, 0x0330
13931 * The ISA IRQ number is found in bits 2 and 3 of the CfgLsw. It decodes as:
13932 * 00: 10
13933 * 01: 11
13934 * 10: 12
13935 * 11: 15
13937 static unsigned int __devinit advansys_isa_irq_no(PortAddr iop_base)
13939 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
13940 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x03) + 10;
13941 if (chip_irq == 13)
13942 chip_irq = 15;
13943 return chip_irq;
13946 static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
13948 int err = -ENODEV;
13949 PortAddr iop_base = _asc_def_iop_base[id];
13950 struct Scsi_Host *shost;
13951 struct asc_board *board;
13953 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
13954 ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
13955 return -ENODEV;
13957 ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
13958 if (!AscFindSignature(iop_base))
13959 goto release_region;
13960 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
13961 goto release_region;
13963 err = -ENOMEM;
13964 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
13965 if (!shost)
13966 goto release_region;
13968 board = shost_priv(shost);
13969 board->irq = advansys_isa_irq_no(iop_base);
13970 board->dev = dev;
13972 err = advansys_board_found(shost, iop_base, ASC_IS_ISA);
13973 if (err)
13974 goto free_host;
13976 dev_set_drvdata(dev, shost);
13977 return 0;
13979 free_host:
13980 scsi_host_put(shost);
13981 release_region:
13982 release_region(iop_base, ASC_IOADR_GAP);
13983 return err;
13986 static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
13988 int ioport = _asc_def_iop_base[id];
13989 advansys_release(dev_get_drvdata(dev));
13990 release_region(ioport, ASC_IOADR_GAP);
13991 return 0;
13994 static struct isa_driver advansys_isa_driver = {
13995 .probe = advansys_isa_probe,
13996 .remove = __devexit_p(advansys_isa_remove),
13997 .driver = {
13998 .owner = THIS_MODULE,
13999 .name = DRV_NAME,
14004 * The VLB IRQ number is found in bits 2 to 4 of the CfgLsw. It decodes as:
14005 * 000: invalid
14006 * 001: 10
14007 * 010: 11
14008 * 011: 12
14009 * 100: invalid
14010 * 101: 14
14011 * 110: 15
14012 * 111: invalid
14014 static unsigned int __devinit advansys_vlb_irq_no(PortAddr iop_base)
14016 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
14017 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x07) + 9;
14018 if ((chip_irq < 10) || (chip_irq == 13) || (chip_irq > 15))
14019 return 0;
14020 return chip_irq;
14023 static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
14025 int err = -ENODEV;
14026 PortAddr iop_base = _asc_def_iop_base[id];
14027 struct Scsi_Host *shost;
14028 struct asc_board *board;
14030 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
14031 ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
14032 return -ENODEV;
14034 ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
14035 if (!AscFindSignature(iop_base))
14036 goto release_region;
14038 * I don't think this condition can actually happen, but the old
14039 * driver did it, and the chances of finding a VLB setup in 2007
14040 * to do testing with is slight to none.
14042 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
14043 goto release_region;
14045 err = -ENOMEM;
14046 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14047 if (!shost)
14048 goto release_region;
14050 board = shost_priv(shost);
14051 board->irq = advansys_vlb_irq_no(iop_base);
14052 board->dev = dev;
14054 err = advansys_board_found(shost, iop_base, ASC_IS_VL);
14055 if (err)
14056 goto free_host;
14058 dev_set_drvdata(dev, shost);
14059 return 0;
14061 free_host:
14062 scsi_host_put(shost);
14063 release_region:
14064 release_region(iop_base, ASC_IOADR_GAP);
14065 return -ENODEV;
14068 static struct isa_driver advansys_vlb_driver = {
14069 .probe = advansys_vlb_probe,
14070 .remove = __devexit_p(advansys_isa_remove),
14071 .driver = {
14072 .owner = THIS_MODULE,
14073 .name = "advansys_vlb",
14077 static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
14078 { "ABP7401" },
14079 { "ABP7501" },
14080 { "" }
14083 MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
14086 * EISA is a little more tricky than PCI; each EISA device may have two
14087 * channels, and this driver is written to make each channel its own Scsi_Host
14089 struct eisa_scsi_data {
14090 struct Scsi_Host *host[2];
14094 * The EISA IRQ number is found in bits 8 to 10 of the CfgLsw. It decodes as:
14095 * 000: 10
14096 * 001: 11
14097 * 010: 12
14098 * 011: invalid
14099 * 100: 14
14100 * 101: 15
14101 * 110: invalid
14102 * 111: invalid
14104 static unsigned int __devinit advansys_eisa_irq_no(struct eisa_device *edev)
14106 unsigned short cfg_lsw = inw(edev->base_addr + 0xc86);
14107 unsigned int chip_irq = ((cfg_lsw >> 8) & 0x07) + 10;
14108 if ((chip_irq == 13) || (chip_irq > 15))
14109 return 0;
14110 return chip_irq;
14113 static int __devinit advansys_eisa_probe(struct device *dev)
14115 int i, ioport, irq = 0;
14116 int err;
14117 struct eisa_device *edev = to_eisa_device(dev);
14118 struct eisa_scsi_data *data;
14120 err = -ENOMEM;
14121 data = kzalloc(sizeof(*data), GFP_KERNEL);
14122 if (!data)
14123 goto fail;
14124 ioport = edev->base_addr + 0xc30;
14126 err = -ENODEV;
14127 for (i = 0; i < 2; i++, ioport += 0x20) {
14128 struct asc_board *board;
14129 struct Scsi_Host *shost;
14130 if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) {
14131 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
14132 ioport + ASC_IOADR_GAP - 1);
14133 continue;
14135 if (!AscFindSignature(ioport)) {
14136 release_region(ioport, ASC_IOADR_GAP);
14137 continue;
14141 * I don't know why we need to do this for EISA chips, but
14142 * not for any others. It looks to be equivalent to
14143 * AscGetChipCfgMsw, but I may have overlooked something,
14144 * so I'm not converting it until I get an EISA board to
14145 * test with.
14147 inw(ioport + 4);
14149 if (!irq)
14150 irq = advansys_eisa_irq_no(edev);
14152 err = -ENOMEM;
14153 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14154 if (!shost)
14155 goto release_region;
14157 board = shost_priv(shost);
14158 board->irq = irq;
14159 board->dev = dev;
14161 err = advansys_board_found(shost, ioport, ASC_IS_EISA);
14162 if (!err) {
14163 data->host[i] = shost;
14164 continue;
14167 scsi_host_put(shost);
14168 release_region:
14169 release_region(ioport, ASC_IOADR_GAP);
14170 break;
14173 if (err)
14174 goto free_data;
14175 dev_set_drvdata(dev, data);
14176 return 0;
14178 free_data:
14179 kfree(data->host[0]);
14180 kfree(data->host[1]);
14181 kfree(data);
14182 fail:
14183 return err;
14186 static __devexit int advansys_eisa_remove(struct device *dev)
14188 int i;
14189 struct eisa_scsi_data *data = dev_get_drvdata(dev);
14191 for (i = 0; i < 2; i++) {
14192 int ioport;
14193 struct Scsi_Host *shost = data->host[i];
14194 if (!shost)
14195 continue;
14196 ioport = shost->io_port;
14197 advansys_release(shost);
14198 release_region(ioport, ASC_IOADR_GAP);
14201 kfree(data);
14202 return 0;
14205 static struct eisa_driver advansys_eisa_driver = {
14206 .id_table = advansys_eisa_table,
14207 .driver = {
14208 .name = DRV_NAME,
14209 .probe = advansys_eisa_probe,
14210 .remove = __devexit_p(advansys_eisa_remove),
14214 /* PCI Devices supported by this driver */
14215 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
14216 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
14217 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14218 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
14219 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14220 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
14221 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14222 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
14223 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14224 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
14225 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14226 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
14227 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14231 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
14233 static void __devinit advansys_set_latency(struct pci_dev *pdev)
14235 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
14236 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
14237 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
14238 } else {
14239 u8 latency;
14240 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
14241 if (latency < 0x20)
14242 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
14246 static int __devinit
14247 advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14249 int err, ioport;
14250 struct Scsi_Host *shost;
14251 struct asc_board *board;
14253 err = pci_enable_device(pdev);
14254 if (err)
14255 goto fail;
14256 err = pci_request_regions(pdev, DRV_NAME);
14257 if (err)
14258 goto disable_device;
14259 pci_set_master(pdev);
14260 advansys_set_latency(pdev);
14262 err = -ENODEV;
14263 if (pci_resource_len(pdev, 0) == 0)
14264 goto release_region;
14266 ioport = pci_resource_start(pdev, 0);
14268 err = -ENOMEM;
14269 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14270 if (!shost)
14271 goto release_region;
14273 board = shost_priv(shost);
14274 board->irq = pdev->irq;
14275 board->dev = &pdev->dev;
14277 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
14278 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
14279 pdev->device == PCI_DEVICE_ID_38C1600_REV1) {
14280 board->flags |= ASC_IS_WIDE_BOARD;
14283 err = advansys_board_found(shost, ioport, ASC_IS_PCI);
14284 if (err)
14285 goto free_host;
14287 pci_set_drvdata(pdev, shost);
14288 return 0;
14290 free_host:
14291 scsi_host_put(shost);
14292 release_region:
14293 pci_release_regions(pdev);
14294 disable_device:
14295 pci_disable_device(pdev);
14296 fail:
14297 return err;
14300 static void __devexit advansys_pci_remove(struct pci_dev *pdev)
14302 advansys_release(pci_get_drvdata(pdev));
14303 pci_release_regions(pdev);
14304 pci_disable_device(pdev);
14307 static struct pci_driver advansys_pci_driver = {
14308 .name = DRV_NAME,
14309 .id_table = advansys_pci_tbl,
14310 .probe = advansys_pci_probe,
14311 .remove = __devexit_p(advansys_pci_remove),
14314 static int __init advansys_init(void)
14316 int error;
14318 error = isa_register_driver(&advansys_isa_driver,
14319 ASC_IOADR_TABLE_MAX_IX);
14320 if (error)
14321 goto fail;
14323 error = isa_register_driver(&advansys_vlb_driver,
14324 ASC_IOADR_TABLE_MAX_IX);
14325 if (error)
14326 goto unregister_isa;
14328 error = eisa_driver_register(&advansys_eisa_driver);
14329 if (error)
14330 goto unregister_vlb;
14332 error = pci_register_driver(&advansys_pci_driver);
14333 if (error)
14334 goto unregister_eisa;
14336 return 0;
14338 unregister_eisa:
14339 eisa_driver_unregister(&advansys_eisa_driver);
14340 unregister_vlb:
14341 isa_unregister_driver(&advansys_vlb_driver);
14342 unregister_isa:
14343 isa_unregister_driver(&advansys_isa_driver);
14344 fail:
14345 return error;
14348 static void __exit advansys_exit(void)
14350 pci_unregister_driver(&advansys_pci_driver);
14351 eisa_driver_unregister(&advansys_eisa_driver);
14352 isa_unregister_driver(&advansys_vlb_driver);
14353 isa_unregister_driver(&advansys_isa_driver);
14356 module_init(advansys_init);
14357 module_exit(advansys_exit);
14359 MODULE_LICENSE("GPL");